11591693c7b415e9869157c711fe11263c95d74eDavid Li/*
21591693c7b415e9869157c711fe11263c95d74eDavid Li * Copyright © 2010 Intel Corporation
31591693c7b415e9869157c711fe11263c95d74eDavid Li *
41591693c7b415e9869157c711fe11263c95d74eDavid Li * Permission is hereby granted, free of charge, to any person obtaining a
51591693c7b415e9869157c711fe11263c95d74eDavid Li * copy of this software and associated documentation files (the "Software"),
61591693c7b415e9869157c711fe11263c95d74eDavid Li * to deal in the Software without restriction, including without limitation
71591693c7b415e9869157c711fe11263c95d74eDavid Li * the rights to use, copy, modify, merge, publish, distribute, sublicense,
81591693c7b415e9869157c711fe11263c95d74eDavid Li * and/or sell copies of the Software, and to permit persons to whom the
91591693c7b415e9869157c711fe11263c95d74eDavid Li * Software is furnished to do so, subject to the following conditions:
101591693c7b415e9869157c711fe11263c95d74eDavid Li *
111591693c7b415e9869157c711fe11263c95d74eDavid Li * The above copyright notice and this permission notice (including the next
121591693c7b415e9869157c711fe11263c95d74eDavid Li * paragraph) shall be included in all copies or substantial portions of the
131591693c7b415e9869157c711fe11263c95d74eDavid Li * Software.
141591693c7b415e9869157c711fe11263c95d74eDavid Li *
151591693c7b415e9869157c711fe11263c95d74eDavid Li * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161591693c7b415e9869157c711fe11263c95d74eDavid Li * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171591693c7b415e9869157c711fe11263c95d74eDavid Li * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
181591693c7b415e9869157c711fe11263c95d74eDavid Li * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
191591693c7b415e9869157c711fe11263c95d74eDavid Li * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
201591693c7b415e9869157c711fe11263c95d74eDavid Li * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
211591693c7b415e9869157c711fe11263c95d74eDavid Li * DEALINGS IN THE SOFTWARE.
221591693c7b415e9869157c711fe11263c95d74eDavid Li */
231591693c7b415e9869157c711fe11263c95d74eDavid Li
241591693c7b415e9869157c711fe11263c95d74eDavid Li/**
251591693c7b415e9869157c711fe11263c95d74eDavid Li * \file ir_constant_expression.cpp
261591693c7b415e9869157c711fe11263c95d74eDavid Li * Evaluate and process constant valued expressions
271591693c7b415e9869157c711fe11263c95d74eDavid Li *
281591693c7b415e9869157c711fe11263c95d74eDavid Li * In GLSL, constant valued expressions are used in several places.  These
291591693c7b415e9869157c711fe11263c95d74eDavid Li * must be processed and evaluated very early in the compilation process.
301591693c7b415e9869157c711fe11263c95d74eDavid Li *
311591693c7b415e9869157c711fe11263c95d74eDavid Li *    * Sizes of arrays
321591693c7b415e9869157c711fe11263c95d74eDavid Li *    * Initializers for uniforms
331591693c7b415e9869157c711fe11263c95d74eDavid Li *    * Initializers for \c const variables
341591693c7b415e9869157c711fe11263c95d74eDavid Li */
351591693c7b415e9869157c711fe11263c95d74eDavid Li
361591693c7b415e9869157c711fe11263c95d74eDavid Li#include <math.h>
37d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li#include <cmath>
381591693c7b415e9869157c711fe11263c95d74eDavid Li#include "main/core.h" /* for MAX2, MIN2, CLAMP */
391591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir.h"
401591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir_visitor.h"
411591693c7b415e9869157c711fe11263c95d74eDavid Li#include "glsl_types.h"
421591693c7b415e9869157c711fe11263c95d74eDavid Li
431591693c7b415e9869157c711fe11263c95d74eDavid Listatic float
441591693c7b415e9869157c711fe11263c95d74eDavid Lidot(ir_constant *op0, ir_constant *op1)
451591693c7b415e9869157c711fe11263c95d74eDavid Li{
461591693c7b415e9869157c711fe11263c95d74eDavid Li   assert(op0->type->is_float() && op1->type->is_float());
471591693c7b415e9869157c711fe11263c95d74eDavid Li
481591693c7b415e9869157c711fe11263c95d74eDavid Li   float result = 0;
491591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned c = 0; c < op0->type->components(); c++)
501591693c7b415e9869157c711fe11263c95d74eDavid Li      result += op0->value.f[c] * op1->value.f[c];
511591693c7b415e9869157c711fe11263c95d74eDavid Li
521591693c7b415e9869157c711fe11263c95d74eDavid Li   return result;
531591693c7b415e9869157c711fe11263c95d74eDavid Li}
541591693c7b415e9869157c711fe11263c95d74eDavid Li
551591693c7b415e9869157c711fe11263c95d74eDavid Liir_constant *
561591693c7b415e9869157c711fe11263c95d74eDavid Liir_expression::constant_expression_value()
571591693c7b415e9869157c711fe11263c95d74eDavid Li{
581591693c7b415e9869157c711fe11263c95d74eDavid Li   if (this->type->is_error())
591591693c7b415e9869157c711fe11263c95d74eDavid Li      return NULL;
601591693c7b415e9869157c711fe11263c95d74eDavid Li
611591693c7b415e9869157c711fe11263c95d74eDavid Li   ir_constant *op[Elements(this->operands)] = { NULL, };
621591693c7b415e9869157c711fe11263c95d74eDavid Li   ir_constant_data data;
631591693c7b415e9869157c711fe11263c95d74eDavid Li
641591693c7b415e9869157c711fe11263c95d74eDavid Li   memset(&data, 0, sizeof(data));
651591693c7b415e9869157c711fe11263c95d74eDavid Li
661591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned operand = 0; operand < this->get_num_operands(); operand++) {
671591693c7b415e9869157c711fe11263c95d74eDavid Li      op[operand] = this->operands[operand]->constant_expression_value();
681591693c7b415e9869157c711fe11263c95d74eDavid Li      if (!op[operand])
691591693c7b415e9869157c711fe11263c95d74eDavid Li	 return NULL;
701591693c7b415e9869157c711fe11263c95d74eDavid Li   }
711591693c7b415e9869157c711fe11263c95d74eDavid Li
721591693c7b415e9869157c711fe11263c95d74eDavid Li   if (op[1] != NULL)
731591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == op[1]->type->base_type);
741591693c7b415e9869157c711fe11263c95d74eDavid Li
751591693c7b415e9869157c711fe11263c95d74eDavid Li   bool op0_scalar = op[0]->type->is_scalar();
761591693c7b415e9869157c711fe11263c95d74eDavid Li   bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
771591693c7b415e9869157c711fe11263c95d74eDavid Li
781591693c7b415e9869157c711fe11263c95d74eDavid Li   /* When iterating over a vector or matrix's components, we want to increase
791591693c7b415e9869157c711fe11263c95d74eDavid Li    * the loop counter.  However, for scalars, we want to stay at 0.
801591693c7b415e9869157c711fe11263c95d74eDavid Li    */
811591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned c0_inc = op0_scalar ? 0 : 1;
821591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned c1_inc = op1_scalar ? 0 : 1;
831591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned components;
841591693c7b415e9869157c711fe11263c95d74eDavid Li   if (op1_scalar || !op[1]) {
851591693c7b415e9869157c711fe11263c95d74eDavid Li      components = op[0]->type->components();
861591693c7b415e9869157c711fe11263c95d74eDavid Li   } else {
871591693c7b415e9869157c711fe11263c95d74eDavid Li      components = op[1]->type->components();
881591693c7b415e9869157c711fe11263c95d74eDavid Li   }
891591693c7b415e9869157c711fe11263c95d74eDavid Li
90d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li   void *ctx = hieralloc_parent(this);
911591693c7b415e9869157c711fe11263c95d74eDavid Li
921591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Handle array operations here, rather than below. */
931591693c7b415e9869157c711fe11263c95d74eDavid Li   if (op[0]->type->is_array()) {
941591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[1] != NULL && op[1]->type->is_array());
951591693c7b415e9869157c711fe11263c95d74eDavid Li      switch (this->operation) {
961591693c7b415e9869157c711fe11263c95d74eDavid Li      case ir_binop_all_equal:
971591693c7b415e9869157c711fe11263c95d74eDavid Li	 return new(ctx) ir_constant(op[0]->has_value(op[1]));
981591693c7b415e9869157c711fe11263c95d74eDavid Li      case ir_binop_any_nequal:
991591693c7b415e9869157c711fe11263c95d74eDavid Li	 return new(ctx) ir_constant(!op[0]->has_value(op[1]));
1001591693c7b415e9869157c711fe11263c95d74eDavid Li      default:
1011591693c7b415e9869157c711fe11263c95d74eDavid Li	 break;
1021591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1031591693c7b415e9869157c711fe11263c95d74eDavid Li      return NULL;
1041591693c7b415e9869157c711fe11263c95d74eDavid Li   }
1051591693c7b415e9869157c711fe11263c95d74eDavid Li
1061591693c7b415e9869157c711fe11263c95d74eDavid Li   switch (this->operation) {
1071591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_bit_not:
1081591693c7b415e9869157c711fe11263c95d74eDavid Li       switch (op[0]->type->base_type) {
1091591693c7b415e9869157c711fe11263c95d74eDavid Li       case GLSL_TYPE_INT:
1101591693c7b415e9869157c711fe11263c95d74eDavid Li           for (unsigned c = 0; c < components; c++)
1111591693c7b415e9869157c711fe11263c95d74eDavid Li               data.i[c] = ~ op[0]->value.i[c];
1121591693c7b415e9869157c711fe11263c95d74eDavid Li           break;
1131591693c7b415e9869157c711fe11263c95d74eDavid Li       case GLSL_TYPE_UINT:
1141591693c7b415e9869157c711fe11263c95d74eDavid Li           for (unsigned c = 0; c < components; c++)
1151591693c7b415e9869157c711fe11263c95d74eDavid Li               data.u[c] = ~ op[0]->value.u[c];
1161591693c7b415e9869157c711fe11263c95d74eDavid Li           break;
1171591693c7b415e9869157c711fe11263c95d74eDavid Li       default:
1181591693c7b415e9869157c711fe11263c95d74eDavid Li           assert(0);
1191591693c7b415e9869157c711fe11263c95d74eDavid Li       }
1201591693c7b415e9869157c711fe11263c95d74eDavid Li       break;
1211591693c7b415e9869157c711fe11263c95d74eDavid Li
1221591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_logic_not:
1231591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
1241591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
1251591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.b[c] = !op[0]->value.b[c];
1261591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
1271591693c7b415e9869157c711fe11263c95d74eDavid Li
1281591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_f2i:
1291591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
1301591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1311591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.i[c] = (int) op[0]->value.f[c];
1321591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1331591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
1341591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_i2f:
1351591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_INT);
1361591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1371591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = (float) op[0]->value.i[c];
1381591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1391591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
1401591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_u2f:
1411591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_UINT);
1421591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1431591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = (float) op[0]->value.u[c];
1441591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1451591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
1461591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_b2f:
1471591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
1481591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1491591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = op[0]->value.b[c] ? 1.0F : 0.0F;
1501591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1511591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
1521591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_f2b:
1531591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
1541591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1551591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.b[c] = op[0]->value.f[c] != 0.0F ? true : false;
1561591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1571591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
1581591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_b2i:
1591591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
1601591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1611591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.u[c] = op[0]->value.b[c] ? 1 : 0;
1621591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1631591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
1641591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_i2b:
1651591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_integer());
1661591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1671591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.b[c] = op[0]->value.u[c] ? true : false;
1681591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1691591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
1701591693c7b415e9869157c711fe11263c95d74eDavid Li
1711591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_any:
1721591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_boolean());
1731591693c7b415e9869157c711fe11263c95d74eDavid Li      data.b[0] = false;
1741591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1751591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (op[0]->value.b[c])
1761591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[0] = true;
1771591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1781591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
1791591693c7b415e9869157c711fe11263c95d74eDavid Li
1801591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_trunc:
1811591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
1821591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1831591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = truncf(op[0]->value.f[c]);
1841591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1851591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
1861591693c7b415e9869157c711fe11263c95d74eDavid Li
1871591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_ceil:
1881591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
1891591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1901591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = ceilf(op[0]->value.f[c]);
1911591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1921591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
1931591693c7b415e9869157c711fe11263c95d74eDavid Li
1941591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_floor:
1951591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
1961591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
1971591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = floorf(op[0]->value.f[c]);
1981591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1991591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2001591693c7b415e9869157c711fe11263c95d74eDavid Li
2011591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_fract:
2021591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
2031591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (this->type->base_type) {
2041591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
2051591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.u[c] = 0;
2061591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
2071591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
2081591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.i[c] = 0;
2091591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
2101591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
2111591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = op[0]->value.f[c] - floor(op[0]->value.f[c]);
2121591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
2131591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
2141591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
2151591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
2161591693c7b415e9869157c711fe11263c95d74eDavid Li      }
2171591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2181591693c7b415e9869157c711fe11263c95d74eDavid Li
2191591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_sin:
2201591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_sin_reduced:
2211591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
2221591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
2231591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = sinf(op[0]->value.f[c]);
2241591693c7b415e9869157c711fe11263c95d74eDavid Li      }
2251591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2261591693c7b415e9869157c711fe11263c95d74eDavid Li
2271591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_cos:
2281591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_cos_reduced:
2291591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
2301591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
2311591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = cosf(op[0]->value.f[c]);
2321591693c7b415e9869157c711fe11263c95d74eDavid Li      }
2331591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2341591693c7b415e9869157c711fe11263c95d74eDavid Li
2351591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_neg:
2361591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
2371591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (this->type->base_type) {
2381591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
2391591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.u[c] = -((int) op[0]->value.u[c]);
2401591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
2411591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
2421591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.i[c] = -op[0]->value.i[c];
2431591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
2441591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
2451591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = -op[0]->value.f[c];
2461591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
2471591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
2481591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
2491591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
2501591693c7b415e9869157c711fe11263c95d74eDavid Li      }
2511591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2521591693c7b415e9869157c711fe11263c95d74eDavid Li
2531591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_abs:
2541591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
2551591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (this->type->base_type) {
2561591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
2571591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.u[c] = op[0]->value.u[c];
2581591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
2591591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
2601591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.i[c] = op[0]->value.i[c];
2611591693c7b415e9869157c711fe11263c95d74eDavid Li	    if (data.i[c] < 0)
2621591693c7b415e9869157c711fe11263c95d74eDavid Li	       data.i[c] = -data.i[c];
2631591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
2641591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
2651591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = fabs(op[0]->value.f[c]);
2661591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
2671591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
2681591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
2691591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
2701591693c7b415e9869157c711fe11263c95d74eDavid Li      }
2711591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2721591693c7b415e9869157c711fe11263c95d74eDavid Li
2731591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_sign:
2741591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
2751591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (this->type->base_type) {
2761591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
2771591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.u[c] = op[0]->value.i[c] > 0;
2781591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
2791591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
2801591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
2811591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
2821591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
2831591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = float((op[0]->value.f[c] > 0)-(op[0]->value.f[c] < 0));
2841591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
2851591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
2861591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
2871591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
2881591693c7b415e9869157c711fe11263c95d74eDavid Li      }
2891591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2901591693c7b415e9869157c711fe11263c95d74eDavid Li
2911591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_rcp:
2921591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
2931591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
2941591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (this->type->base_type) {
2951591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
2961591693c7b415e9869157c711fe11263c95d74eDavid Li	    if (op[0]->value.u[c] != 0.0)
2971591693c7b415e9869157c711fe11263c95d74eDavid Li	       data.u[c] = 1 / op[0]->value.u[c];
2981591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
2991591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
3001591693c7b415e9869157c711fe11263c95d74eDavid Li	    if (op[0]->value.i[c] != 0.0)
3011591693c7b415e9869157c711fe11263c95d74eDavid Li	       data.i[c] = 1 / op[0]->value.i[c];
3021591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
3031591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
3041591693c7b415e9869157c711fe11263c95d74eDavid Li	    if (op[0]->value.f[c] != 0.0)
3051591693c7b415e9869157c711fe11263c95d74eDavid Li	       data.f[c] = 1.0F / op[0]->value.f[c];
3061591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
3071591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
3081591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
3091591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
3101591693c7b415e9869157c711fe11263c95d74eDavid Li      }
3111591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3121591693c7b415e9869157c711fe11263c95d74eDavid Li
3131591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_rsq:
3141591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
3151591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
3161591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = 1.0F / sqrtf(op[0]->value.f[c]);
3171591693c7b415e9869157c711fe11263c95d74eDavid Li      }
3181591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3191591693c7b415e9869157c711fe11263c95d74eDavid Li
3201591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_sqrt:
3211591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
3221591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
3231591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = sqrtf(op[0]->value.f[c]);
3241591693c7b415e9869157c711fe11263c95d74eDavid Li      }
3251591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3261591693c7b415e9869157c711fe11263c95d74eDavid Li
3271591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_exp:
3281591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
3291591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
3301591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = expf(op[0]->value.f[c]);
3311591693c7b415e9869157c711fe11263c95d74eDavid Li      }
3321591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3331591693c7b415e9869157c711fe11263c95d74eDavid Li
3341591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_exp2:
3351591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
3361591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
3371591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = exp2f(op[0]->value.f[c]);
3381591693c7b415e9869157c711fe11263c95d74eDavid Li      }
3391591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3401591693c7b415e9869157c711fe11263c95d74eDavid Li
3411591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_log:
3421591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
3431591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
3441591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = logf(op[0]->value.f[c]);
3451591693c7b415e9869157c711fe11263c95d74eDavid Li      }
3461591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3471591693c7b415e9869157c711fe11263c95d74eDavid Li
3481591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_log2:
3491591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
3501591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
351d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li	 data.f[c] = log(op[0]->value.f[c]);
3521591693c7b415e9869157c711fe11263c95d74eDavid Li      }
3531591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3541591693c7b415e9869157c711fe11263c95d74eDavid Li
3551591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_dFdx:
3561591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_dFdy:
3571591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
3581591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
3591591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = 0.0;
3601591693c7b415e9869157c711fe11263c95d74eDavid Li      }
3611591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3621591693c7b415e9869157c711fe11263c95d74eDavid Li
3631591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_pow:
3641591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
3651591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
3661591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]);
3671591693c7b415e9869157c711fe11263c95d74eDavid Li      }
3681591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3691591693c7b415e9869157c711fe11263c95d74eDavid Li
3701591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_dot:
3711591693c7b415e9869157c711fe11263c95d74eDavid Li      data.f[0] = dot(op[0], op[1]);
3721591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3731591693c7b415e9869157c711fe11263c95d74eDavid Li
3741591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_min:
3751591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
3761591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0, c0 = 0, c1 = 0;
3771591693c7b415e9869157c711fe11263c95d74eDavid Li	   c < components;
3781591693c7b415e9869157c711fe11263c95d74eDavid Li	   c0 += c0_inc, c1 += c1_inc, c++) {
3791591693c7b415e9869157c711fe11263c95d74eDavid Li
3801591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
3811591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
3821591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]);
3831591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
3841591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
3851591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]);
3861591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
3871591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
3881591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]);
3891591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
3901591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
3911591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
3921591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
3931591693c7b415e9869157c711fe11263c95d74eDavid Li      }
3941591693c7b415e9869157c711fe11263c95d74eDavid Li
3951591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3961591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_max:
3971591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
3981591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0, c0 = 0, c1 = 0;
3991591693c7b415e9869157c711fe11263c95d74eDavid Li	   c < components;
4001591693c7b415e9869157c711fe11263c95d74eDavid Li	   c0 += c0_inc, c1 += c1_inc, c++) {
4011591693c7b415e9869157c711fe11263c95d74eDavid Li
4021591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
4031591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
4041591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]);
4051591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
4061591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
4071591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]);
4081591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
4091591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
4101591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]);
4111591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
4121591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
4131591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
4141591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
4151591693c7b415e9869157c711fe11263c95d74eDavid Li      }
4161591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
4171591693c7b415e9869157c711fe11263c95d74eDavid Li
4181591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_add:
4191591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
4201591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0, c0 = 0, c1 = 0;
4211591693c7b415e9869157c711fe11263c95d74eDavid Li	   c < components;
4221591693c7b415e9869157c711fe11263c95d74eDavid Li	   c0 += c0_inc, c1 += c1_inc, c++) {
4231591693c7b415e9869157c711fe11263c95d74eDavid Li
4241591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
4251591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
4261591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.u[c] = op[0]->value.u[c0] + op[1]->value.u[c1];
4271591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
4281591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
4291591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.i[c] = op[0]->value.i[c0] + op[1]->value.i[c1];
4301591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
4311591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
4321591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = op[0]->value.f[c0] + op[1]->value.f[c1];
4331591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
4341591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
4351591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
4361591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
4371591693c7b415e9869157c711fe11263c95d74eDavid Li      }
4381591693c7b415e9869157c711fe11263c95d74eDavid Li
4391591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
4401591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_sub:
4411591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
4421591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0, c0 = 0, c1 = 0;
4431591693c7b415e9869157c711fe11263c95d74eDavid Li	   c < components;
4441591693c7b415e9869157c711fe11263c95d74eDavid Li	   c0 += c0_inc, c1 += c1_inc, c++) {
4451591693c7b415e9869157c711fe11263c95d74eDavid Li
4461591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
4471591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
4481591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.u[c] = op[0]->value.u[c0] - op[1]->value.u[c1];
4491591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
4501591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
4511591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.i[c] = op[0]->value.i[c0] - op[1]->value.i[c1];
4521591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
4531591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
4541591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1];
4551591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
4561591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
4571591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
4581591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
4591591693c7b415e9869157c711fe11263c95d74eDavid Li      }
4601591693c7b415e9869157c711fe11263c95d74eDavid Li
4611591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
4621591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_mul:
4631591693c7b415e9869157c711fe11263c95d74eDavid Li      /* Check for equal types, or unequal types involving scalars */
4641591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((op[0]->type == op[1]->type && !op[0]->type->is_matrix())
4651591693c7b415e9869157c711fe11263c95d74eDavid Li	  || op0_scalar || op1_scalar) {
4661591693c7b415e9869157c711fe11263c95d74eDavid Li	 for (unsigned c = 0, c0 = 0, c1 = 0;
4671591693c7b415e9869157c711fe11263c95d74eDavid Li	      c < components;
4681591693c7b415e9869157c711fe11263c95d74eDavid Li	      c0 += c0_inc, c1 += c1_inc, c++) {
4691591693c7b415e9869157c711fe11263c95d74eDavid Li
4701591693c7b415e9869157c711fe11263c95d74eDavid Li	    switch (op[0]->type->base_type) {
4711591693c7b415e9869157c711fe11263c95d74eDavid Li	    case GLSL_TYPE_UINT:
4721591693c7b415e9869157c711fe11263c95d74eDavid Li	       data.u[c] = op[0]->value.u[c0] * op[1]->value.u[c1];
4731591693c7b415e9869157c711fe11263c95d74eDavid Li	       break;
4741591693c7b415e9869157c711fe11263c95d74eDavid Li	    case GLSL_TYPE_INT:
4751591693c7b415e9869157c711fe11263c95d74eDavid Li	       data.i[c] = op[0]->value.i[c0] * op[1]->value.i[c1];
4761591693c7b415e9869157c711fe11263c95d74eDavid Li	       break;
4771591693c7b415e9869157c711fe11263c95d74eDavid Li	    case GLSL_TYPE_FLOAT:
4781591693c7b415e9869157c711fe11263c95d74eDavid Li	       data.f[c] = op[0]->value.f[c0] * op[1]->value.f[c1];
4791591693c7b415e9869157c711fe11263c95d74eDavid Li	       break;
4801591693c7b415e9869157c711fe11263c95d74eDavid Li	    default:
4811591693c7b415e9869157c711fe11263c95d74eDavid Li	       assert(0);
4821591693c7b415e9869157c711fe11263c95d74eDavid Li	    }
4831591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
4841591693c7b415e9869157c711fe11263c95d74eDavid Li      } else {
4851591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(op[0]->type->is_matrix() || op[1]->type->is_matrix());
4861591693c7b415e9869157c711fe11263c95d74eDavid Li
4871591693c7b415e9869157c711fe11263c95d74eDavid Li	 /* Multiply an N-by-M matrix with an M-by-P matrix.  Since either
4881591693c7b415e9869157c711fe11263c95d74eDavid Li	  * matrix can be a GLSL vector, either N or P can be 1.
4891591693c7b415e9869157c711fe11263c95d74eDavid Li	  *
4901591693c7b415e9869157c711fe11263c95d74eDavid Li	  * For vec*mat, the vector is treated as a row vector.  This
4911591693c7b415e9869157c711fe11263c95d74eDavid Li	  * means the vector is a 1-row x M-column matrix.
4921591693c7b415e9869157c711fe11263c95d74eDavid Li	  *
4931591693c7b415e9869157c711fe11263c95d74eDavid Li	  * For mat*vec, the vector is treated as a column vector.  Since
4941591693c7b415e9869157c711fe11263c95d74eDavid Li	  * matrix_columns is 1 for vectors, this just works.
4951591693c7b415e9869157c711fe11263c95d74eDavid Li	  */
4961591693c7b415e9869157c711fe11263c95d74eDavid Li	 const unsigned n = op[0]->type->is_vector()
4971591693c7b415e9869157c711fe11263c95d74eDavid Li	    ? 1 : op[0]->type->vector_elements;
4981591693c7b415e9869157c711fe11263c95d74eDavid Li	 const unsigned m = op[1]->type->vector_elements;
4991591693c7b415e9869157c711fe11263c95d74eDavid Li	 const unsigned p = op[1]->type->matrix_columns;
5001591693c7b415e9869157c711fe11263c95d74eDavid Li	 for (unsigned j = 0; j < p; j++) {
5011591693c7b415e9869157c711fe11263c95d74eDavid Li	    for (unsigned i = 0; i < n; i++) {
5021591693c7b415e9869157c711fe11263c95d74eDavid Li	       for (unsigned k = 0; k < m; k++) {
5031591693c7b415e9869157c711fe11263c95d74eDavid Li		  data.f[i+n*j] += op[0]->value.f[i+n*k]*op[1]->value.f[k+m*j];
5041591693c7b415e9869157c711fe11263c95d74eDavid Li	       }
5051591693c7b415e9869157c711fe11263c95d74eDavid Li	    }
5061591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
5071591693c7b415e9869157c711fe11263c95d74eDavid Li      }
5081591693c7b415e9869157c711fe11263c95d74eDavid Li
5091591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
5101591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_div:
5111591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
5121591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0, c0 = 0, c1 = 0;
5131591693c7b415e9869157c711fe11263c95d74eDavid Li	   c < components;
5141591693c7b415e9869157c711fe11263c95d74eDavid Li	   c0 += c0_inc, c1 += c1_inc, c++) {
5151591693c7b415e9869157c711fe11263c95d74eDavid Li
5161591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
5171591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
5181591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.u[c] = op[0]->value.u[c0] / op[1]->value.u[c1];
5191591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
5201591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
5211591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.i[c] = op[0]->value.i[c0] / op[1]->value.i[c1];
5221591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
5231591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
5241591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = op[0]->value.f[c0] / op[1]->value.f[c1];
5251591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
5261591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
5271591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
5281591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
5291591693c7b415e9869157c711fe11263c95d74eDavid Li      }
5301591693c7b415e9869157c711fe11263c95d74eDavid Li
5311591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
5321591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_mod:
5331591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
5341591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0, c0 = 0, c1 = 0;
5351591693c7b415e9869157c711fe11263c95d74eDavid Li	   c < components;
5361591693c7b415e9869157c711fe11263c95d74eDavid Li	   c0 += c0_inc, c1 += c1_inc, c++) {
5371591693c7b415e9869157c711fe11263c95d74eDavid Li
5381591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
5391591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
5401591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.u[c] = op[0]->value.u[c0] % op[1]->value.u[c1];
5411591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
5421591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
5431591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.i[c] = op[0]->value.i[c0] % op[1]->value.i[c1];
5441591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
5451591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
5461591693c7b415e9869157c711fe11263c95d74eDavid Li	    /* We don't use fmod because it rounds toward zero; GLSL specifies
5471591693c7b415e9869157c711fe11263c95d74eDavid Li	     * the use of floor.
5481591693c7b415e9869157c711fe11263c95d74eDavid Li	     */
5491591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = op[0]->value.f[c0] - op[1]->value.f[c1]
5501591693c7b415e9869157c711fe11263c95d74eDavid Li	       * floorf(op[0]->value.f[c0] / op[1]->value.f[c1]);
5511591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
5521591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
5531591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
5541591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
5551591693c7b415e9869157c711fe11263c95d74eDavid Li      }
5561591693c7b415e9869157c711fe11263c95d74eDavid Li
5571591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
5581591693c7b415e9869157c711fe11263c95d74eDavid Li
5591591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_logic_and:
5601591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
5611591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
5621591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
5631591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
5641591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_logic_xor:
5651591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
5661591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
5671591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
5681591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
5691591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_logic_or:
5701591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
5711591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
5721591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
5731591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
5741591693c7b415e9869157c711fe11263c95d74eDavid Li
5751591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_less:
5761591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type == op[1]->type);
5771591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
5781591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
5791591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
5801591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
5811591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
5821591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
5831591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
5841591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
5851591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
5861591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
5871591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
5881591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
5891591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
5901591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
5911591693c7b415e9869157c711fe11263c95d74eDavid Li      }
5921591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
5931591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_greater:
5941591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type == op[1]->type);
5951591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
5961591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
5971591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
5981591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
5991591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
6001591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
6011591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
6021591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
6031591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
6041591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
6051591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
6061591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
6071591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
6081591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
6091591693c7b415e9869157c711fe11263c95d74eDavid Li      }
6101591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
6111591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_lequal:
6121591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type == op[1]->type);
6131591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
6141591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
6151591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
6161591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
6171591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
6181591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
6191591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
6201591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
6211591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
6221591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
6231591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
6241591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
6251591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
6261591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
6271591693c7b415e9869157c711fe11263c95d74eDavid Li      }
6281591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
6291591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_gequal:
6301591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type == op[1]->type);
6311591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
6321591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
6331591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
6341591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
6351591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
6361591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
6371591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
6381591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
6391591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
6401591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
6411591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
6421591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
6431591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
6441591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
6451591693c7b415e9869157c711fe11263c95d74eDavid Li      }
6461591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
6471591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_equal:
6481591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type == op[1]->type);
6491591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < components; c++) {
6501591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
6511591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
6521591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
6531591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
6541591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
6551591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
6561591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
6571591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
6581591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
6591591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
6601591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
6611591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
6621591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
6631591693c7b415e9869157c711fe11263c95d74eDavid Li      }
6641591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
6651591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_nequal:
6661591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type != op[1]->type);
6671591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < components; c++) {
6681591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
6691591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
6701591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
6711591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
6721591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
6731591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
6741591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
6751591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
6761591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
6771591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
6781591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
6791591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
6801591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
6811591693c7b415e9869157c711fe11263c95d74eDavid Li      }
6821591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
6831591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_all_equal:
6841591693c7b415e9869157c711fe11263c95d74eDavid Li      data.b[0] = op[0]->has_value(op[1]);
6851591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
6861591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_any_nequal:
6871591693c7b415e9869157c711fe11263c95d74eDavid Li      data.b[0] = !op[0]->has_value(op[1]);
6881591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
6891591693c7b415e9869157c711fe11263c95d74eDavid Li
6901591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_lshift:
6911591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0, c0 = 0, c1 = 0;
6921591693c7b415e9869157c711fe11263c95d74eDavid Li           c < components;
6931591693c7b415e9869157c711fe11263c95d74eDavid Li           c0 += c0_inc, c1 += c1_inc, c++) {
6941591693c7b415e9869157c711fe11263c95d74eDavid Li
6951591693c7b415e9869157c711fe11263c95d74eDavid Li          if (op[0]->type->base_type == GLSL_TYPE_INT &&
6961591693c7b415e9869157c711fe11263c95d74eDavid Li              op[1]->type->base_type == GLSL_TYPE_INT) {
6971591693c7b415e9869157c711fe11263c95d74eDavid Li              data.i[c] = op[0]->value.i[c0] << op[1]->value.i[c1];
6981591693c7b415e9869157c711fe11263c95d74eDavid Li
6991591693c7b415e9869157c711fe11263c95d74eDavid Li          } else if (op[0]->type->base_type == GLSL_TYPE_INT &&
7001591693c7b415e9869157c711fe11263c95d74eDavid Li                     op[1]->type->base_type == GLSL_TYPE_UINT) {
7011591693c7b415e9869157c711fe11263c95d74eDavid Li              data.i[c] = op[0]->value.i[c0] << op[1]->value.u[c1];
7021591693c7b415e9869157c711fe11263c95d74eDavid Li
7031591693c7b415e9869157c711fe11263c95d74eDavid Li          } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
7041591693c7b415e9869157c711fe11263c95d74eDavid Li                     op[1]->type->base_type == GLSL_TYPE_INT) {
7051591693c7b415e9869157c711fe11263c95d74eDavid Li              data.u[c] = op[0]->value.u[c0] << op[1]->value.i[c1];
7061591693c7b415e9869157c711fe11263c95d74eDavid Li
7071591693c7b415e9869157c711fe11263c95d74eDavid Li          } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
7081591693c7b415e9869157c711fe11263c95d74eDavid Li                     op[1]->type->base_type == GLSL_TYPE_UINT) {
7091591693c7b415e9869157c711fe11263c95d74eDavid Li              data.u[c] = op[0]->value.u[c0] << op[1]->value.u[c1];
7101591693c7b415e9869157c711fe11263c95d74eDavid Li          }
7111591693c7b415e9869157c711fe11263c95d74eDavid Li      }
7121591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
7131591693c7b415e9869157c711fe11263c95d74eDavid Li
7141591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_rshift:
7151591693c7b415e9869157c711fe11263c95d74eDavid Li       for (unsigned c = 0, c0 = 0, c1 = 0;
7161591693c7b415e9869157c711fe11263c95d74eDavid Li            c < components;
7171591693c7b415e9869157c711fe11263c95d74eDavid Li            c0 += c0_inc, c1 += c1_inc, c++) {
7181591693c7b415e9869157c711fe11263c95d74eDavid Li
7191591693c7b415e9869157c711fe11263c95d74eDavid Li           if (op[0]->type->base_type == GLSL_TYPE_INT &&
7201591693c7b415e9869157c711fe11263c95d74eDavid Li               op[1]->type->base_type == GLSL_TYPE_INT) {
7211591693c7b415e9869157c711fe11263c95d74eDavid Li               data.i[c] = op[0]->value.i[c0] >> op[1]->value.i[c1];
7221591693c7b415e9869157c711fe11263c95d74eDavid Li
7231591693c7b415e9869157c711fe11263c95d74eDavid Li           } else if (op[0]->type->base_type == GLSL_TYPE_INT &&
7241591693c7b415e9869157c711fe11263c95d74eDavid Li                      op[1]->type->base_type == GLSL_TYPE_UINT) {
7251591693c7b415e9869157c711fe11263c95d74eDavid Li               data.i[c] = op[0]->value.i[c0] >> op[1]->value.u[c1];
7261591693c7b415e9869157c711fe11263c95d74eDavid Li
7271591693c7b415e9869157c711fe11263c95d74eDavid Li           } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
7281591693c7b415e9869157c711fe11263c95d74eDavid Li                      op[1]->type->base_type == GLSL_TYPE_INT) {
7291591693c7b415e9869157c711fe11263c95d74eDavid Li               data.u[c] = op[0]->value.u[c0] >> op[1]->value.i[c1];
7301591693c7b415e9869157c711fe11263c95d74eDavid Li
7311591693c7b415e9869157c711fe11263c95d74eDavid Li           } else if (op[0]->type->base_type == GLSL_TYPE_UINT &&
7321591693c7b415e9869157c711fe11263c95d74eDavid Li                      op[1]->type->base_type == GLSL_TYPE_UINT) {
7331591693c7b415e9869157c711fe11263c95d74eDavid Li               data.u[c] = op[0]->value.u[c0] >> op[1]->value.u[c1];
7341591693c7b415e9869157c711fe11263c95d74eDavid Li           }
7351591693c7b415e9869157c711fe11263c95d74eDavid Li       }
7361591693c7b415e9869157c711fe11263c95d74eDavid Li       break;
7371591693c7b415e9869157c711fe11263c95d74eDavid Li
7381591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_bit_and:
7391591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0, c0 = 0, c1 = 0;
7401591693c7b415e9869157c711fe11263c95d74eDavid Li           c < components;
7411591693c7b415e9869157c711fe11263c95d74eDavid Li           c0 += c0_inc, c1 += c1_inc, c++) {
7421591693c7b415e9869157c711fe11263c95d74eDavid Li
7431591693c7b415e9869157c711fe11263c95d74eDavid Li          switch (op[0]->type->base_type) {
7441591693c7b415e9869157c711fe11263c95d74eDavid Li          case GLSL_TYPE_INT:
7451591693c7b415e9869157c711fe11263c95d74eDavid Li              data.i[c] = op[0]->value.i[c0] & op[1]->value.i[c1];
7461591693c7b415e9869157c711fe11263c95d74eDavid Li              break;
7471591693c7b415e9869157c711fe11263c95d74eDavid Li          case GLSL_TYPE_UINT:
7481591693c7b415e9869157c711fe11263c95d74eDavid Li              data.u[c] = op[0]->value.u[c0] & op[1]->value.u[c1];
7491591693c7b415e9869157c711fe11263c95d74eDavid Li              break;
7501591693c7b415e9869157c711fe11263c95d74eDavid Li          default:
7511591693c7b415e9869157c711fe11263c95d74eDavid Li              assert(0);
7521591693c7b415e9869157c711fe11263c95d74eDavid Li          }
7531591693c7b415e9869157c711fe11263c95d74eDavid Li      }
7541591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
7551591693c7b415e9869157c711fe11263c95d74eDavid Li
7561591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_bit_or:
7571591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0, c0 = 0, c1 = 0;
7581591693c7b415e9869157c711fe11263c95d74eDavid Li           c < components;
7591591693c7b415e9869157c711fe11263c95d74eDavid Li           c0 += c0_inc, c1 += c1_inc, c++) {
7601591693c7b415e9869157c711fe11263c95d74eDavid Li
7611591693c7b415e9869157c711fe11263c95d74eDavid Li          switch (op[0]->type->base_type) {
7621591693c7b415e9869157c711fe11263c95d74eDavid Li          case GLSL_TYPE_INT:
7631591693c7b415e9869157c711fe11263c95d74eDavid Li              data.i[c] = op[0]->value.i[c0] | op[1]->value.i[c1];
7641591693c7b415e9869157c711fe11263c95d74eDavid Li              break;
7651591693c7b415e9869157c711fe11263c95d74eDavid Li          case GLSL_TYPE_UINT:
7661591693c7b415e9869157c711fe11263c95d74eDavid Li              data.u[c] = op[0]->value.u[c0] | op[1]->value.u[c1];
7671591693c7b415e9869157c711fe11263c95d74eDavid Li              break;
7681591693c7b415e9869157c711fe11263c95d74eDavid Li          default:
7691591693c7b415e9869157c711fe11263c95d74eDavid Li              assert(0);
7701591693c7b415e9869157c711fe11263c95d74eDavid Li          }
7711591693c7b415e9869157c711fe11263c95d74eDavid Li      }
7721591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
7731591693c7b415e9869157c711fe11263c95d74eDavid Li
7741591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_bit_xor:
7751591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0, c0 = 0, c1 = 0;
7761591693c7b415e9869157c711fe11263c95d74eDavid Li           c < components;
7771591693c7b415e9869157c711fe11263c95d74eDavid Li           c0 += c0_inc, c1 += c1_inc, c++) {
7781591693c7b415e9869157c711fe11263c95d74eDavid Li
7791591693c7b415e9869157c711fe11263c95d74eDavid Li          switch (op[0]->type->base_type) {
7801591693c7b415e9869157c711fe11263c95d74eDavid Li          case GLSL_TYPE_INT:
7811591693c7b415e9869157c711fe11263c95d74eDavid Li              data.i[c] = op[0]->value.i[c0] ^ op[1]->value.i[c1];
7821591693c7b415e9869157c711fe11263c95d74eDavid Li              break;
7831591693c7b415e9869157c711fe11263c95d74eDavid Li          case GLSL_TYPE_UINT:
7841591693c7b415e9869157c711fe11263c95d74eDavid Li              data.u[c] = op[0]->value.u[c0] ^ op[1]->value.u[c1];
7851591693c7b415e9869157c711fe11263c95d74eDavid Li              break;
7861591693c7b415e9869157c711fe11263c95d74eDavid Li          default:
7871591693c7b415e9869157c711fe11263c95d74eDavid Li              assert(0);
7881591693c7b415e9869157c711fe11263c95d74eDavid Li          }
7891591693c7b415e9869157c711fe11263c95d74eDavid Li      }
7901591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
7911591693c7b415e9869157c711fe11263c95d74eDavid Li
7921591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_quadop_vector:
7931591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < this->type->vector_elements; c++) {
7941591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (this->type->base_type) {
7951591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
7961591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.i[c] = op[c]->value.i[0];
7971591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
7981591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
7991591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.u[c] = op[c]->value.u[0];
8001591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
8011591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
8021591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = op[c]->value.f[0];
8031591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
8041591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
8051591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(0);
8061591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
8071591693c7b415e9869157c711fe11263c95d74eDavid Li      }
8081591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
8091591693c7b415e9869157c711fe11263c95d74eDavid Li
8101591693c7b415e9869157c711fe11263c95d74eDavid Li   default:
8111591693c7b415e9869157c711fe11263c95d74eDavid Li      /* FINISHME: Should handle all expression types. */
8121591693c7b415e9869157c711fe11263c95d74eDavid Li      return NULL;
8131591693c7b415e9869157c711fe11263c95d74eDavid Li   }
8141591693c7b415e9869157c711fe11263c95d74eDavid Li
8151591693c7b415e9869157c711fe11263c95d74eDavid Li   return new(ctx) ir_constant(this->type, &data);
8161591693c7b415e9869157c711fe11263c95d74eDavid Li}
8171591693c7b415e9869157c711fe11263c95d74eDavid Li
8181591693c7b415e9869157c711fe11263c95d74eDavid Li
8191591693c7b415e9869157c711fe11263c95d74eDavid Liir_constant *
8201591693c7b415e9869157c711fe11263c95d74eDavid Liir_texture::constant_expression_value()
8211591693c7b415e9869157c711fe11263c95d74eDavid Li{
8221591693c7b415e9869157c711fe11263c95d74eDavid Li   /* texture lookups aren't constant expressions */
8231591693c7b415e9869157c711fe11263c95d74eDavid Li   return NULL;
8241591693c7b415e9869157c711fe11263c95d74eDavid Li}
8251591693c7b415e9869157c711fe11263c95d74eDavid Li
8261591693c7b415e9869157c711fe11263c95d74eDavid Li
8271591693c7b415e9869157c711fe11263c95d74eDavid Liir_constant *
8281591693c7b415e9869157c711fe11263c95d74eDavid Liir_swizzle::constant_expression_value()
8291591693c7b415e9869157c711fe11263c95d74eDavid Li{
8301591693c7b415e9869157c711fe11263c95d74eDavid Li   ir_constant *v = this->val->constant_expression_value();
8311591693c7b415e9869157c711fe11263c95d74eDavid Li
8321591693c7b415e9869157c711fe11263c95d74eDavid Li   if (v != NULL) {
8331591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_constant_data data = { { 0 } };
8341591693c7b415e9869157c711fe11263c95d74eDavid Li
8351591693c7b415e9869157c711fe11263c95d74eDavid Li      const unsigned swiz_idx[4] = {
8361591693c7b415e9869157c711fe11263c95d74eDavid Li	 this->mask.x, this->mask.y, this->mask.z, this->mask.w
8371591693c7b415e9869157c711fe11263c95d74eDavid Li      };
8381591693c7b415e9869157c711fe11263c95d74eDavid Li
8391591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned i = 0; i < this->mask.num_components; i++) {
8401591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (v->type->base_type) {
8411591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
8421591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:   data.u[i] = v->value.u[swiz_idx[i]]; break;
8431591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
8441591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_BOOL:  data.b[i] = v->value.b[swiz_idx[i]]; break;
8451591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:              assert(!"Should not get here."); break;
8461591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
8471591693c7b415e9869157c711fe11263c95d74eDavid Li      }
8481591693c7b415e9869157c711fe11263c95d74eDavid Li
849d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li      void *ctx = hieralloc_parent(this);
8501591693c7b415e9869157c711fe11263c95d74eDavid Li      return new(ctx) ir_constant(this->type, &data);
8511591693c7b415e9869157c711fe11263c95d74eDavid Li   }
8521591693c7b415e9869157c711fe11263c95d74eDavid Li   return NULL;
8531591693c7b415e9869157c711fe11263c95d74eDavid Li}
8541591693c7b415e9869157c711fe11263c95d74eDavid Li
8551591693c7b415e9869157c711fe11263c95d74eDavid Li
8561591693c7b415e9869157c711fe11263c95d74eDavid Liir_constant *
8571591693c7b415e9869157c711fe11263c95d74eDavid Liir_dereference_variable::constant_expression_value()
8581591693c7b415e9869157c711fe11263c95d74eDavid Li{
8591591693c7b415e9869157c711fe11263c95d74eDavid Li   /* This may occur during compile and var->type is glsl_type::error_type */
8601591693c7b415e9869157c711fe11263c95d74eDavid Li   if (!var)
8611591693c7b415e9869157c711fe11263c95d74eDavid Li      return NULL;
8621591693c7b415e9869157c711fe11263c95d74eDavid Li
8631591693c7b415e9869157c711fe11263c95d74eDavid Li   /* The constant_value of a uniform variable is its initializer,
8641591693c7b415e9869157c711fe11263c95d74eDavid Li    * not the lifetime constant value of the uniform.
8651591693c7b415e9869157c711fe11263c95d74eDavid Li    */
8661591693c7b415e9869157c711fe11263c95d74eDavid Li   if (var->mode == ir_var_uniform)
8671591693c7b415e9869157c711fe11263c95d74eDavid Li      return NULL;
8681591693c7b415e9869157c711fe11263c95d74eDavid Li
8691591693c7b415e9869157c711fe11263c95d74eDavid Li   if (!var->constant_value)
8701591693c7b415e9869157c711fe11263c95d74eDavid Li      return NULL;
8711591693c7b415e9869157c711fe11263c95d74eDavid Li
872d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li   return var->constant_value->clone(hieralloc_parent(var), NULL);
8731591693c7b415e9869157c711fe11263c95d74eDavid Li}
8741591693c7b415e9869157c711fe11263c95d74eDavid Li
8751591693c7b415e9869157c711fe11263c95d74eDavid Li
8761591693c7b415e9869157c711fe11263c95d74eDavid Liir_constant *
8771591693c7b415e9869157c711fe11263c95d74eDavid Liir_dereference_array::constant_expression_value()
8781591693c7b415e9869157c711fe11263c95d74eDavid Li{
8791591693c7b415e9869157c711fe11263c95d74eDavid Li   ir_constant *array = this->array->constant_expression_value();
8801591693c7b415e9869157c711fe11263c95d74eDavid Li   ir_constant *idx = this->array_index->constant_expression_value();
8811591693c7b415e9869157c711fe11263c95d74eDavid Li
8821591693c7b415e9869157c711fe11263c95d74eDavid Li   if ((array != NULL) && (idx != NULL)) {
883d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li      void *ctx = hieralloc_parent(this);
8841591693c7b415e9869157c711fe11263c95d74eDavid Li      if (array->type->is_matrix()) {
8851591693c7b415e9869157c711fe11263c95d74eDavid Li	 /* Array access of a matrix results in a vector.
8861591693c7b415e9869157c711fe11263c95d74eDavid Li	  */
8871591693c7b415e9869157c711fe11263c95d74eDavid Li	 const unsigned column = idx->value.u[0];
8881591693c7b415e9869157c711fe11263c95d74eDavid Li
8891591693c7b415e9869157c711fe11263c95d74eDavid Li	 const glsl_type *const column_type = array->type->column_type();
8901591693c7b415e9869157c711fe11263c95d74eDavid Li
8911591693c7b415e9869157c711fe11263c95d74eDavid Li	 /* Offset in the constant matrix to the first element of the column
8921591693c7b415e9869157c711fe11263c95d74eDavid Li	  * to be extracted.
8931591693c7b415e9869157c711fe11263c95d74eDavid Li	  */
8941591693c7b415e9869157c711fe11263c95d74eDavid Li	 const unsigned mat_idx = column * column_type->vector_elements;
8951591693c7b415e9869157c711fe11263c95d74eDavid Li
8961591693c7b415e9869157c711fe11263c95d74eDavid Li	 ir_constant_data data = { { 0 } };
8971591693c7b415e9869157c711fe11263c95d74eDavid Li
8981591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (column_type->base_type) {
8991591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
9001591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
9011591693c7b415e9869157c711fe11263c95d74eDavid Li	    for (unsigned i = 0; i < column_type->vector_elements; i++)
9021591693c7b415e9869157c711fe11263c95d74eDavid Li	       data.u[i] = array->value.u[mat_idx + i];
9031591693c7b415e9869157c711fe11263c95d74eDavid Li
9041591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
9051591693c7b415e9869157c711fe11263c95d74eDavid Li
9061591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
9071591693c7b415e9869157c711fe11263c95d74eDavid Li	    for (unsigned i = 0; i < column_type->vector_elements; i++)
9081591693c7b415e9869157c711fe11263c95d74eDavid Li	       data.f[i] = array->value.f[mat_idx + i];
9091591693c7b415e9869157c711fe11263c95d74eDavid Li
9101591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
9111591693c7b415e9869157c711fe11263c95d74eDavid Li
9121591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
9131591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(!"Should not get here.");
9141591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
9151591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
9161591693c7b415e9869157c711fe11263c95d74eDavid Li
9171591693c7b415e9869157c711fe11263c95d74eDavid Li	 return new(ctx) ir_constant(column_type, &data);
9181591693c7b415e9869157c711fe11263c95d74eDavid Li      } else if (array->type->is_vector()) {
9191591693c7b415e9869157c711fe11263c95d74eDavid Li	 const unsigned component = idx->value.u[0];
9201591693c7b415e9869157c711fe11263c95d74eDavid Li
9211591693c7b415e9869157c711fe11263c95d74eDavid Li	 return new(ctx) ir_constant(array, component);
9221591693c7b415e9869157c711fe11263c95d74eDavid Li      } else {
9231591693c7b415e9869157c711fe11263c95d74eDavid Li	 const unsigned index = idx->value.u[0];
9241591693c7b415e9869157c711fe11263c95d74eDavid Li	 return array->get_array_element(index)->clone(ctx, NULL);
9251591693c7b415e9869157c711fe11263c95d74eDavid Li      }
9261591693c7b415e9869157c711fe11263c95d74eDavid Li   }
9271591693c7b415e9869157c711fe11263c95d74eDavid Li   return NULL;
9281591693c7b415e9869157c711fe11263c95d74eDavid Li}
9291591693c7b415e9869157c711fe11263c95d74eDavid Li
9301591693c7b415e9869157c711fe11263c95d74eDavid Li
9311591693c7b415e9869157c711fe11263c95d74eDavid Liir_constant *
9321591693c7b415e9869157c711fe11263c95d74eDavid Liir_dereference_record::constant_expression_value()
9331591693c7b415e9869157c711fe11263c95d74eDavid Li{
9341591693c7b415e9869157c711fe11263c95d74eDavid Li   ir_constant *v = this->record->constant_expression_value();
9351591693c7b415e9869157c711fe11263c95d74eDavid Li
9361591693c7b415e9869157c711fe11263c95d74eDavid Li   return (v != NULL) ? v->get_record_field(this->field) : NULL;
9371591693c7b415e9869157c711fe11263c95d74eDavid Li}
9381591693c7b415e9869157c711fe11263c95d74eDavid Li
9391591693c7b415e9869157c711fe11263c95d74eDavid Li
9401591693c7b415e9869157c711fe11263c95d74eDavid Liir_constant *
9411591693c7b415e9869157c711fe11263c95d74eDavid Liir_assignment::constant_expression_value()
9421591693c7b415e9869157c711fe11263c95d74eDavid Li{
9431591693c7b415e9869157c711fe11263c95d74eDavid Li   /* FINISHME: Handle CEs involving assignment (return RHS) */
9441591693c7b415e9869157c711fe11263c95d74eDavid Li   return NULL;
9451591693c7b415e9869157c711fe11263c95d74eDavid Li}
9461591693c7b415e9869157c711fe11263c95d74eDavid Li
9471591693c7b415e9869157c711fe11263c95d74eDavid Li
9481591693c7b415e9869157c711fe11263c95d74eDavid Liir_constant *
9491591693c7b415e9869157c711fe11263c95d74eDavid Liir_constant::constant_expression_value()
9501591693c7b415e9869157c711fe11263c95d74eDavid Li{
9511591693c7b415e9869157c711fe11263c95d74eDavid Li   return this;
9521591693c7b415e9869157c711fe11263c95d74eDavid Li}
9531591693c7b415e9869157c711fe11263c95d74eDavid Li
9541591693c7b415e9869157c711fe11263c95d74eDavid Li
9551591693c7b415e9869157c711fe11263c95d74eDavid Liir_constant *
9561591693c7b415e9869157c711fe11263c95d74eDavid Liir_call::constant_expression_value()
9571591693c7b415e9869157c711fe11263c95d74eDavid Li{
9581591693c7b415e9869157c711fe11263c95d74eDavid Li   if (this->type == glsl_type::error_type)
9591591693c7b415e9869157c711fe11263c95d74eDavid Li      return NULL;
9601591693c7b415e9869157c711fe11263c95d74eDavid Li
9611591693c7b415e9869157c711fe11263c95d74eDavid Li   /* From the GLSL 1.20 spec, page 23:
9621591693c7b415e9869157c711fe11263c95d74eDavid Li    * "Function calls to user-defined functions (non-built-in functions)
9631591693c7b415e9869157c711fe11263c95d74eDavid Li    *  cannot be used to form constant expressions."
9641591693c7b415e9869157c711fe11263c95d74eDavid Li    */
9651591693c7b415e9869157c711fe11263c95d74eDavid Li   if (!this->callee->is_builtin)
9661591693c7b415e9869157c711fe11263c95d74eDavid Li      return NULL;
9671591693c7b415e9869157c711fe11263c95d74eDavid Li
9681591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned num_parameters = 0;
9691591693c7b415e9869157c711fe11263c95d74eDavid Li
9701591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Check if all parameters are constant */
9711591693c7b415e9869157c711fe11263c95d74eDavid Li   ir_constant *op[3];
9721591693c7b415e9869157c711fe11263c95d74eDavid Li   foreach_list(n, &this->actual_parameters) {
9731591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_constant *constant = ((ir_rvalue *) n)->constant_expression_value();
9741591693c7b415e9869157c711fe11263c95d74eDavid Li      if (constant == NULL)
9751591693c7b415e9869157c711fe11263c95d74eDavid Li	 return NULL;
9761591693c7b415e9869157c711fe11263c95d74eDavid Li
9771591693c7b415e9869157c711fe11263c95d74eDavid Li      op[num_parameters] = constant;
9781591693c7b415e9869157c711fe11263c95d74eDavid Li
9791591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(num_parameters < 3);
9801591693c7b415e9869157c711fe11263c95d74eDavid Li      num_parameters++;
9811591693c7b415e9869157c711fe11263c95d74eDavid Li   }
9821591693c7b415e9869157c711fe11263c95d74eDavid Li
9831591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Individual cases below can either:
9841591693c7b415e9869157c711fe11263c95d74eDavid Li    * - Assign "expr" a new ir_expression to evaluate (for basic opcodes)
9851591693c7b415e9869157c711fe11263c95d74eDavid Li    * - Fill "data" with appopriate constant data
9861591693c7b415e9869157c711fe11263c95d74eDavid Li    * - Return an ir_constant directly.
9871591693c7b415e9869157c711fe11263c95d74eDavid Li    */
988d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li   void *mem_ctx = hieralloc_parent(this);
9891591693c7b415e9869157c711fe11263c95d74eDavid Li   ir_expression *expr = NULL;
9901591693c7b415e9869157c711fe11263c95d74eDavid Li
9911591693c7b415e9869157c711fe11263c95d74eDavid Li   ir_constant_data data;
9921591693c7b415e9869157c711fe11263c95d74eDavid Li   memset(&data, 0, sizeof(data));
9931591693c7b415e9869157c711fe11263c95d74eDavid Li
9941591693c7b415e9869157c711fe11263c95d74eDavid Li   const char *callee = this->callee_name();
9951591693c7b415e9869157c711fe11263c95d74eDavid Li   if (strcmp(callee, "abs") == 0) {
9961591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_unop_abs, type, op[0], NULL);
9971591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "all") == 0) {
9981591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_boolean());
9991591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
10001591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (!op[0]->value.b[c])
10011591693c7b415e9869157c711fe11263c95d74eDavid Li	    return new(mem_ctx) ir_constant(false);
10021591693c7b415e9869157c711fe11263c95d74eDavid Li      }
10031591693c7b415e9869157c711fe11263c95d74eDavid Li      return new(mem_ctx) ir_constant(true);
10041591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "any") == 0) {
10051591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_boolean());
10061591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
10071591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (op[0]->value.b[c])
10081591693c7b415e9869157c711fe11263c95d74eDavid Li	    return new(mem_ctx) ir_constant(true);
10091591693c7b415e9869157c711fe11263c95d74eDavid Li      }
10101591693c7b415e9869157c711fe11263c95d74eDavid Li      return new(mem_ctx) ir_constant(false);
10111591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "acos") == 0) {
10121591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float());
10131591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
10141591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = acosf(op[0]->value.f[c]);
10151591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "acosh") == 0) {
10161591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float());
10171591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
10181591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = acoshf(op[0]->value.f[c]);
10191591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "asin") == 0) {
10201591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float());
10211591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
10221591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = asinf(op[0]->value.f[c]);
10231591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "asinh") == 0) {
10241591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float());
10251591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
10261591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = asinhf(op[0]->value.f[c]);
10271591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "atan") == 0) {
10281591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float());
10291591693c7b415e9869157c711fe11263c95d74eDavid Li      if (num_parameters == 2) {
10301591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(op[1]->type->is_float());
10311591693c7b415e9869157c711fe11263c95d74eDavid Li	 for (unsigned c = 0; c < op[0]->type->components(); c++)
10321591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = atan2f(op[0]->value.f[c], op[1]->value.f[c]);
10331591693c7b415e9869157c711fe11263c95d74eDavid Li      } else {
10341591693c7b415e9869157c711fe11263c95d74eDavid Li	 for (unsigned c = 0; c < op[0]->type->components(); c++)
10351591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = atanf(op[0]->value.f[c]);
10361591693c7b415e9869157c711fe11263c95d74eDavid Li      }
10371591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "atanh") == 0) {
10381591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float());
10391591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
10401591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = atanhf(op[0]->value.f[c]);
10411591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "dFdx") == 0 || strcmp(callee, "dFdy") == 0) {
10421591693c7b415e9869157c711fe11263c95d74eDavid Li      return ir_constant::zero(mem_ctx, this->type);
10431591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "ceil") == 0) {
10441591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_unop_ceil, type, op[0], NULL);
10451591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "clamp") == 0) {
10461591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(num_parameters == 3);
10471591693c7b415e9869157c711fe11263c95d74eDavid Li      unsigned c1_inc = op[1]->type->is_scalar() ? 0 : 1;
10481591693c7b415e9869157c711fe11263c95d74eDavid Li      unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
10491591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0, c1 = 0, c2 = 0;
10501591693c7b415e9869157c711fe11263c95d74eDavid Li	   c < op[0]->type->components();
10511591693c7b415e9869157c711fe11263c95d74eDavid Li	   c1 += c1_inc, c2 += c2_inc, c++) {
10521591693c7b415e9869157c711fe11263c95d74eDavid Li
10531591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
10541591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
10551591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.u[c] = CLAMP(op[0]->value.u[c], op[1]->value.u[c1],
10561591693c7b415e9869157c711fe11263c95d74eDavid Li			      op[2]->value.u[c2]);
10571591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
10581591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
10591591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.i[c] = CLAMP(op[0]->value.i[c], op[1]->value.i[c1],
10601591693c7b415e9869157c711fe11263c95d74eDavid Li			      op[2]->value.i[c2]);
10611591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
10621591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
10631591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = CLAMP(op[0]->value.f[c], op[1]->value.f[c1],
10641591693c7b415e9869157c711fe11263c95d74eDavid Li			      op[2]->value.f[c2]);
10651591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
10661591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
10671591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(!"Should not get here.");
10681591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
10691591693c7b415e9869157c711fe11263c95d74eDavid Li      }
10701591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "cos") == 0) {
10711591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_unop_cos, type, op[0], NULL);
10721591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "cosh") == 0) {
10731591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float());
10741591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
10751591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = coshf(op[0]->value.f[c]);
10761591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "cross") == 0) {
10771591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type == glsl_type::vec3_type);
10781591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[1]->type == glsl_type::vec3_type);
10791591693c7b415e9869157c711fe11263c95d74eDavid Li      data.f[0] = (op[0]->value.f[1] * op[1]->value.f[2] -
10801591693c7b415e9869157c711fe11263c95d74eDavid Li		   op[1]->value.f[1] * op[0]->value.f[2]);
10811591693c7b415e9869157c711fe11263c95d74eDavid Li      data.f[1] = (op[0]->value.f[2] * op[1]->value.f[0] -
10821591693c7b415e9869157c711fe11263c95d74eDavid Li		   op[1]->value.f[2] * op[0]->value.f[0]);
10831591693c7b415e9869157c711fe11263c95d74eDavid Li      data.f[2] = (op[0]->value.f[0] * op[1]->value.f[1] -
10841591693c7b415e9869157c711fe11263c95d74eDavid Li		   op[1]->value.f[0] * op[0]->value.f[1]);
10851591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "degrees") == 0) {
10861591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float());
10871591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
10881591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = 180.0F / M_PI * op[0]->value.f[c];
10891591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "distance") == 0) {
10901591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float() && op[1]->type->is_float());
10911591693c7b415e9869157c711fe11263c95d74eDavid Li      float length_squared = 0.0;
10921591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
10931591693c7b415e9869157c711fe11263c95d74eDavid Li	 float t = op[0]->value.f[c] - op[1]->value.f[c];
10941591693c7b415e9869157c711fe11263c95d74eDavid Li	 length_squared += t * t;
10951591693c7b415e9869157c711fe11263c95d74eDavid Li      }
10961591693c7b415e9869157c711fe11263c95d74eDavid Li      return new(mem_ctx) ir_constant(sqrtf(length_squared));
10971591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "dot") == 0) {
10981591693c7b415e9869157c711fe11263c95d74eDavid Li      return new(mem_ctx) ir_constant(dot(op[0], op[1]));
10991591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "equal") == 0) {
11001591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
11011591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
11021591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
11031591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
11041591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.u[c] == op[1]->value.u[c];
11051591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
11061591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
11071591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.i[c] == op[1]->value.i[c];
11081591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
11091591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
11101591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.f[c] == op[1]->value.f[c];
11111591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
11121591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_BOOL:
11131591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.b[c] == op[1]->value.b[c];
11141591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
11151591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
11161591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(!"Should not get here.");
11171591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
11181591693c7b415e9869157c711fe11263c95d74eDavid Li      }
11191591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "exp") == 0) {
11201591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_unop_exp, type, op[0], NULL);
11211591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "exp2") == 0) {
11221591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_unop_exp2, type, op[0], NULL);
11231591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "faceforward") == 0) {
11241591693c7b415e9869157c711fe11263c95d74eDavid Li      if (dot(op[2], op[1]) < 0)
11251591693c7b415e9869157c711fe11263c95d74eDavid Li	 return op[0];
11261591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
11271591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = -op[0]->value.f[c];
11281591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "floor") == 0) {
11291591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_unop_floor, type, op[0], NULL);
11301591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "fract") == 0) {
11311591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_unop_fract, type, op[0], NULL);
11321591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "fwidth") == 0) {
11331591693c7b415e9869157c711fe11263c95d74eDavid Li      return ir_constant::zero(mem_ctx, this->type);
11341591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "greaterThan") == 0) {
11351591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
11361591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
11371591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
11381591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
11391591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
11401591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
11411591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
11421591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
11431591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
11441591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
11451591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
11461591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
11471591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
11481591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(!"Should not get here.");
11491591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
11501591693c7b415e9869157c711fe11263c95d74eDavid Li      }
11511591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "greaterThanEqual") == 0) {
11521591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
11531591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
11541591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
11551591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
11561591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.u[c] >= op[1]->value.u[c];
11571591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
11581591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
11591591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.i[c] >= op[1]->value.i[c];
11601591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
11611591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
11621591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.f[c] >= op[1]->value.f[c];
11631591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
11641591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
11651591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(!"Should not get here.");
11661591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
11671591693c7b415e9869157c711fe11263c95d74eDavid Li      }
11681591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "inversesqrt") == 0) {
11691591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_unop_rsq, type, op[0], NULL);
11701591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "length") == 0) {
11711591693c7b415e9869157c711fe11263c95d74eDavid Li      return new(mem_ctx) ir_constant(sqrtf(dot(op[0], op[0])));
11721591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "lessThan") == 0) {
11731591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
11741591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
11751591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
11761591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
11771591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.u[c] < op[1]->value.u[c];
11781591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
11791591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
11801591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.i[c] < op[1]->value.i[c];
11811591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
11821591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
11831591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.f[c] < op[1]->value.f[c];
11841591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
11851591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
11861591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(!"Should not get here.");
11871591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
11881591693c7b415e9869157c711fe11263c95d74eDavid Li      }
11891591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "lessThanEqual") == 0) {
11901591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
11911591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
11921591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
11931591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
11941591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.u[c] <= op[1]->value.u[c];
11951591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
11961591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
11971591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.i[c] <= op[1]->value.i[c];
11981591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
11991591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
12001591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.f[c] <= op[1]->value.f[c];
12011591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
12021591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
12031591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(!"Should not get here.");
12041591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
12051591693c7b415e9869157c711fe11263c95d74eDavid Li      }
12061591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "log") == 0) {
12071591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_unop_log, type, op[0], NULL);
12081591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "log2") == 0) {
12091591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_unop_log2, type, op[0], NULL);
12101591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "matrixCompMult") == 0) {
12111591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float() && op[1]->type->is_float());
12121591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
12131591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = op[0]->value.f[c] * op[1]->value.f[c];
12141591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "max") == 0) {
12151591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_binop_max, type, op[0], op[1]);
12161591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "min") == 0) {
12171591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_binop_min, type, op[0], op[1]);
12181591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "mix") == 0) {
12191591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float() && op[1]->type->is_float());
12201591693c7b415e9869157c711fe11263c95d74eDavid Li      if (op[2]->type->is_float()) {
12211591693c7b415e9869157c711fe11263c95d74eDavid Li	 unsigned c2_inc = op[2]->type->is_scalar() ? 0 : 1;
12221591693c7b415e9869157c711fe11263c95d74eDavid Li	 unsigned components = op[0]->type->components();
12231591693c7b415e9869157c711fe11263c95d74eDavid Li	 for (unsigned c = 0, c2 = 0; c < components; c2 += c2_inc, c++) {
12241591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = op[0]->value.f[c] * (1 - op[2]->value.f[c2]) +
12251591693c7b415e9869157c711fe11263c95d74eDavid Li			op[1]->value.f[c] * op[2]->value.f[c2];
12261591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
12271591693c7b415e9869157c711fe11263c95d74eDavid Li      } else {
12281591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(op[2]->type->is_boolean());
12291591693c7b415e9869157c711fe11263c95d74eDavid Li	 for (unsigned c = 0; c < op[0]->type->components(); c++)
12301591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = op[op[2]->value.b[c] ? 1 : 0]->value.f[c];
12311591693c7b415e9869157c711fe11263c95d74eDavid Li      }
12321591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "mod") == 0) {
12331591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_binop_mod, type, op[0], op[1]);
12341591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "normalize") == 0) {
12351591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float());
12361591693c7b415e9869157c711fe11263c95d74eDavid Li      float length = sqrtf(dot(op[0], op[0]));
12371591693c7b415e9869157c711fe11263c95d74eDavid Li
12381591693c7b415e9869157c711fe11263c95d74eDavid Li      if (length == 0)
12391591693c7b415e9869157c711fe11263c95d74eDavid Li	 return ir_constant::zero(mem_ctx, this->type);
12401591693c7b415e9869157c711fe11263c95d74eDavid Li
12411591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
12421591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = op[0]->value.f[c] / length;
12431591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "not") == 0) {
12441591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_unop_logic_not, type, op[0], NULL);
12451591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "notEqual") == 0) {
12461591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_vector() && op[1] && op[1]->type->is_vector());
12471591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++) {
12481591693c7b415e9869157c711fe11263c95d74eDavid Li	 switch (op[0]->type->base_type) {
12491591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_UINT:
12501591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.u[c] != op[1]->value.u[c];
12511591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
12521591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_INT:
12531591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.i[c] != op[1]->value.i[c];
12541591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
12551591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_FLOAT:
12561591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.f[c] != op[1]->value.f[c];
12571591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
12581591693c7b415e9869157c711fe11263c95d74eDavid Li	 case GLSL_TYPE_BOOL:
12591591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.b[c] = op[0]->value.b[c] != op[1]->value.b[c];
12601591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
12611591693c7b415e9869157c711fe11263c95d74eDavid Li	 default:
12621591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(!"Should not get here.");
12631591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
12641591693c7b415e9869157c711fe11263c95d74eDavid Li      }
12651591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "outerProduct") == 0) {
12661591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_vector() && op[1]->type->is_vector());
12671591693c7b415e9869157c711fe11263c95d74eDavid Li      const unsigned m = op[0]->type->vector_elements;
12681591693c7b415e9869157c711fe11263c95d74eDavid Li      const unsigned n = op[1]->type->vector_elements;
12691591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned j = 0; j < n; j++) {
12701591693c7b415e9869157c711fe11263c95d74eDavid Li	 for (unsigned i = 0; i < m; i++) {
12711591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[i+m*j] = op[0]->value.f[i] * op[1]->value.f[j];
12721591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
12731591693c7b415e9869157c711fe11263c95d74eDavid Li      }
12741591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "pow") == 0) {
12751591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_binop_pow, type, op[0], op[1]);
12761591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "radians") == 0) {
12771591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float());
12781591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
12791591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = M_PI / 180.0F * op[0]->value.f[c];
12801591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "reflect") == 0) {
12811591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float());
12821591693c7b415e9869157c711fe11263c95d74eDavid Li      float dot_NI = dot(op[1], op[0]);
12831591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
12841591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = op[0]->value.f[c] - 2 * dot_NI * op[1]->value.f[c];
12851591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "refract") == 0) {
12861591693c7b415e9869157c711fe11263c95d74eDavid Li      const float eta = op[2]->value.f[0];
12871591693c7b415e9869157c711fe11263c95d74eDavid Li      const float dot_NI = dot(op[1], op[0]);
12881591693c7b415e9869157c711fe11263c95d74eDavid Li      const float k = 1.0F - eta * eta * (1.0F - dot_NI * dot_NI);
12891591693c7b415e9869157c711fe11263c95d74eDavid Li      if (k < 0.0) {
12901591693c7b415e9869157c711fe11263c95d74eDavid Li	 return ir_constant::zero(mem_ctx, this->type);
12911591693c7b415e9869157c711fe11263c95d74eDavid Li      } else {
12921591693c7b415e9869157c711fe11263c95d74eDavid Li	 for (unsigned c = 0; c < type->components(); c++) {
12931591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = eta * op[0]->value.f[c] - (eta * dot_NI + sqrtf(k))
12941591693c7b415e9869157c711fe11263c95d74eDavid Li			    * op[1]->value.f[c];
12951591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
12961591693c7b415e9869157c711fe11263c95d74eDavid Li      }
12971591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "sign") == 0) {
12981591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_unop_sign, type, op[0], NULL);
12991591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "sin") == 0) {
13001591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_unop_sin, type, op[0], NULL);
13011591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "sinh") == 0) {
13021591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float());
13031591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
13041591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = sinhf(op[0]->value.f[c]);
13051591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "smoothstep") == 0) {
13061591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(num_parameters == 3);
13071591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[1]->type == op[0]->type);
13081591693c7b415e9869157c711fe11263c95d74eDavid Li      unsigned edge_inc = op[0]->type->is_scalar() ? 0 : 1;
13091591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0, e = 0; c < type->components(); e += edge_inc, c++) {
13101591693c7b415e9869157c711fe11263c95d74eDavid Li	 const float edge0 = op[0]->value.f[e];
13111591693c7b415e9869157c711fe11263c95d74eDavid Li	 const float edge1 = op[1]->value.f[e];
13121591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (edge0 == edge1) {
13131591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = 0.0; /* Avoid a crash - results are undefined anyway */
13141591693c7b415e9869157c711fe11263c95d74eDavid Li	 } else {
13151591693c7b415e9869157c711fe11263c95d74eDavid Li	    const float numerator = op[2]->value.f[c] - edge0;
13161591693c7b415e9869157c711fe11263c95d74eDavid Li	    const float denominator = edge1 - edge0;
13171591693c7b415e9869157c711fe11263c95d74eDavid Li	    const float t = CLAMP(numerator/denominator, 0, 1);
13181591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[c] = t * t * (3 - 2 * t);
13191591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
13201591693c7b415e9869157c711fe11263c95d74eDavid Li      }
13211591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "sqrt") == 0) {
13221591693c7b415e9869157c711fe11263c95d74eDavid Li      expr = new(mem_ctx) ir_expression(ir_unop_sqrt, type, op[0], NULL);
13231591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "step") == 0) {
13241591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float() && op[1]->type->is_float());
13251591693c7b415e9869157c711fe11263c95d74eDavid Li      /* op[0] (edge) may be either a scalar or a vector */
13261591693c7b415e9869157c711fe11263c95d74eDavid Li      const unsigned c0_inc = op[0]->type->is_scalar() ? 0 : 1;
13271591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0, c0 = 0; c < type->components(); c0 += c0_inc, c++)
13281591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = (op[1]->value.f[c] < op[0]->value.f[c0]) ? 0.0F : 1.0F;
13291591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "tan") == 0) {
13301591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float());
13311591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
13321591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = tanf(op[0]->value.f[c]);
13331591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "tanh") == 0) {
13341591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_float());
13351591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned c = 0; c < op[0]->type->components(); c++)
13361591693c7b415e9869157c711fe11263c95d74eDavid Li	 data.f[c] = tanhf(op[0]->value.f[c]);
13371591693c7b415e9869157c711fe11263c95d74eDavid Li   } else if (strcmp(callee, "transpose") == 0) {
13381591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(op[0]->type->is_matrix());
13391591693c7b415e9869157c711fe11263c95d74eDavid Li      const unsigned n = op[0]->type->vector_elements;
13401591693c7b415e9869157c711fe11263c95d74eDavid Li      const unsigned m = op[0]->type->matrix_columns;
13411591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned j = 0; j < m; j++) {
13421591693c7b415e9869157c711fe11263c95d74eDavid Li	 for (unsigned i = 0; i < n; i++) {
13431591693c7b415e9869157c711fe11263c95d74eDavid Li	    data.f[m*i+j] += op[0]->value.f[i+n*j];
13441591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
13451591693c7b415e9869157c711fe11263c95d74eDavid Li      }
13461591693c7b415e9869157c711fe11263c95d74eDavid Li   } else {
13471591693c7b415e9869157c711fe11263c95d74eDavid Li      /* Unsupported builtin - some are not allowed in constant expressions. */
13481591693c7b415e9869157c711fe11263c95d74eDavid Li      return NULL;
13491591693c7b415e9869157c711fe11263c95d74eDavid Li   }
13501591693c7b415e9869157c711fe11263c95d74eDavid Li
13511591693c7b415e9869157c711fe11263c95d74eDavid Li   if (expr != NULL)
13521591693c7b415e9869157c711fe11263c95d74eDavid Li      return expr->constant_expression_value();
13531591693c7b415e9869157c711fe11263c95d74eDavid Li
13541591693c7b415e9869157c711fe11263c95d74eDavid Li   return new(mem_ctx) ir_constant(this->type, &data);
13551591693c7b415e9869157c711fe11263c95d74eDavid Li}
1356