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