glsl/ast/ir: Add 64-bit integer constant support
[mesa.git] / src / compiler / glsl / ir.cpp
index 8e4b382ebd3c65bbfcc1ff3ef6744dd997a6e901..ad88ada13f129f7ae945212a7c57eac05465ad13 100644 (file)
@@ -613,6 +613,32 @@ ir_constant::ir_constant(int integer, unsigned vector_elements)
    }
 }
 
+ir_constant::ir_constant(uint64_t u64, unsigned vector_elements)
+   : ir_rvalue(ir_type_constant)
+{
+   assert(vector_elements <= 4);
+   this->type = glsl_type::get_instance(GLSL_TYPE_UINT64, vector_elements, 1);
+   for (unsigned i = 0; i < vector_elements; i++) {
+      this->value.u64[i] = u64;
+   }
+   for (unsigned i = vector_elements; i < 16; i++) {
+      this->value.u64[i] = 0;
+   }
+}
+
+ir_constant::ir_constant(int64_t int64, unsigned vector_elements)
+   : ir_rvalue(ir_type_constant)
+{
+   assert(vector_elements <= 4);
+   this->type = glsl_type::get_instance(GLSL_TYPE_INT64, vector_elements, 1);
+   for (unsigned i = 0; i < vector_elements; i++) {
+      this->value.i64[i] = int64;
+   }
+   for (unsigned i = vector_elements; i < 16; i++) {
+      this->value.i64[i] = 0;
+   }
+}
+
 ir_constant::ir_constant(bool b, unsigned vector_elements)
    : ir_rvalue(ir_type_constant)
 {
@@ -716,6 +742,11 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
            for (unsigned i = 0; i < type->components(); i++)
               this->value.d[i] = value->value.d[0];
            break;
+        case GLSL_TYPE_UINT64:
+        case GLSL_TYPE_INT64:
+           for (unsigned i = 0; i < type->components(); i++)
+              this->value.u64[i] = value->value.u64[0];
+           break;
         case GLSL_TYPE_BOOL:
            for (unsigned i = 0; i < type->components(); i++)
               this->value.b[i] = value->value.b[0];
@@ -778,6 +809,12 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
         case GLSL_TYPE_DOUBLE:
            this->value.d[i] = value->get_double_component(j);
            break;
+         case GLSL_TYPE_UINT64:
+           this->value.u64[i] = value->get_uint64_component(j);
+           break;
+        case GLSL_TYPE_INT64:
+           this->value.i64[i] = value->get_int64_component(j);
+           break;
         default:
            /* FINISHME: What to do?  Exceptions are not the answer.
             */
@@ -831,6 +868,8 @@ ir_constant::get_bool_component(unsigned i) const
    case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0;
    case GLSL_TYPE_BOOL:  return this->value.b[i];
    case GLSL_TYPE_DOUBLE: return this->value.d[i] != 0.0;
+   case GLSL_TYPE_UINT64: return this->value.u64[i] != 0;
+   case GLSL_TYPE_INT64:  return this->value.i64[i] != 0;
    default:              assert(!"Should not get here."); break;
    }
 
@@ -849,6 +888,8 @@ ir_constant::get_float_component(unsigned i) const
    case GLSL_TYPE_FLOAT: return this->value.f[i];
    case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1.0f : 0.0f;
    case GLSL_TYPE_DOUBLE: return (float) this->value.d[i];
+   case GLSL_TYPE_UINT64: return (float) this->value.u64[i];
+   case GLSL_TYPE_INT64:  return (float) this->value.i64[i];
    default:              assert(!"Should not get here."); break;
    }
 
@@ -867,6 +908,8 @@ ir_constant::get_double_component(unsigned i) const
    case GLSL_TYPE_FLOAT: return (double) this->value.f[i];
    case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1.0 : 0.0;
    case GLSL_TYPE_DOUBLE: return this->value.d[i];
+   case GLSL_TYPE_UINT64: return (double) this->value.u64[i];
+   case GLSL_TYPE_INT64:  return (double) this->value.i64[i];
    default:              assert(!"Should not get here."); break;
    }
 
@@ -885,6 +928,8 @@ ir_constant::get_int_component(unsigned i) const
    case GLSL_TYPE_FLOAT: return (int) this->value.f[i];
    case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
    case GLSL_TYPE_DOUBLE: return (int) this->value.d[i];
+   case GLSL_TYPE_UINT64: return (int) this->value.u64[i];
+   case GLSL_TYPE_INT64:  return (int) this->value.i64[i];
    default:              assert(!"Should not get here."); break;
    }
 
@@ -903,6 +948,48 @@ ir_constant::get_uint_component(unsigned i) const
    case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i];
    case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
    case GLSL_TYPE_DOUBLE: return (unsigned) this->value.d[i];
+   case GLSL_TYPE_UINT64: return (unsigned) this->value.u64[i];
+   case GLSL_TYPE_INT64:  return (unsigned) this->value.i64[i];
+   default:              assert(!"Should not get here."); break;
+   }
+
+   /* Must return something to make the compiler happy.  This is clearly an
+    * error case.
+    */
+   return 0;
+}
+
+int64_t
+ir_constant::get_int64_component(unsigned i) const
+{
+   switch (this->type->base_type) {
+   case GLSL_TYPE_UINT:  return this->value.u[i];
+   case GLSL_TYPE_INT:   return this->value.i[i];
+   case GLSL_TYPE_FLOAT: return (int64_t) this->value.f[i];
+   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
+   case GLSL_TYPE_DOUBLE: return (int64_t) this->value.d[i];
+   case GLSL_TYPE_UINT64: return (int64_t) this->value.u64[i];
+   case GLSL_TYPE_INT64:  return this->value.i64[i];
+   default:              assert(!"Should not get here."); break;
+   }
+
+   /* Must return something to make the compiler happy.  This is clearly an
+    * error case.
+    */
+   return 0;
+}
+
+uint64_t
+ir_constant::get_uint64_component(unsigned i) const
+{
+   switch (this->type->base_type) {
+   case GLSL_TYPE_UINT:  return this->value.u[i];
+   case GLSL_TYPE_INT:   return this->value.i[i];
+   case GLSL_TYPE_FLOAT: return (uint64_t) this->value.f[i];
+   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
+   case GLSL_TYPE_DOUBLE: return (uint64_t) this->value.d[i];
+   case GLSL_TYPE_UINT64: return this->value.u64[i];
+   case GLSL_TYPE_INT64:  return (uint64_t) this->value.i64[i];
    default:              assert(!"Should not get here."); break;
    }
 
@@ -968,6 +1055,8 @@ ir_constant::copy_offset(ir_constant *src, int offset)
    case GLSL_TYPE_INT:
    case GLSL_TYPE_FLOAT:
    case GLSL_TYPE_DOUBLE:
+   case GLSL_TYPE_UINT64:
+   case GLSL_TYPE_INT64:
    case GLSL_TYPE_BOOL: {
       unsigned int size = src->type->components();
       assert (size <= this->type->components() - offset);
@@ -988,6 +1077,12 @@ ir_constant::copy_offset(ir_constant *src, int offset)
         case GLSL_TYPE_DOUBLE:
            value.d[i+offset] = src->get_double_component(i);
            break;
+         case GLSL_TYPE_UINT64:
+           value.u64[i+offset] = src->get_uint64_component(i);
+           break;
+        case GLSL_TYPE_INT64:
+           value.i64[i+offset] = src->get_int64_component(i);
+           break;
         default: // Shut up the compiler
            break;
         }
@@ -1047,6 +1142,12 @@ ir_constant::copy_masked_offset(ir_constant *src, int offset, unsigned int mask)
         case GLSL_TYPE_DOUBLE:
            value.d[i+offset] = src->get_double_component(id++);
            break;
+         case GLSL_TYPE_UINT64:
+           value.u64[i+offset] = src->get_uint64_component(id++);
+           break;
+        case GLSL_TYPE_INT64:
+           value.i64[i+offset] = src->get_int64_component(id++);
+           break;
         default:
            assert(!"Should not get here.");
            return;
@@ -1111,6 +1212,14 @@ ir_constant::has_value(const ir_constant *c) const
         if (this->value.d[i] != c->value.d[i])
            return false;
         break;
+      case GLSL_TYPE_UINT64:
+        if (this->value.u64[i] != c->value.u64[i])
+           return false;
+        break;
+      case GLSL_TYPE_INT64:
+        if (this->value.i64[i] != c->value.i64[i])
+           return false;
+        break;
       default:
         assert(!"Should not get here.");
         return false;
@@ -1152,6 +1261,14 @@ ir_constant::is_value(float f, int i) const
         if (this->value.d[c] != double(f))
            return false;
         break;
+      case GLSL_TYPE_UINT64:
+        if (this->value.u64[c] != uint64_t(i))
+           return false;
+        break;
+      case GLSL_TYPE_INT64:
+        if (this->value.i64[c] != i)
+           return false;
+        break;
       default:
         /* The only other base types are structures, arrays, and samplers.
          * Samplers cannot be constants, and the others should have been