[Mesa-dev] [RFC 03/11] glsl: Add "built-in" functions to do eq(fp64, fp64)
Elie Tournier
tournier.elie at gmail.com
Fri Mar 3 16:22:59 UTC 2017
Signed-off-by: Elie Tournier <elie.tournier at collabora.com>
---
src/compiler/glsl/builtin_float64.h | 119 ++++++++++++++++++++++++++++++++
src/compiler/glsl/builtin_functions.cpp | 4 ++
src/compiler/glsl/builtin_functions.h | 3 +
src/compiler/glsl/float64.glsl | 41 +++++++++++
4 files changed, 167 insertions(+)
diff --git a/src/compiler/glsl/builtin_float64.h b/src/compiler/glsl/builtin_float64.h
index 6df91e10f5..e614374d75 100644
--- a/src/compiler/glsl/builtin_float64.h
+++ b/src/compiler/glsl/builtin_float64.h
@@ -36,3 +36,122 @@ fneg64(void *mem_ctx, builtin_available_predicate avail)
sig->replace_parameters(&sig_parameters);
return sig;
}
+ir_function_signature *
+extractFloat64Frac(void *mem_ctx, builtin_available_predicate avail)
+{
+ ir_function_signature *const sig =
+ new(mem_ctx) ir_function_signature(glsl_type::uvec2_type, avail);
+ ir_factory body(&sig->body, mem_ctx);
+ sig->is_defined = true;
+
+ exec_list sig_parameters;
+
+ ir_variable *const r000D = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "a", ir_var_function_in);
+ sig_parameters.push_tail(r000D);
+ ir_variable *const r000E = body.make_temp(glsl_type::uvec2_type, "vec_ctor");
+ body.emit(assign(r000E, bit_and(swizzle_x(r000D), body.constant(1048575u)), 0x01));
+
+ body.emit(assign(r000E, swizzle_y(r000D), 0x02));
+
+ body.emit(ret(r000E));
+
+ sig->replace_parameters(&sig_parameters);
+ return sig;
+}
+ir_function_signature *
+extractFloat64Exp(void *mem_ctx, builtin_available_predicate avail)
+{
+ ir_function_signature *const sig =
+ new(mem_ctx) ir_function_signature(glsl_type::uint_type, avail);
+ ir_factory body(&sig->body, mem_ctx);
+ sig->is_defined = true;
+
+ exec_list sig_parameters;
+
+ ir_variable *const r000F = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "a", ir_var_function_in);
+ sig_parameters.push_tail(r000F);
+ ir_expression *const r0010 = rshift(swizzle_x(r000F), body.constant(int(20)));
+ ir_expression *const r0011 = bit_and(r0010, body.constant(2047u));
+ body.emit(ret(r0011));
+
+ sig->replace_parameters(&sig_parameters);
+ return sig;
+}
+ir_function_signature *
+feq64(void *mem_ctx, builtin_available_predicate avail)
+{
+ ir_function_signature *const sig =
+ new(mem_ctx) ir_function_signature(glsl_type::bool_type, avail);
+ ir_factory body(&sig->body, mem_ctx);
+ sig->is_defined = true;
+
+ exec_list sig_parameters;
+
+ ir_variable *const r0012 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "a", ir_var_function_in);
+ sig_parameters.push_tail(r0012);
+ ir_variable *const r0013 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "b", ir_var_function_in);
+ sig_parameters.push_tail(r0013);
+ ir_variable *const r0014 = body.make_temp(glsl_type::bool_type, "return_value");
+ ir_variable *const r0015 = new(mem_ctx) ir_variable(glsl_type::bool_type, "isbNaN", ir_var_auto);
+ body.emit(r0015);
+ ir_variable *const r0016 = new(mem_ctx) ir_variable(glsl_type::bool_type, "isaNaN", ir_var_auto);
+ body.emit(r0016);
+ ir_variable *const r0017 = body.make_temp(glsl_type::uvec2_type, "vec_ctor");
+ body.emit(assign(r0017, bit_and(swizzle_x(r0012), body.constant(1048575u)), 0x01));
+
+ body.emit(assign(r0017, swizzle_y(r0012), 0x02));
+
+ ir_variable *const r0018 = body.make_temp(glsl_type::uvec2_type, "vec_ctor");
+ body.emit(assign(r0018, bit_and(swizzle_x(r0013), body.constant(1048575u)), 0x01));
+
+ body.emit(assign(r0018, swizzle_y(r0013), 0x02));
+
+ ir_expression *const r0019 = rshift(swizzle_x(r0012), body.constant(int(20)));
+ ir_expression *const r001A = bit_and(r0019, body.constant(2047u));
+ ir_expression *const r001B = equal(r001A, body.constant(2047u));
+ ir_expression *const r001C = bit_or(swizzle_x(r0017), swizzle_y(r0012));
+ ir_expression *const r001D = nequal(r001C, body.constant(0u));
+ body.emit(assign(r0016, logic_and(r001B, r001D), 0x01));
+
+ ir_expression *const r001E = rshift(swizzle_x(r0013), body.constant(int(20)));
+ ir_expression *const r001F = bit_and(r001E, body.constant(2047u));
+ ir_expression *const r0020 = equal(r001F, body.constant(2047u));
+ ir_expression *const r0021 = bit_or(swizzle_x(r0018), swizzle_y(r0013));
+ ir_expression *const r0022 = nequal(r0021, body.constant(0u));
+ body.emit(assign(r0015, logic_and(r0020, r0022), 0x01));
+
+ /* IF CONDITION */
+ ir_expression *const r0024 = logic_or(r0016, r0015);
+ ir_if *f0023 = new(mem_ctx) ir_if(operand(r0024).val);
+ exec_list *const f0023_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f0023->then_instructions;
+
+ body.emit(assign(r0014, body.constant(false), 0x01));
+
+
+ /* ELSE INSTRUCTIONS */
+ body.instructions = &f0023->else_instructions;
+
+ ir_expression *const r0025 = equal(swizzle_y(r0012), swizzle_y(r0013));
+ ir_expression *const r0026 = equal(swizzle_x(r0012), swizzle_x(r0013));
+ ir_expression *const r0027 = equal(swizzle_y(r0012), body.constant(0u));
+ ir_expression *const r0028 = bit_or(swizzle_x(r0012), swizzle_x(r0013));
+ ir_expression *const r0029 = lshift(r0028, body.constant(int(1)));
+ ir_expression *const r002A = equal(r0029, body.constant(0u));
+ ir_expression *const r002B = logic_and(r0027, r002A);
+ ir_expression *const r002C = logic_or(r0026, r002B);
+ body.emit(assign(r0014, logic_and(r0025, r002C), 0x01));
+
+
+ body.instructions = f0023_parent_instructions;
+ body.emit(f0023);
+
+ /* END IF */
+
+ body.emit(ret(r0014));
+
+ sig->replace_parameters(&sig_parameters);
+ return sig;
+}
diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp
index a189b84190..5e73d2469c 100644
--- a/src/compiler/glsl/builtin_functions.cpp
+++ b/src/compiler/glsl/builtin_functions.cpp
@@ -3137,6 +3137,10 @@ builtin_builder::create_builtins()
generate_ir::fneg64(mem_ctx, integer_functions_supported),
NULL);
+ add_function("__builtin_feq64",
+ generate_ir::feq64(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 37c6cc33c2..741698dc9e 100644
--- a/src/compiler/glsl/builtin_functions.h
+++ b/src/compiler/glsl/builtin_functions.h
@@ -69,6 +69,9 @@ fabs64(void *mem_ctx, builtin_available_predicate avail);
ir_function_signature *
fneg64(void *mem_ctx, builtin_available_predicate avail);
+ir_function_signature *
+feq64(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 82875e9407..dc7668c18b 100644
--- a/src/compiler/glsl/float64.glsl
+++ b/src/compiler/glsl/float64.glsl
@@ -36,3 +36,44 @@ fneg64( uvec2 a )
a.x ^= (1u<<31);
return a;
}
+
+/* Returns the fraction bits of the double-precision floating-point value `a'.*/
+uvec2
+extractFloat64Frac( uvec2 a )
+{
+ return uvec2( a.x & 0x000FFFFFu, a.y );
+}
+
+/* Returns the exponent bits of the double-precision floating-point value `a'.*/
+uint
+extractFloat64Exp( uvec2 a )
+{
+ return (a.x>>20) & 0x7FFu;
+}
+
+/* Returns true if the double-precision floating-point value `a' is equal to the
+ * corresponding value `b', and false otherwise. The comparison is performed
+ * according to the IEEE Standard for Floating-Point Arithmetic.
+ */
+bool
+feq64( uvec2 a, uvec2 b )
+{
+ uvec2 aFrac;
+ uvec2 bFrac;
+ bool isaNaN;
+ bool isbNaN;
+
+ aFrac = extractFloat64Frac( a );
+ bFrac = extractFloat64Frac( b );
+ isaNaN = ( extractFloat64Exp( a ) == 0x7FFu ) &&
+ ( ( aFrac.x | aFrac.y ) != 0u );
+ isbNaN = ( extractFloat64Exp( b ) == 0x7FFu ) &&
+ ( ( bFrac.x | bFrac.y ) != 0u );
+
+ if ( isaNaN || isbNaN ) {
+ return false;
+ }
+ return ( a.y == b.y ) &&
+ ( ( a.x == b.x ) ||
+ ( ( a.y == 0u ) && ( ( ( a.x | b.x )<<1) == 0u ) ) );
+}
--
2.11.0
More information about the mesa-dev
mailing list