From: Elie Tournier <tournier.e...@gmail.com>

v2: use mix

Signed-off-by: Elie Tournier <elie.tourn...@collabora.com>
---
 src/compiler/glsl/builtin_float64.h     | 179 ++++++++++++++++++++++++++++++++
 src/compiler/glsl/builtin_functions.cpp |   4 +
 src/compiler/glsl/builtin_functions.h   |   3 +
 src/compiler/glsl/float64.glsl          |  41 ++++++++
 src/compiler/glsl/glcpp/glcpp-parse.y   |   1 +
 5 files changed, 228 insertions(+)

diff --git a/src/compiler/glsl/builtin_float64.h 
b/src/compiler/glsl/builtin_float64.h
index c200447..8ce2baa 100644
--- a/src/compiler/glsl/builtin_float64.h
+++ b/src/compiler/glsl/builtin_float64.h
@@ -5354,3 +5354,182 @@ uint_to_fp64(void *mem_ctx, builtin_available_predicate 
avail)
    sig->replace_parameters(&sig_parameters);
    return sig;
 }
+ir_function_signature *
+fp64_to_int(void *mem_ctx, builtin_available_predicate avail)
+{
+   ir_function_signature *const sig =
+      new(mem_ctx) ir_function_signature(glsl_type::int_type, avail);
+   ir_factory body(&sig->body, mem_ctx);
+   sig->is_defined = true;
+
+   exec_list sig_parameters;
+
+   ir_variable *const r088E = new(mem_ctx) ir_variable(glsl_type::uvec2_type, 
"a", ir_var_function_in);
+   sig_parameters.push_tail(r088E);
+   ir_variable *const r088F = body.make_temp(glsl_type::bool_type, 
"execute_flag");
+   body.emit(assign(r088F, body.constant(true), 0x01));
+
+   ir_variable *const r0890 = body.make_temp(glsl_type::int_type, 
"return_value");
+   ir_variable *const r0891 = new(mem_ctx) ir_variable(glsl_type::uint_type, 
"absZ", ir_var_auto);
+   body.emit(r0891);
+   ir_variable *const r0892 = new(mem_ctx) ir_variable(glsl_type::uint_type, 
"aSign", ir_var_auto);
+   body.emit(r0892);
+   ir_variable *const r0893 = new(mem_ctx) ir_variable(glsl_type::uint_type, 
"aFracHi", ir_var_auto);
+   body.emit(r0893);
+   ir_variable *const r0894 = body.make_temp(glsl_type::uint_type, 
"extractFloat64FracHi_retval");
+   body.emit(assign(r0894, bit_and(swizzle_y(r088E), body.constant(1048575u)), 
0x01));
+
+   body.emit(assign(r0893, r0894, 0x01));
+
+   ir_variable *const r0895 = body.make_temp(glsl_type::int_type, 
"extractFloat64Exp_retval");
+   ir_expression *const r0896 = rshift(swizzle_y(r088E), 
body.constant(int(20)));
+   ir_expression *const r0897 = bit_and(r0896, body.constant(2047u));
+   body.emit(assign(r0895, expr(ir_unop_u2i, r0897), 0x01));
+
+   body.emit(assign(r0892, rshift(swizzle_y(r088E), body.constant(int(31))), 
0x01));
+
+   body.emit(assign(r0891, body.constant(0u), 0x01));
+
+   ir_variable *const r0898 = body.make_temp(glsl_type::int_type, 
"assignment_tmp");
+   body.emit(assign(r0898, add(r0895, body.constant(int(-1043))), 0x01));
+
+   /* IF CONDITION */
+   ir_expression *const r089A = gequal(r0898, body.constant(int(0)));
+   ir_if *f0899 = new(mem_ctx) ir_if(operand(r089A).val);
+   exec_list *const f0899_parent_instructions = body.instructions;
+
+      /* THEN INSTRUCTIONS */
+      body.instructions = &f0899->then_instructions;
+
+      /* IF CONDITION */
+      ir_expression *const r089C = less(body.constant(int(1054)), r0895);
+      ir_if *f089B = new(mem_ctx) ir_if(operand(r089C).val);
+      exec_list *const f089B_parent_instructions = body.instructions;
+
+         /* THEN INSTRUCTIONS */
+         body.instructions = &f089B->then_instructions;
+
+         /* IF CONDITION */
+         ir_expression *const r089E = equal(r0895, body.constant(int(2047)));
+         ir_expression *const r089F = bit_or(r0894, swizzle_x(r088E));
+         ir_expression *const r08A0 = expr(ir_unop_u2i, r089F);
+         ir_expression *const r08A1 = expr(ir_unop_i2b, r08A0);
+         ir_expression *const r08A2 = logic_and(r089E, r08A1);
+         ir_if *f089D = new(mem_ctx) ir_if(operand(r08A2).val);
+         exec_list *const f089D_parent_instructions = body.instructions;
+
+            /* THEN INSTRUCTIONS */
+            body.instructions = &f089D->then_instructions;
+
+            body.emit(assign(r0892, body.constant(0u), 0x01));
+
+
+         body.instructions = f089D_parent_instructions;
+         body.emit(f089D);
+
+         /* END IF */
+
+         ir_expression *const r08A3 = expr(ir_unop_u2i, r0892);
+         ir_expression *const r08A4 = expr(ir_unop_i2b, r08A3);
+         body.emit(assign(r0890, expr(ir_triop_csel, r08A4, 
body.constant(int(-2147483648)), body.constant(int(2147483647))), 0x01));
+
+         body.emit(assign(r088F, body.constant(false), 0x01));
+
+
+         /* ELSE INSTRUCTIONS */
+         body.instructions = &f089B->else_instructions;
+
+         ir_variable *const r08A5 = body.make_temp(glsl_type::uint_type, "a0");
+         body.emit(assign(r08A5, bit_or(r0894, body.constant(1048576u)), 
0x01));
+
+         ir_expression *const r08A6 = equal(r0898, body.constant(int(0)));
+         ir_expression *const r08A7 = lshift(r08A5, r0898);
+         ir_expression *const r08A8 = neg(r0898);
+         ir_expression *const r08A9 = bit_and(r08A8, body.constant(int(31)));
+         ir_expression *const r08AA = rshift(swizzle_x(r088E), r08A9);
+         ir_expression *const r08AB = bit_or(r08A7, r08AA);
+         body.emit(assign(r0891, expr(ir_triop_csel, r08A6, r08A5, r08AB), 
0x01));
+
+
+      body.instructions = f089B_parent_instructions;
+      body.emit(f089B);
+
+      /* END IF */
+
+
+      /* ELSE INSTRUCTIONS */
+      body.instructions = &f0899->else_instructions;
+
+      /* IF CONDITION */
+      ir_expression *const r08AD = less(r0895, body.constant(int(1023)));
+      ir_if *f08AC = new(mem_ctx) ir_if(operand(r08AD).val);
+      exec_list *const f08AC_parent_instructions = body.instructions;
+
+         /* THEN INSTRUCTIONS */
+         body.instructions = &f08AC->then_instructions;
+
+         body.emit(assign(r0890, body.constant(int(0)), 0x01));
+
+         body.emit(assign(r088F, body.constant(false), 0x01));
+
+
+         /* ELSE INSTRUCTIONS */
+         body.instructions = &f08AC->else_instructions;
+
+         body.emit(assign(r0893, bit_or(r0894, body.constant(1048576u)), 
0x01));
+
+         ir_expression *const r08AE = neg(r0898);
+         body.emit(assign(r0891, rshift(r0893, r08AE), 0x01));
+
+
+      body.instructions = f08AC_parent_instructions;
+      body.emit(f08AC);
+
+      /* END IF */
+
+
+   body.instructions = f0899_parent_instructions;
+   body.emit(f0899);
+
+   /* END IF */
+
+   /* IF CONDITION */
+   ir_if *f08AF = new(mem_ctx) ir_if(operand(r088F).val);
+   exec_list *const f08AF_parent_instructions = body.instructions;
+
+      /* THEN INSTRUCTIONS */
+      body.instructions = &f08AF->then_instructions;
+
+      ir_variable *const r08B0 = body.make_temp(glsl_type::int_type, 
"mix_retval");
+      ir_expression *const r08B1 = nequal(r0892, body.constant(0u));
+      ir_expression *const r08B2 = expr(ir_unop_u2i, r0891);
+      ir_expression *const r08B3 = neg(r08B2);
+      ir_expression *const r08B4 = expr(ir_unop_u2i, r0891);
+      body.emit(assign(r08B0, expr(ir_triop_csel, r08B1, r08B3, r08B4), 0x01));
+
+      ir_expression *const r08B5 = less(r08B0, body.constant(int(0)));
+      ir_expression *const r08B6 = expr(ir_unop_b2i, r08B5);
+      ir_expression *const r08B7 = expr(ir_unop_i2u, r08B6);
+      ir_expression *const r08B8 = bit_xor(r0892, r08B7);
+      ir_expression *const r08B9 = expr(ir_unop_u2i, r08B8);
+      ir_expression *const r08BA = expr(ir_unop_i2b, r08B9);
+      ir_expression *const r08BB = expr(ir_unop_i2b, r08B0);
+      ir_expression *const r08BC = logic_and(r08BA, r08BB);
+      ir_expression *const r08BD = expr(ir_unop_u2i, r0892);
+      ir_expression *const r08BE = expr(ir_unop_i2b, r08BD);
+      ir_expression *const r08BF = expr(ir_triop_csel, r08BE, 
body.constant(int(-2147483648)), body.constant(int(2147483647)));
+      body.emit(assign(r0890, expr(ir_triop_csel, r08BC, r08BF, r08B0), 0x01));
+
+      body.emit(assign(r088F, body.constant(false), 0x01));
+
+
+   body.instructions = f08AF_parent_instructions;
+   body.emit(f08AF);
+
+   /* END IF */
+
+   body.emit(ret(r0890));
+
+   sig->replace_parameters(&sig_parameters);
+   return sig;
+}
diff --git a/src/compiler/glsl/builtin_functions.cpp 
b/src/compiler/glsl/builtin_functions.cpp
index 20051b1..96c3ff2 100644
--- a/src/compiler/glsl/builtin_functions.cpp
+++ b/src/compiler/glsl/builtin_functions.cpp
@@ -3378,6 +3378,10 @@ builtin_builder::create_builtins()
                 generate_ir::uint_to_fp64(mem_ctx, 
integer_functions_supported),
                 NULL);
 
+   add_function("__builtin_fp64_to_int",
+                generate_ir::fp64_to_int(mem_ctx, integer_functions_supported),
+                NULL);
+
 #undef F
 #undef FI
 #undef FIUD_VEC
diff --git a/src/compiler/glsl/builtin_functions.h 
b/src/compiler/glsl/builtin_functions.h
index a9674dc..8a7c914 100644
--- a/src/compiler/glsl/builtin_functions.h
+++ b/src/compiler/glsl/builtin_functions.h
@@ -94,6 +94,9 @@ fp64_to_uint(void *mem_ctx, builtin_available_predicate 
avail);
 ir_function_signature *
 uint_to_fp64(void *mem_ctx, builtin_available_predicate avail);
 
+ir_function_signature *
+fp64_to_int(void *mem_ctx, builtin_available_predicate avail);
+
 }
 
 #endif /* BULITIN_FUNCTIONS_H */
diff --git a/src/compiler/glsl/float64.glsl b/src/compiler/glsl/float64.glsl
index befaf29..557d773 100644
--- a/src/compiler/glsl/float64.glsl
+++ b/src/compiler/glsl/float64.glsl
@@ -812,3 +812,44 @@ uint_to_fp64(uint a)
 
    return packFloat64(0u, 0x432 - shiftDist, aHigh, aLow);
 }
+
+/* Returns the result of converting the double-precision floating-point value
+ * `a' to the 32-bit two's complement integer format.  The conversion is
+ * performed according to the IEEE Standard for Floating-Point Arithmetic---
+ * which means in particular that the conversion is rounded according to the
+ * current rounding mode.  If `a' is a NaN, the largest positive integer is
+ * returned.  Otherwise, if the conversion overflows, the largest integer with
+ * the same sign as `a' is returned.
+ */
+int
+fp64_to_int(uvec2 a)
+{
+   uint aFracLo = extractFloat64FracLo(a);
+   uint aFracHi = extractFloat64FracHi(a);
+   int aExp = extractFloat64Exp(a);
+   uint aSign = extractFloat64Sign(a);
+
+   uint absZ = 0u;
+   uint aFracExtra = 0u;
+   int shiftCount = aExp - 0x413;
+
+   if (0 <= shiftCount) {
+      if (0x41E < aExp) {
+         if ((aExp == 0x7FF) && bool(aFracHi | aFracLo))
+            aSign = 0u;
+         return mix(0x7FFFFFFF, 0x80000000, bool(aSign));
+      }
+      shortShift64Left(aFracHi | 0x00100000u, aFracLo, shiftCount, absZ, 
aFracExtra);
+   } else {
+      if (aExp < 0x3FF)
+         return 0;
+
+      aFracHi |= 0x00100000u;
+      aFracExtra = ( aFracHi << (shiftCount & 31)) | aFracLo;
+      absZ = aFracHi >> (- shiftCount);
+   }
+
+   int z = mix(int(absZ), -int(absZ), (aSign != 0u));
+   int nan = mix(0x7FFFFFFF, 0x80000000, bool(aSign));
+   return mix(z, nan, bool(aSign ^ uint(z < 0)) && bool(z));
+}
diff --git a/src/compiler/glsl/glcpp/glcpp-parse.y 
b/src/compiler/glsl/glcpp/glcpp-parse.y
index 826ed01..3e3b6b7 100644
--- a/src/compiler/glsl/glcpp/glcpp-parse.y
+++ b/src/compiler/glsl/glcpp/glcpp-parse.y
@@ -2377,6 +2377,7 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t 
*parser, intmax_t versio
          add_builtin_define(parser, "__have_builtin_builtin_fmul64", 1);
          add_builtin_define(parser, "__have_builtin_builtin_fp64_to_uint", 1);
          add_builtin_define(parser, "__have_builtin_builtin_uint_to_fp64", 1);
+         add_builtin_define(parser, "__have_builtin_builtin_fp64_to_int", 1);
       }
    }
 
-- 
2.9.5

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to