1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2010 Intel Corporation
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software.
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DEALINGS IN THE SOFTWARE.
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file ir_constant_expression.cpp
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Evaluate and process constant valued expressions
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In GLSL, constant valued expressions are used in several places.  These
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * must be processed and evaluated very early in the compilation process.
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    * Sizes of arrays
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    * Initializers for uniforms
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *    * Initializers for \c const variables
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <math.h>
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/core.h" /* for MAX2, MIN2, CLAMP */
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir_visitor.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_types.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/hash_table.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Using C99 rounding functions for roundToEven() implementation is
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * difficult, because round(), rint, and nearbyint() are affected by
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * fesetenv(), which the application may have done for its own
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * purposes.  Mesa's IROUND macro is close to what we want, but it
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * rounds away from 0 on n + 0.5.
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orground_to_even(float val)
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int rounded = IROUND(val);
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (val - floor(val) == 0.5) {
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (rounded % 2 != 0)
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 rounded += val > 0 ? -1 : 1;
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return rounded;
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic float
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdot(ir_constant *op0, ir_constant *op1)
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(op0->type->is_float() && op1->type->is_float());
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   float result = 0;
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (unsigned c = 0; c < op0->type->components(); c++)
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result += op0->value.f[c] * op1->value.f[c];
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return result;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* This method is the only one supported by gcc.  Unions in particular
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * are iffy, and read-through-converted-pointer is killed by strict
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * aliasing.  OTOH, the compiler sees through the memcpy, so the
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * resulting asm is reasonable.
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic float
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbitcast_u2f(unsigned int u)
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(sizeof(float) == sizeof(unsigned int));
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   float f;
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memcpy(&f, &u, sizeof(f));
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return f;
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned int
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbitcast_f2u(float f)
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(sizeof(float) == sizeof(unsigned int));
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int u;
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memcpy(&u, &f, sizeof(f));
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return u;
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_constant *
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_rvalue::constant_expression_value(struct hash_table *variable_context)
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(this->type->is_error());
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_constant *
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_expression::constant_expression_value(struct hash_table *variable_context)
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->type->is_error())
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_constant *op[Elements(this->operands)] = { NULL, };
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_constant_data data;
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   memset(&data, 0, sizeof(data));
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (unsigned operand = 0; operand < this->get_num_operands(); operand++) {
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      op[operand] = this->operands[operand]->constant_expression_value(variable_context);
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!op[operand])
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return NULL;
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (op[1] != NULL)
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == op[1]->type->base_type ||
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     this->operation == ir_binop_lshift ||
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     this->operation == ir_binop_rshift);
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool op0_scalar = op[0]->type->is_scalar();
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* When iterating over a vector or matrix's components, we want to increase
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * the loop counter.  However, for scalars, we want to stay at 0.
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned c0_inc = op0_scalar ? 0 : 1;
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned c1_inc = op1_scalar ? 0 : 1;
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned components;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (op1_scalar || !op[1]) {
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      components = op[0]->type->components();
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      components = op[1]->type->components();
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *ctx = ralloc_parent(this);
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Handle array operations here, rather than below. */
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (op[0]->type->is_array()) {
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[1] != NULL && op[1]->type->is_array());
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (this->operation) {
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case ir_binop_all_equal:
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return new(ctx) ir_constant(op[0]->has_value(op[1]));
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case ir_binop_any_nequal:
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return new(ctx) ir_constant(!op[0]->has_value(op[1]));
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (this->operation) {
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_bit_not:
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       switch (op[0]->type->base_type) {
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       case GLSL_TYPE_INT:
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           for (unsigned c = 0; c < components; c++)
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               data.i[c] = ~ op[0]->value.i[c];
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           break;
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       case GLSL_TYPE_UINT:
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           for (unsigned c = 0; c < components; c++)
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               data.u[c] = ~ op[0]->value.u[c];
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           break;
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       default:
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           assert(0);
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       }
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       break;
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_logic_not:
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++)
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.b[c] = !op[0]->value.b[c];
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_f2i:
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.i[c] = (int) op[0]->value.f[c];
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_f2u:
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         data.i[c] = (unsigned) op[0]->value.f[c];
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_i2f:
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_INT);
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = (float) op[0]->value.i[c];
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_u2f:
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_UINT);
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = (float) op[0]->value.u[c];
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_b2f:
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = op[0]->value.b[c] ? 1.0F : 0.0F;
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_f2b:
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.b[c] = op[0]->value.f[c] != 0.0F ? true : false;
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_b2i:
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.u[c] = op[0]->value.b[c] ? 1 : 0;
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_i2b:
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->is_integer());
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.b[c] = op[0]->value.u[c] ? true : false;
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_u2i:
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_UINT);
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.i[c] = op[0]->value.u[c];
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_i2u:
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_INT);
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.u[c] = op[0]->value.i[c];
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_bitcast_i2f:
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_INT);
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = bitcast_u2f(op[0]->value.i[c]);
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_bitcast_f2i:
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.i[c] = bitcast_f2u(op[0]->value.f[c]);
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_bitcast_u2f:
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_UINT);
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = bitcast_u2f(op[0]->value.u[c]);
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_bitcast_f2u:
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.u[c] = bitcast_f2u(op[0]->value.f[c]);
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_any:
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->is_boolean());
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      data.b[0] = false;
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (op[0]->value.b[c])
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[0] = true;
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_trunc:
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = truncf(op[0]->value.f[c]);
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_round_even:
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = round_to_even(op[0]->value.f[c]);
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_ceil:
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = ceilf(op[0]->value.f[c]);
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_floor:
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = floorf(op[0]->value.f[c]);
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_fract:
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (this->type->base_type) {
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.u[c] = 0;
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.i[c] = 0;
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_sin:
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_sin_reduced:
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = sinf(op[0]->value.f[c]);
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_cos:
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_cos_reduced:
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = cosf(op[0]->value.f[c]);
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_neg:
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (this->type->base_type) {
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.u[c] = -((int) op[0]->value.u[c]);
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.i[c] = -op[0]->value.i[c];
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.f[c] = -op[0]->value.f[c];
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_abs:
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (this->type->base_type) {
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.u[c] = op[0]->value.u[c];
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.i[c] = op[0]->value.i[c];
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (data.i[c] < 0)
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.i[c] = -data.i[c];
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.f[c] = fabs(op[0]->value.f[c]);
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_sign:
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (this->type->base_type) {
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.u[c] = op[0]->value.i[c] > 0;
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_rcp:
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (this->type->base_type) {
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (op[0]->value.u[c] != 0.0)
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.u[c] = 1 / op[0]->value.u[c];
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (op[0]->value.i[c] != 0.0)
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.i[c] = 1 / op[0]->value.i[c];
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (op[0]->value.f[c] != 0.0)
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.f[c] = 1.0F / op[0]->value.f[c];
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_rsq:
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = 1.0F / sqrtf(op[0]->value.f[c]);
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_sqrt:
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = sqrtf(op[0]->value.f[c]);
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_exp:
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = expf(op[0]->value.f[c]);
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_exp2:
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = exp2f(op[0]->value.f[c]);
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_log:
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = logf(op[0]->value.f[c]);
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_log2:
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = log2f(op[0]->value.f[c]);
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_dFdx:
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_dFdy:
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = 0.0;
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_pow:
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]);
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_dot:
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      data.f[0] = dot(op[0], op[1]);
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_min:
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0, c0 = 0, c1 = 0;
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   c < components;
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   c0 += c0_inc, c1 += c1_inc, c++) {
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (op[0]->type->base_type) {
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]);
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]);
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]);
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_max:
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0, c0 = 0, c1 = 0;
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   c < components;
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   c0 += c0_inc, c1 += c1_inc, c++) {
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (op[0]->type->base_type) {
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]);
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]);
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]);
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_add:
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0, c0 = 0, c1 = 0;
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   c < components;
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   c0 += c0_inc, c1 += c1_inc, c++) {
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (op[0]->type->base_type) {
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_sub:
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0, c0 = 0, c1 = 0;
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   c < components;
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   c0 += c0_inc, c1 += c1_inc, c++) {
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (op[0]->type->base_type) {
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_mul:
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Check for equal types, or unequal types involving scalars */
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  || op0_scalar || op1_scalar) {
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 for (unsigned c = 0, c0 = 0, c1 = 0;
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      c < components;
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      c0 += c0_inc, c1 += c1_inc, c++) {
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    switch (op[0]->type->base_type) {
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    case GLSL_TYPE_UINT:
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       break;
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    case GLSL_TYPE_INT:
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       break;
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    case GLSL_TYPE_FLOAT:
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       break;
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    default:
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       assert(0);
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Multiply an N-by-M matrix with an M-by-P matrix.  Since either
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * matrix can be a GLSL vector, either N or P can be 1.
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * For vec*mat, the vector is treated as a row vector.  This
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * means the vector is a 1-row x M-column matrix.
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  *
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * For mat*vec, the vector is treated as a column vector.  Since
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * matrix_columns is 1 for vectors, this just works.
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const unsigned n = op[0]->type->is_vector()
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ? 1 : op[0]->type->vector_elements;
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const unsigned m = op[1]->type->vector_elements;
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const unsigned p = op[1]->type->matrix_columns;
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 for (unsigned j = 0; j < p; j++) {
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    for (unsigned i = 0; i < n; i++) {
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       for (unsigned k = 0; k < m; k++) {
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		  data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       }
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_div:
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* FINISHME: Emit warning when division-by-zero is detected. */
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0, c0 = 0, c1 = 0;
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   c < components;
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   c0 += c0_inc, c1 += c1_inc, c++) {
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (op[0]->type->base_type) {
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (op[1]->value.u[c1] == 0) {
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.u[c] = 0;
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    } else {
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (op[1]->value.i[c1] == 0) {
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.i[c] = 0;
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    } else {
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_mod:
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* FINISHME: Emit warning when division-by-zero is detected. */
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0, c0 = 0, c1 = 0;
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   c < components;
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	   c0 += c0_inc, c1 += c1_inc, c++) {
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (op[0]->type->base_type) {
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (op[1]->value.u[c1] == 0) {
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.u[c] = 0;
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    } else {
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (op[1]->value.i[c1] == 0) {
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.i[c] = 0;
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    } else {
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    }
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    /* We don't use fmod because it rounds toward zero; GLSL specifies
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     * the use of floor.
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     */
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_logic_and:
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++)
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_logic_xor:
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++)
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_logic_or:
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++)
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_less:
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type == op[1]->type);
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (op[0]->type->base_type) {
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.u[c] < op[1]->value.u[c];
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.i[c] < op[1]->value.i[c];
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.f[c] < op[1]->value.f[c];
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_greater:
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type == op[1]->type);
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (op[0]->type->base_type) {
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_lequal:
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type == op[1]->type);
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (op[0]->type->base_type) {
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c];
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c];
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c];
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_gequal:
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type == op[1]->type);
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < op[0]->type->components(); c++) {
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (op[0]->type->base_type) {
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c];
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c];
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c];
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_equal:
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type == op[1]->type);
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < components; c++) {
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (op[0]->type->base_type) {
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_BOOL:
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.b[c] == op[1]->value.b[c];
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_nequal:
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(op[0]->type == op[1]->type);
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < components; c++) {
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (op[0]->type->base_type) {
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_BOOL:
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.b[c] = op[0]->value.b[c] != op[1]->value.b[c];
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_all_equal:
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      data.b[0] = op[0]->has_value(op[1]);
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_any_nequal:
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      data.b[0] = !op[0]->has_value(op[1]);
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_lshift:
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0, c0 = 0, c1 = 0;
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           c < components;
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           c0 += c0_inc, c1 += c1_inc, c++) {
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          if (op[0]->type->base_type == GLSL_TYPE_INT &&
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              op[1]->type->base_type == GLSL_TYPE_INT) {
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              data.i[c] = op[0]->value.i[c0] << op[1]->value.i[c1];
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          } else if (op[0]->type->base_type == GLSL_TYPE_INT &&
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     op[1]->type->base_type == GLSL_TYPE_UINT) {
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              data.i[c] = op[0]->value.i[c0] << op[1]->value.u[c1];
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     op[1]->type->base_type == GLSL_TYPE_INT) {
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              data.u[c] = op[0]->value.u[c0] << op[1]->value.i[c1];
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     op[1]->type->base_type == GLSL_TYPE_UINT) {
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              data.u[c] = op[0]->value.u[c0] << op[1]->value.u[c1];
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          }
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_rshift:
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       for (unsigned c = 0, c0 = 0, c1 = 0;
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            c < components;
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            c0 += c0_inc, c1 += c1_inc, c++) {
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           if (op[0]->type->base_type == GLSL_TYPE_INT &&
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               op[1]->type->base_type == GLSL_TYPE_INT) {
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               data.i[c] = op[0]->value.i[c0] >> op[1]->value.i[c1];
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           } else if (op[0]->type->base_type == GLSL_TYPE_INT &&
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      op[1]->type->base_type == GLSL_TYPE_UINT) {
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               data.i[c] = op[0]->value.i[c0] >> op[1]->value.u[c1];
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      op[1]->type->base_type == GLSL_TYPE_INT) {
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               data.u[c] = op[0]->value.u[c0] >> op[1]->value.i[c1];
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      op[1]->type->base_type == GLSL_TYPE_UINT) {
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               data.u[c] = op[0]->value.u[c0] >> op[1]->value.u[c1];
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           }
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       }
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       break;
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_bit_and:
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0, c0 = 0, c1 = 0;
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           c < components;
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           c0 += c0_inc, c1 += c1_inc, c++) {
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          switch (op[0]->type->base_type) {
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          case GLSL_TYPE_INT:
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              data.i[c] = op[0]->value.i[c0] & op[1]->value.i[c1];
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              break;
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          case GLSL_TYPE_UINT:
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              data.u[c] = op[0]->value.u[c0] & op[1]->value.u[c1];
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              break;
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          default:
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              assert(0);
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          }
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_bit_or:
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0, c0 = 0, c1 = 0;
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           c < components;
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           c0 += c0_inc, c1 += c1_inc, c++) {
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          switch (op[0]->type->base_type) {
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          case GLSL_TYPE_INT:
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              data.i[c] = op[0]->value.i[c0] | op[1]->value.i[c1];
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              break;
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          case GLSL_TYPE_UINT:
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              data.u[c] = op[0]->value.u[c0] | op[1]->value.u[c1];
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              break;
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          default:
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              assert(0);
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          }
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_bit_xor:
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0, c0 = 0, c1 = 0;
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           c < components;
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           c0 += c0_inc, c1 += c1_inc, c++) {
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          switch (op[0]->type->base_type) {
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          case GLSL_TYPE_INT:
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              data.i[c] = op[0]->value.i[c0] ^ op[1]->value.i[c1];
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              break;
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          case GLSL_TYPE_UINT:
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              data.u[c] = op[0]->value.u[c0] ^ op[1]->value.u[c1];
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              break;
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          default:
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              assert(0);
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          }
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_quadop_vector:
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned c = 0; c < this->type->vector_elements; c++) {
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (this->type->base_type) {
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.i[c] = op[c]->value.i[0];
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.u[c] = op[c]->value.u[0];
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    data.f[c] = op[c]->value.f[0];
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(0);
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* FINISHME: Should handle all expression types. */
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return new(ctx) ir_constant(this->type, &data);
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_constant *
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_texture::constant_expression_value(struct hash_table *variable_context)
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* texture lookups aren't constant expressions */
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_constant *
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_swizzle::constant_expression_value(struct hash_table *variable_context)
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_constant *v = this->val->constant_expression_value(variable_context);
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (v != NULL) {
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_constant_data data = { { 0 } };
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const unsigned swiz_idx[4] = {
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 this->mask.x, this->mask.y, this->mask.z, this->mask.w
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      };
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned i = 0; i < this->mask.num_components; i++) {
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (v->type->base_type) {
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:   data.u[i] = v->value.u[swiz_idx[i]]; break;
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_BOOL:  data.b[i] = v->value.b[swiz_idx[i]]; break;
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:              assert(!"Should not get here."); break;
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      void *ctx = ralloc_parent(this);
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return new(ctx) ir_constant(this->type, &data);
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_dereference_variable::constant_referenced(struct hash_table *variable_context,
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					     ir_constant *&store, int &offset) const
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (variable_context) {
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      store = (ir_constant *)hash_table_find(variable_context, var);
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset = 0;
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      store = NULL;
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset = 0;
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_constant *
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_dereference_variable::constant_expression_value(struct hash_table *variable_context)
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* This may occur during compile and var->type is glsl_type::error_type */
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!var)
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Give priority to the context hashtable, if it exists */
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (variable_context) {
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_constant *value = (ir_constant *)hash_table_find(variable_context, var);
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if(value)
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return value;
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* The constant_value of a uniform variable is its initializer,
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * not the lifetime constant value of the uniform.
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (var->mode == ir_var_uniform)
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!var->constant_value)
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return var->constant_value->clone(ralloc_parent(var), NULL);
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_dereference_array::constant_referenced(struct hash_table *variable_context,
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					  ir_constant *&store, int &offset) const
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_constant *index_c = array_index->constant_expression_value(variable_context);
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!index_c || !index_c->type->is_scalar() || !index_c->type->is_integer()) {
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      store = 0;
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset = 0;
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int index = index_c->type->base_type == GLSL_TYPE_INT ?
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      index_c->get_int_component(0) :
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      index_c->get_uint_component(0);
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_constant *substore;
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int suboffset;
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const ir_dereference *deref = array->as_dereference();
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!deref) {
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      store = 0;
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset = 0;
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   deref->constant_referenced(variable_context, substore, suboffset);
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!substore) {
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      store = 0;
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset = 0;
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const glsl_type *vt = substore->type;
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (vt->is_array()) {
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      store = substore->get_array_element(index);
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset = 0;
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (vt->is_matrix()) {
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      store = substore;
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset = index * vt->vector_elements;
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (vt->is_vector()) {
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      store = substore;
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset = suboffset + index;
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   store = 0;
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset = 0;
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_constant *
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_dereference_array::constant_expression_value(struct hash_table *variable_context)
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_constant *array = this->array->constant_expression_value(variable_context);
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_constant *idx = this->array_index->constant_expression_value(variable_context);
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((array != NULL) && (idx != NULL)) {
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      void *ctx = ralloc_parent(this);
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (array->type->is_matrix()) {
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Array access of a matrix results in a vector.
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const unsigned column = idx->value.u[0];
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const glsl_type *const column_type = array->type->column_type();
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Offset in the constant matrix to the first element of the column
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * to be extracted.
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const unsigned mat_idx = column * column_type->vector_elements;
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_constant_data data = { { 0 } };
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 switch (column_type->base_type) {
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_UINT:
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_INT:
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    for (unsigned i = 0; i < column_type->vector_elements; i++)
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.u[i] = array->value.u[mat_idx + i];
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 case GLSL_TYPE_FLOAT:
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    for (unsigned i = 0; i < column_type->vector_elements; i++)
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       data.f[i] = array->value.f[mat_idx + i];
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 default:
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    assert(!"Should not get here.");
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    break;
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return new(ctx) ir_constant(column_type, &data);
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if (array->type->is_vector()) {
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const unsigned component = idx->value.u[0];
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return new(ctx) ir_constant(array, component);
1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 const unsigned index = idx->value.u[0];
1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return array->get_array_element(index)->clone(ctx, NULL);
1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_dereference_record::constant_referenced(struct hash_table *variable_context,
1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					   ir_constant *&store, int &offset) const
1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_constant *substore;
1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int suboffset;
1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const ir_dereference *deref = record->as_dereference();
1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!deref) {
1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      store = 0;
1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset = 0;
1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   deref->constant_referenced(variable_context, substore, suboffset);
1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!substore) {
1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      store = 0;
1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset = 0;
1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return;
1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   store = substore->get_record_field(field);
1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   offset = 0;
1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_constant *
1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_dereference_record::constant_expression_value(struct hash_table *variable_context)
1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_constant *v = this->record->constant_expression_value();
1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (v != NULL) ? v->get_record_field(this->field) : NULL;
1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_constant *
1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_assignment::constant_expression_value(struct hash_table *variable_context)
1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* FINISHME: Handle CEs involving assignment (return RHS) */
1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return NULL;
1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_constant *
1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_constant::constant_expression_value(struct hash_table *variable_context)
1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return this;
1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_constant *
1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_call::constant_expression_value(struct hash_table *variable_context)
1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return this->callee->constant_expression_value(&this->actual_parameters, variable_context);
1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool ir_function_signature::constant_expression_evaluate_expression_list(const struct exec_list &body,
1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org									 struct hash_table *variable_context,
1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org									 ir_constant **result)
1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_list(n, &body) {
1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_instruction *inst = (ir_instruction *)n;
1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch(inst->ir_type) {
1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* (declare () type symbol) */
1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case ir_type_variable: {
1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_variable *var = inst->as_variable();
1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 hash_table_insert(variable_context, ir_constant::zero(this, var->type), var);
1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* (assign [condition] (write-mask) (ref) (value)) */
1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case ir_type_assignment: {
1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_assignment *asg = inst->as_assignment();
1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (asg->condition) {
1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    ir_constant *cond = asg->condition->constant_expression_value(variable_context);
1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (!cond)
1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       return false;
1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    if (!cond->get_bool_component(0))
1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       break;
1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_constant *store = NULL;
1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 int offset = 0;
1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 asg->lhs->constant_referenced(variable_context, store, offset);
1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (!store)
1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return false;
1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_constant *value = asg->rhs->constant_expression_value(variable_context);
1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (!value)
1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return false;
1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 store->copy_masked_offset(value, offset, asg->write_mask);
1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* (return (expression)) */
1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case ir_type_return:
1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert (result);
1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 *result = inst->as_return()->value->constant_expression_value(variable_context);
1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return *result != NULL;
1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* (call name (ref) (params))*/
1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case ir_type_call: {
1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_call *call = inst->as_call();
1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Just say no to void functions in constant expressions.  We
1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * don't need them at that point.
1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (!call->return_deref)
1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return false;
1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_constant *store = NULL;
1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 int offset = 0;
1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 call->return_deref->constant_referenced(variable_context, store, offset);
1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (!store)
1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return false;
1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_constant *value = call->constant_expression_value(variable_context);
1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if(!value)
1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return false;
1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 store->copy_offset(value, offset);
1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* (if condition (then-instructions) (else-instructions)) */
1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case ir_type_if: {
1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_if *iif = inst->as_if();
1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir_constant *cond = iif->condition->constant_expression_value(variable_context);
1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (!cond || !cond->type->is_boolean())
1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return false;
1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 exec_list &branch = cond->get_bool_component(0) ? iif->then_instructions : iif->else_instructions;
1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 *result = NULL;
1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (!constant_expression_evaluate_expression_list(branch, variable_context, result))
1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return false;
1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* If there was a return in the branch chosen, drop out now. */
1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (*result)
1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    return true;
1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* Every other expression type, we drop out. */
1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 return false;
1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Reaching the end of the block is not an error condition */
1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (result)
1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      *result = NULL;
1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return true;
1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_constant *
1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_function_signature::constant_expression_value(exec_list *actual_parameters, struct hash_table *variable_context)
1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const glsl_type *type = this->return_type;
1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type == glsl_type::void_type)
1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* From the GLSL 1.20 spec, page 23:
1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * "Function calls to user-defined functions (non-built-in functions)
1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *  cannot be used to form constant expressions."
1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!this->is_builtin)
1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /*
1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * Of the builtin functions, only the texture lookups and the noise
1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * ones must not be used in constant expressions.  They all include
1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * specific opcodes so they don't need to be special-cased at this
1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * point.
1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Initialize the table of dereferencable names with the function
1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * parameters.  Verify their const-ness on the way.
1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *
1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * We expect the correctness of the number of parameters to have
1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * been checked earlier.
1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   hash_table *deref_hash = hash_table_ctor(8, hash_table_pointer_hash,
1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					    hash_table_pointer_compare);
1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If "origin" is non-NULL, then the function body is there.  So we
1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * have to use the variable objects from the object with the body,
1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * but the parameter instanciation on the current object.
1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const exec_node *parameter_info = origin ? origin->parameters.head : parameters.head;
1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_list(n, actual_parameters) {
1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value(variable_context);
1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (constant == NULL) {
1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         hash_table_dtor(deref_hash);
1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return NULL;
1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_variable *var = (ir_variable *)parameter_info;
1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      hash_table_insert(deref_hash, constant, var);
1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      parameter_info = parameter_info->next;
1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_constant *result = NULL;
1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Now run the builtin function until something non-constant
1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * happens or we get the result.
1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (constant_expression_evaluate_expression_list(origin ? origin->body : body, deref_hash, &result) && result)
1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      result = result->clone(ralloc_parent(this), NULL);
1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   hash_table_dtor(deref_hash);
1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return result;
1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1355