glsl: Sort constant expression handling by IR operand enum value
authorIan Romanick <ian.d.romanick@intel.com>
Wed, 13 Jul 2016 00:26:38 +0000 (17:26 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Tue, 30 Aug 2016 23:28:01 +0000 (16:28 -0700)
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
src/compiler/glsl/ir_constant_expression.cpp

index c9f4949c6e89197572fd82b50b27b88242684d45..6ced8c8016b60bd2083e7deac9363a0ba64003f5 100644 (file)
@@ -676,6 +676,124 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
           data.b[c] = !op[0]->value.b[c];
       break;
 
+   case ir_unop_neg:
+      for (unsigned c = 0; c < op[0]->type->components(); c++) {
+         switch (this->type->base_type) {
+         case GLSL_TYPE_UINT:
+            data.u[c] = -((int) op[0]->value.u[c]);
+            break;
+         case GLSL_TYPE_INT:
+            data.i[c] = -op[0]->value.i[c];
+            break;
+         case GLSL_TYPE_FLOAT:
+            data.f[c] = -op[0]->value.f[c];
+            break;
+         case GLSL_TYPE_DOUBLE:
+            data.d[c] = -op[0]->value.d[c];
+            break;
+         default:
+            assert(0);
+         }
+      }
+      break;
+
+   case ir_unop_abs:
+      for (unsigned c = 0; c < op[0]->type->components(); c++) {
+         switch (this->type->base_type) {
+         case GLSL_TYPE_INT:
+            data.i[c] = op[0]->value.i[c];
+            if (data.i[c] < 0)
+               data.i[c] = -data.i[c];
+            break;
+         case GLSL_TYPE_FLOAT:
+            data.f[c] = fabs(op[0]->value.f[c]);
+            break;
+         case GLSL_TYPE_DOUBLE:
+            data.d[c] = fabs(op[0]->value.d[c]);
+            break;
+         default:
+            assert(0);
+         }
+      }
+      break;
+
+   case ir_unop_sign:
+      for (unsigned c = 0; c < op[0]->type->components(); c++) {
+         switch (this->type->base_type) {
+         case GLSL_TYPE_INT:
+            data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
+            break;
+         case GLSL_TYPE_FLOAT:
+            data.f[c] = float((op[0]->value.f[c] > 0.0F) - (op[0]->value.f[c] < 0.0F));
+            break;
+         case GLSL_TYPE_DOUBLE:
+            data.d[c] = double((op[0]->value.d[c] > 0.0) - (op[0]->value.d[c] < 0.0));
+            break;
+         default:
+            assert(0);
+         }
+      }
+      break;
+
+   case ir_unop_rcp:
+      for (unsigned c = 0; c < op[0]->type->components(); c++) {
+         switch (this->type->base_type) {
+         case GLSL_TYPE_FLOAT:
+            if (op[0]->value.f[c] != 0.0F)
+               data.f[c] = 1.0F / op[0]->value.f[c];
+            break;
+         case GLSL_TYPE_DOUBLE:
+            if (op[0]->value.d[c] != 0.0)
+               data.d[c] = 1.0 / op[0]->value.d[c];
+            break;
+         default:
+            assert(0);
+         }
+      }
+      break;
+
+   case ir_unop_rsq:
+      for (unsigned c = 0; c < op[0]->type->components(); c++) {
+         if (op[0]->type->base_type == GLSL_TYPE_DOUBLE)
+            data.d[c] = 1.0 / sqrt(op[0]->value.d[c]);
+         else
+            data.f[c] = 1.0F / sqrtf(op[0]->value.f[c]);
+      }
+      break;
+
+   case ir_unop_sqrt:
+      for (unsigned c = 0; c < op[0]->type->components(); c++) {
+         if (op[0]->type->base_type == GLSL_TYPE_DOUBLE)
+            data.d[c] = sqrt(op[0]->value.d[c]);
+         else
+            data.f[c] = sqrtf(op[0]->value.f[c]);
+      }
+      break;
+
+   case ir_unop_exp:
+      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+      for (unsigned c = 0; c < op[0]->type->components(); c++)
+         data.f[c] = expf(op[0]->value.f[c]);
+      break;
+
+   case ir_unop_log:
+      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+      for (unsigned c = 0; c < op[0]->type->components(); c++)
+         data.f[c] = logf(op[0]->value.f[c]);
+      break;
+
+   case ir_unop_exp2:
+      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+      for (unsigned c = 0; c < op[0]->type->components(); c++)
+         data.f[c] = exp2f(op[0]->value.f[c]);
+      break;
+
+   case ir_unop_log2:
+      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+      for (unsigned c = 0; c < op[0]->type->components(); c++)
+         data.f[c] = log2f(op[0]->value.f[c]);
+      break;
+
    case ir_unop_f2i:
       assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
       for (unsigned c = 0; c < op[0]->type->components(); c++)
@@ -694,10 +812,10 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
          data.f[c] = (float) op[0]->value.i[c];
       break;
 
-   case ir_unop_u2f:
-      assert(op[0]->type->base_type == GLSL_TYPE_UINT);
+   case ir_unop_f2b:
+      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
       for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.f[c] = (float) op[0]->value.u[c];
+         data.b[c] = op[0]->value.f[c] != 0.0F ? true : false;
       break;
 
    case ir_unop_b2f:
@@ -706,10 +824,10 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
          data.f[c] = op[0]->value.b[c] ? 1.0F : 0.0F;
       break;
 
-   case ir_unop_f2b:
-      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+   case ir_unop_i2b:
+      assert(op[0]->type->is_integer());
       for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.b[c] = op[0]->value.f[c] != 0.0F ? true : false;
+         data.b[c] = op[0]->value.u[c] ? true : false;
       break;
 
    case ir_unop_b2i:
@@ -718,16 +836,10 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
          data.i[c] = op[0]->value.b[c] ? 1 : 0;
       break;
 
-   case ir_unop_i2b:
-      assert(op[0]->type->is_integer());
-      for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.b[c] = op[0]->value.u[c] ? true : false;
-      break;
-
-   case ir_unop_u2i:
+   case ir_unop_u2f:
       assert(op[0]->type->base_type == GLSL_TYPE_UINT);
       for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.i[c] = op[0]->value.u[c];
+         data.f[c] = (float) op[0]->value.u[c];
       break;
 
    case ir_unop_i2u:
@@ -736,28 +848,10 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
          data.u[c] = op[0]->value.i[c];
       break;
 
-   case ir_unop_bitcast_i2f:
-      assert(op[0]->type->base_type == GLSL_TYPE_INT);
-      for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.f[c] = bitcast_u2f(op[0]->value.i[c]);
-      break;
-
-   case ir_unop_bitcast_f2i:
-      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
-      for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.i[c] = bitcast_f2u(op[0]->value.f[c]);
-      break;
-
-   case ir_unop_bitcast_u2f:
+   case ir_unop_u2i:
       assert(op[0]->type->base_type == GLSL_TYPE_UINT);
       for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.f[c] = bitcast_u2f(op[0]->value.u[c]);
-      break;
-
-   case ir_unop_bitcast_f2u:
-      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
-      for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.u[c] = bitcast_f2u(op[0]->value.f[c]);
+         data.i[c] = op[0]->value.u[c];
       break;
 
    case ir_unop_d2f:
@@ -802,22 +896,36 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
          data.b[c] = op[0]->value.d[c] != 0.0;
       break;
 
-   case ir_unop_trunc:
-      for (unsigned c = 0; c < op[0]->type->components(); c++) {
-         if (op[0]->type->base_type == GLSL_TYPE_DOUBLE)
-            data.d[c] = trunc(op[0]->value.d[c]);
-         else
-            data.f[c] = truncf(op[0]->value.f[c]);
-      }
+   case ir_unop_bitcast_i2f:
+      assert(op[0]->type->base_type == GLSL_TYPE_INT);
+      for (unsigned c = 0; c < op[0]->type->components(); c++)
+         data.f[c] = bitcast_u2f(op[0]->value.i[c]);
       break;
 
+   case ir_unop_bitcast_f2i:
+      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+      for (unsigned c = 0; c < op[0]->type->components(); c++)
+         data.i[c] = bitcast_f2u(op[0]->value.f[c]);
+      break;
 
-   case ir_unop_round_even:
+   case ir_unop_bitcast_u2f:
+      assert(op[0]->type->base_type == GLSL_TYPE_UINT);
+      for (unsigned c = 0; c < op[0]->type->components(); c++)
+         data.f[c] = bitcast_u2f(op[0]->value.u[c]);
+      break;
+
+   case ir_unop_bitcast_f2u:
+      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+      for (unsigned c = 0; c < op[0]->type->components(); c++)
+         data.u[c] = bitcast_f2u(op[0]->value.f[c]);
+      break;
+
+   case ir_unop_trunc:
       for (unsigned c = 0; c < op[0]->type->components(); c++) {
          if (op[0]->type->base_type == GLSL_TYPE_DOUBLE)
-            data.d[c] = _mesa_roundeven(op[0]->value.d[c]);
+            data.d[c] = trunc(op[0]->value.d[c]);
          else
-            data.f[c] = _mesa_roundevenf(op[0]->value.f[c]);
+            data.f[c] = truncf(op[0]->value.f[c]);
       }
       break;
 
@@ -854,134 +962,25 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
       }
       break;
 
-   case ir_unop_sin:
-      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
-      for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.f[c] = sinf(op[0]->value.f[c]);
-      break;
-
-   case ir_unop_cos:
-      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
-      for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.f[c] = cosf(op[0]->value.f[c]);
-      break;
-
-   case ir_unop_neg:
-      for (unsigned c = 0; c < op[0]->type->components(); c++) {
-         switch (this->type->base_type) {
-         case GLSL_TYPE_UINT:
-            data.u[c] = -((int) op[0]->value.u[c]);
-            break;
-         case GLSL_TYPE_INT:
-            data.i[c] = -op[0]->value.i[c];
-            break;
-         case GLSL_TYPE_FLOAT:
-            data.f[c] = -op[0]->value.f[c];
-            break;
-         case GLSL_TYPE_DOUBLE:
-            data.d[c] = -op[0]->value.d[c];
-            break;
-         default:
-            assert(0);
-         }
-      }
-      break;
-
-   case ir_unop_abs:
-      for (unsigned c = 0; c < op[0]->type->components(); c++) {
-         switch (this->type->base_type) {
-         case GLSL_TYPE_INT:
-            data.i[c] = op[0]->value.i[c];
-            if (data.i[c] < 0)
-               data.i[c] = -data.i[c];
-            break;
-         case GLSL_TYPE_FLOAT:
-            data.f[c] = fabs(op[0]->value.f[c]);
-            break;
-         case GLSL_TYPE_DOUBLE:
-            data.d[c] = fabs(op[0]->value.d[c]);
-            break;
-         default:
-            assert(0);
-         }
-      }
-      break;
-
-   case ir_unop_sign:
-      for (unsigned c = 0; c < op[0]->type->components(); c++) {
-         switch (this->type->base_type) {
-         case GLSL_TYPE_INT:
-            data.i[c] = (op[0]->value.i[c] > 0) - (op[0]->value.i[c] < 0);
-            break;
-         case GLSL_TYPE_FLOAT:
-            data.f[c] = float((op[0]->value.f[c] > 0.0F) - (op[0]->value.f[c] < 0.0F));
-            break;
-         case GLSL_TYPE_DOUBLE:
-            data.d[c] = double((op[0]->value.d[c] > 0.0) - (op[0]->value.d[c] < 0.0));
-            break;
-         default:
-            assert(0);
-         }
-      }
-      break;
-
-   case ir_unop_rcp:
-      for (unsigned c = 0; c < op[0]->type->components(); c++) {
-         switch (this->type->base_type) {
-         case GLSL_TYPE_FLOAT:
-            if (op[0]->value.f[c] != 0.0F)
-               data.f[c] = 1.0F / op[0]->value.f[c];
-            break;
-         case GLSL_TYPE_DOUBLE:
-            if (op[0]->value.d[c] != 0.0)
-               data.d[c] = 1.0 / op[0]->value.d[c];
-            break;
-         default:
-            assert(0);
-         }
-      }
-      break;
-
-   case ir_unop_rsq:
-      for (unsigned c = 0; c < op[0]->type->components(); c++) {
-         if (op[0]->type->base_type == GLSL_TYPE_DOUBLE)
-            data.d[c] = 1.0 / sqrt(op[0]->value.d[c]);
-         else
-            data.f[c] = 1.0F / sqrtf(op[0]->value.f[c]);
-      }
-      break;
-
-   case ir_unop_sqrt:
+   case ir_unop_round_even:
       for (unsigned c = 0; c < op[0]->type->components(); c++) {
          if (op[0]->type->base_type == GLSL_TYPE_DOUBLE)
-            data.d[c] = sqrt(op[0]->value.d[c]);
+            data.d[c] = _mesa_roundeven(op[0]->value.d[c]);
          else
-            data.f[c] = sqrtf(op[0]->value.f[c]);
+            data.f[c] = _mesa_roundevenf(op[0]->value.f[c]);
       }
       break;
 
-   case ir_unop_exp:
-      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
-      for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.f[c] = expf(op[0]->value.f[c]);
-      break;
-
-   case ir_unop_exp2:
-      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
-      for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.f[c] = exp2f(op[0]->value.f[c]);
-      break;
-
-   case ir_unop_log:
+   case ir_unop_sin:
       assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
       for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.f[c] = logf(op[0]->value.f[c]);
+         data.f[c] = sinf(op[0]->value.f[c]);
       break;
 
-   case ir_unop_log2:
+   case ir_unop_cos:
       assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
       for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.f[c] = log2f(op[0]->value.f[c]);
+         data.f[c] = cosf(op[0]->value.f[c]);
       break;
 
    case ir_unop_dFdx:
@@ -1011,20 +1010,6 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
                            op[0]->value.f[3]);
       break;
 
-   case ir_unop_unpack_snorm_2x16:
-      assert(op[0]->type == glsl_type::uint_type);
-      unpack_2x16(unpack_snorm_1x16,
-                  op[0]->value.u[0],
-                  &data.f[0], &data.f[1]);
-      break;
-
-   case ir_unop_unpack_snorm_4x8:
-      assert(op[0]->type == glsl_type::uint_type);
-      unpack_4x8(unpack_snorm_1x8,
-                 op[0]->value.u[0],
-                 &data.f[0], &data.f[1], &data.f[2], &data.f[3]);
-      break;
-
    case ir_unop_pack_unorm_2x16:
       assert(op[0]->type == glsl_type::vec2_type);
       data.u[0] = pack_2x16(pack_unorm_1x16,
@@ -1041,6 +1026,27 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
                            op[0]->value.f[3]);
       break;
 
+   case ir_unop_pack_half_2x16:
+      assert(op[0]->type == glsl_type::vec2_type);
+      data.u[0] = pack_2x16(pack_half_1x16,
+                            op[0]->value.f[0],
+                            op[0]->value.f[1]);
+      break;
+
+   case ir_unop_unpack_snorm_2x16:
+      assert(op[0]->type == glsl_type::uint_type);
+      unpack_2x16(unpack_snorm_1x16,
+                  op[0]->value.u[0],
+                  &data.f[0], &data.f[1]);
+      break;
+
+   case ir_unop_unpack_snorm_4x8:
+      assert(op[0]->type == glsl_type::uint_type);
+      unpack_4x8(unpack_snorm_1x8,
+                 op[0]->value.u[0],
+                 &data.f[0], &data.f[1], &data.f[2], &data.f[3]);
+      break;
+
    case ir_unop_unpack_unorm_2x16:
       assert(op[0]->type == glsl_type::uint_type);
       unpack_2x16(unpack_unorm_1x16,
@@ -1055,13 +1061,6 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
                  &data.f[0], &data.f[1], &data.f[2], &data.f[3]);
       break;
 
-   case ir_unop_pack_half_2x16:
-      assert(op[0]->type == glsl_type::vec2_type);
-      data.u[0] = pack_2x16(pack_half_1x16,
-                            op[0]->value.f[0],
-                            op[0]->value.f[1]);
-      break;
-
    case ir_unop_unpack_half_2x16:
       assert(op[0]->type == glsl_type::uint_type);
       unpack_2x16(unpack_half_1x16,
@@ -1069,37 +1068,34 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
                   &data.f[0], &data.f[1]);
       break;
 
-   case ir_binop_pow:
-      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
-      for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]);
-      break;
-
-   case ir_binop_dot:
-      if (op[0]->type->base_type == GLSL_TYPE_DOUBLE)
-         data.d[0] = dot_d(op[0], op[1]);
-      else
-         data.f[0] = dot_f(op[0], op[1]);
+   case ir_unop_bitfield_reverse:
+      for (unsigned c = 0; c < op[0]->type->components(); c++) {
+         switch (this->type->base_type) {
+         case GLSL_TYPE_UINT:
+            data.u[c] = bitfield_reverse(op[0]->value.u[c]);
+            break;
+         case GLSL_TYPE_INT:
+            data.i[c] = bitfield_reverse(op[0]->value.i[c]);
+            break;
+         default:
+            assert(0);
+         }
+      }
       break;
 
-   case ir_binop_min:
-      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
-      for (unsigned c = 0, c0 = 0, c1 = 0;
-           c < components;
-           c0 += c0_inc, c1 += c1_inc, c++) {
+   case ir_unop_bit_count:
+      for (unsigned c = 0; c < components; c++)
+         data.i[c] = _mesa_bitcount(op[0]->value.u[c]);
+      break;
 
+   case ir_unop_find_msb:
+      for (unsigned c = 0; c < components; c++) {
          switch (op[0]->type->base_type) {
          case GLSL_TYPE_UINT:
-            data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]);
+            data.i[c] = find_msb_uint(op[0]->value.u[c]);
             break;
          case GLSL_TYPE_INT:
-            data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]);
-            break;
-         case GLSL_TYPE_FLOAT:
-            data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]);
-            break;
-         case GLSL_TYPE_DOUBLE:
-            data.d[c] = MIN2(op[0]->value.d[c0], op[1]->value.d[c1]);
+            data.i[c] = find_msb_int(op[0]->value.i[c]);
             break;
          default:
             assert(0);
@@ -1107,24 +1103,14 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
       }
       break;
 
-   case ir_binop_max:
-      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
-      for (unsigned c = 0, c0 = 0, c1 = 0;
-           c < components;
-           c0 += c0_inc, c1 += c1_inc, c++) {
-
+   case ir_unop_find_lsb:
+      for (unsigned c = 0; c < components; c++) {
          switch (op[0]->type->base_type) {
          case GLSL_TYPE_UINT:
-            data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]);
+            data.i[c] = find_msb_uint(op[0]->value.u[c] & -op[0]->value.u[c]);
             break;
          case GLSL_TYPE_INT:
-            data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]);
-            break;
-         case GLSL_TYPE_FLOAT:
-            data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]);
-            break;
-         case GLSL_TYPE_DOUBLE:
-            data.d[c] = MAX2(op[0]->value.d[c0], op[1]->value.d[c1]);
+            data.i[c] = find_msb_uint(op[0]->value.i[c] & -op[0]->value.i[c]);
             break;
          default:
             assert(0);
@@ -1132,6 +1118,21 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
       }
       break;
 
+   case ir_unop_saturate:
+      for (unsigned c = 0; c < components; c++)
+         data.f[c] = CLAMP(op[0]->value.f[c], 0.0f, 1.0f);
+      break;
+
+   case ir_unop_pack_double_2x32:
+      /* XXX needs to be checked on big-endian */
+      memcpy(&data.d[0], &op[0]->value.u[0], sizeof(double));
+      break;
+
+   case ir_unop_unpack_double_2x32:
+      /* XXX needs to be checked on big-endian */
+      memcpy(&data.u[0], &op[0]->value.d[0], sizeof(double));
+      break;
+
    case ir_binop_add:
       assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
       for (unsigned c = 0, c0 = 0, c1 = 0;
@@ -1312,24 +1313,6 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
       }
       break;
 
-   case ir_binop_logic_and:
-      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
-      for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
-      break;
-
-   case ir_binop_logic_xor:
-      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
-      for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
-      break;
-
-   case ir_binop_logic_or:
-      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
-      for (unsigned c = 0; c < op[0]->type->components(); c++)
-         data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
-      break;
-
    case ir_binop_less:
       assert(op[0]->type == op[1]->type);
       for (unsigned c = 0; c < op[0]->type->components(); c++) {
@@ -1542,17 +1525,17 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
       }
       break;
 
-   case ir_binop_bit_or:
+   case ir_binop_bit_xor:
       for (unsigned c = 0, c0 = 0, c1 = 0;
            c < components;
            c0 += c0_inc, c1 += c1_inc, c++) {
 
           switch (op[0]->type->base_type) {
           case GLSL_TYPE_UINT:
-              data.u[c] = op[0]->value.u[c0] | op[1]->value.u[c1];
+              data.u[c] = op[0]->value.u[c0] ^ op[1]->value.u[c1];
               break;
           case GLSL_TYPE_INT:
-              data.i[c] = op[0]->value.i[c0] | op[1]->value.i[c1];
+              data.i[c] = op[0]->value.i[c0] ^ op[1]->value.i[c1];
               break;
           default:
               assert(0);
@@ -1560,43 +1543,17 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
       }
       break;
 
-   case ir_binop_vector_extract: {
-      const int c = CLAMP(op[1]->value.i[0], 0,
-                          (int) op[0]->type->vector_elements - 1);
-
-      switch (op[0]->type->base_type) {
-      case GLSL_TYPE_UINT:
-         data.u[0] = op[0]->value.u[c];
-         break;
-      case GLSL_TYPE_INT:
-         data.i[0] = op[0]->value.i[c];
-         break;
-      case GLSL_TYPE_FLOAT:
-         data.f[0] = op[0]->value.f[c];
-         break;
-      case GLSL_TYPE_DOUBLE:
-         data.d[0] = op[0]->value.d[c];
-         break;
-      case GLSL_TYPE_BOOL:
-         data.b[0] = op[0]->value.b[c];
-         break;
-      default:
-         assert(0);
-      }
-      break;
-   }
-
-   case ir_binop_bit_xor:
+   case ir_binop_bit_or:
       for (unsigned c = 0, c0 = 0, c1 = 0;
            c < components;
            c0 += c0_inc, c1 += c1_inc, c++) {
 
           switch (op[0]->type->base_type) {
           case GLSL_TYPE_UINT:
-              data.u[c] = op[0]->value.u[c0] ^ op[1]->value.u[c1];
+              data.u[c] = op[0]->value.u[c0] | op[1]->value.u[c1];
               break;
           case GLSL_TYPE_INT:
-              data.i[c] = op[0]->value.i[c0] ^ op[1]->value.i[c1];
+              data.i[c] = op[0]->value.i[c0] | op[1]->value.i[c1];
               break;
           default:
               assert(0);
@@ -1604,49 +1561,49 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
       }
       break;
 
-   case ir_unop_bitfield_reverse:
-      for (unsigned c = 0; c < op[0]->type->components(); c++) {
-         switch (this->type->base_type) {
-         case GLSL_TYPE_UINT:
-            data.u[c] = bitfield_reverse(op[0]->value.u[c]);
-            break;
-         case GLSL_TYPE_INT:
-            data.i[c] = bitfield_reverse(op[0]->value.i[c]);
-            break;
-         default:
-            assert(0);
-         }
-      }
+   case ir_binop_logic_and:
+      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
+      for (unsigned c = 0; c < op[0]->type->components(); c++)
+         data.b[c] = op[0]->value.b[c] && op[1]->value.b[c];
       break;
 
-   case ir_unop_bit_count:
-      for (unsigned c = 0; c < components; c++)
-         data.i[c] = _mesa_bitcount(op[0]->value.u[c]);
+   case ir_binop_logic_xor:
+      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
+      for (unsigned c = 0; c < op[0]->type->components(); c++)
+         data.b[c] = op[0]->value.b[c] ^ op[1]->value.b[c];
       break;
 
-   case ir_unop_find_msb:
-      for (unsigned c = 0; c < components; c++) {
-         switch (op[0]->type->base_type) {
-         case GLSL_TYPE_UINT:
-            data.i[c] = find_msb_uint(op[0]->value.u[c]);
-            break;
-         case GLSL_TYPE_INT:
-            data.i[c] = find_msb_int(op[0]->value.i[c]);
-            break;
-         default:
-            assert(0);
-         }
-      }
+   case ir_binop_logic_or:
+      assert(op[0]->type->base_type == GLSL_TYPE_BOOL);
+      for (unsigned c = 0; c < op[0]->type->components(); c++)
+         data.b[c] = op[0]->value.b[c] || op[1]->value.b[c];
       break;
 
-   case ir_unop_find_lsb:
-      for (unsigned c = 0; c < components; c++) {
+   case ir_binop_dot:
+      if (op[0]->type->base_type == GLSL_TYPE_DOUBLE)
+         data.d[0] = dot_d(op[0], op[1]);
+      else
+         data.f[0] = dot_f(op[0], op[1]);
+      break;
+
+   case ir_binop_min:
+      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
+      for (unsigned c = 0, c0 = 0, c1 = 0;
+           c < components;
+           c0 += c0_inc, c1 += c1_inc, c++) {
+
          switch (op[0]->type->base_type) {
          case GLSL_TYPE_UINT:
-            data.i[c] = find_msb_uint(op[0]->value.u[c] & -op[0]->value.u[c]);
+            data.u[c] = MIN2(op[0]->value.u[c0], op[1]->value.u[c1]);
             break;
          case GLSL_TYPE_INT:
-            data.i[c] = find_msb_uint(op[0]->value.i[c] & -op[0]->value.i[c]);
+            data.i[c] = MIN2(op[0]->value.i[c0], op[1]->value.i[c1]);
+            break;
+         case GLSL_TYPE_FLOAT:
+            data.f[c] = MIN2(op[0]->value.f[c0], op[1]->value.f[c1]);
+            break;
+         case GLSL_TYPE_DOUBLE:
+            data.d[c] = MIN2(op[0]->value.d[c0], op[1]->value.d[c1]);
             break;
          default:
             assert(0);
@@ -1654,27 +1611,24 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
       }
       break;
 
-   case ir_unop_saturate:
-      for (unsigned c = 0; c < components; c++)
-         data.f[c] = CLAMP(op[0]->value.f[c], 0.0f, 1.0f);
-      break;
-   case ir_unop_pack_double_2x32:
-      /* XXX needs to be checked on big-endian */
-      memcpy(&data.d[0], &op[0]->value.u[0], sizeof(double));
-      break;
-   case ir_unop_unpack_double_2x32:
-      /* XXX needs to be checked on big-endian */
-      memcpy(&data.u[0], &op[0]->value.d[0], sizeof(double));
-      break;
+   case ir_binop_max:
+      assert(op[0]->type == op[1]->type || op0_scalar || op1_scalar);
+      for (unsigned c = 0, c0 = 0, c1 = 0;
+           c < components;
+           c0 += c0_inc, c1 += c1_inc, c++) {
 
-   case ir_triop_bitfield_extract:
-      for (unsigned c = 0; c < components; c++) {
-         switch (this->type->base_type) {
+         switch (op[0]->type->base_type) {
          case GLSL_TYPE_UINT:
-            data.u[c] = bitfield_extract_uint(op[0]->value.u[c], op[1]->value.i[c], op[2]->value.i[c]);
+            data.u[c] = MAX2(op[0]->value.u[c0], op[1]->value.u[c1]);
             break;
          case GLSL_TYPE_INT:
-            data.i[c] = bitfield_extract_int(op[0]->value.i[c], op[1]->value.i[c], op[2]->value.i[c]);
+            data.i[c] = MAX2(op[0]->value.i[c0], op[1]->value.i[c1]);
+            break;
+         case GLSL_TYPE_FLOAT:
+            data.f[c] = MAX2(op[0]->value.f[c0], op[1]->value.f[c1]);
+            break;
+         case GLSL_TYPE_DOUBLE:
+            data.d[c] = MAX2(op[0]->value.d[c0], op[1]->value.d[c1]);
             break;
          default:
             assert(0);
@@ -1682,6 +1636,12 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
       }
       break;
 
+   case ir_binop_pow:
+      assert(op[0]->type->base_type == GLSL_TYPE_FLOAT);
+      for (unsigned c = 0; c < op[0]->type->components(); c++)
+         data.f[c] = powf(op[0]->value.f[c], op[1]->value.f[c]);
+      break;
+
    case ir_binop_ldexp:
       for (unsigned c = 0; c < op[0]->type->components(); c++) {
          switch (this->type->base_type) {
@@ -1697,6 +1657,32 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
       }
       break;
 
+   case ir_binop_vector_extract: {
+      const int c = CLAMP(op[1]->value.i[0], 0,
+                          (int) op[0]->type->vector_elements - 1);
+
+      switch (op[0]->type->base_type) {
+      case GLSL_TYPE_UINT:
+         data.u[0] = op[0]->value.u[c];
+         break;
+      case GLSL_TYPE_INT:
+         data.i[0] = op[0]->value.i[c];
+         break;
+      case GLSL_TYPE_FLOAT:
+         data.f[0] = op[0]->value.f[c];
+         break;
+      case GLSL_TYPE_DOUBLE:
+         data.d[0] = op[0]->value.d[c];
+         break;
+      case GLSL_TYPE_BOOL:
+         data.b[0] = op[0]->value.b[c];
+         break;
+      default:
+         assert(0);
+      }
+      break;
+   }
+
    case ir_triop_fma:
       assert(op[0]->type->base_type == GLSL_TYPE_FLOAT ||
              op[0]->type->base_type == GLSL_TYPE_DOUBLE);
@@ -1746,6 +1732,21 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
       }
       break;
 
+   case ir_triop_bitfield_extract:
+      for (unsigned c = 0; c < components; c++) {
+         switch (this->type->base_type) {
+         case GLSL_TYPE_UINT:
+            data.u[c] = bitfield_extract_uint(op[0]->value.u[c], op[1]->value.i[c], op[2]->value.i[c]);
+            break;
+         case GLSL_TYPE_INT:
+            data.i[c] = bitfield_extract_int(op[0]->value.i[c], op[1]->value.i[c], op[2]->value.i[c]);
+            break;
+         default:
+            assert(0);
+         }
+      }
+      break;
+
    case ir_triop_vector_insert: {
       const unsigned idx = op[2]->value.u[0];