[Mesa-dev] [RFC 04/11] glsl: Add "built-in" functions to do le(fp64, fp64)
Elie Tournier
tournier.elie at gmail.com
Fri Mar 3 16:23:00 UTC 2017
Signed-off-by: Elie Tournier <elie.tournier at 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 | 52 ++++++++++
4 files changed, 238 insertions(+)
diff --git a/src/compiler/glsl/builtin_float64.h b/src/compiler/glsl/builtin_float64.h
index e614374d75..f8ceacdabf 100644
--- a/src/compiler/glsl/builtin_float64.h
+++ b/src/compiler/glsl/builtin_float64.h
@@ -155,3 +155,182 @@ feq64(void *mem_ctx, builtin_available_predicate avail)
sig->replace_parameters(&sig_parameters);
return sig;
}
+ir_function_signature *
+extractFloat64Sign(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 r002D = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "a", ir_var_function_in);
+ sig_parameters.push_tail(r002D);
+ ir_expression *const r002E = rshift(swizzle_x(r002D), body.constant(int(31)));
+ body.emit(ret(r002E));
+
+ sig->replace_parameters(&sig_parameters);
+ return sig;
+}
+ir_function_signature *
+le64(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 r002F = new(mem_ctx) ir_variable(glsl_type::uint_type, "a0", ir_var_function_in);
+ sig_parameters.push_tail(r002F);
+ ir_variable *const r0030 = new(mem_ctx) ir_variable(glsl_type::uint_type, "a1", ir_var_function_in);
+ sig_parameters.push_tail(r0030);
+ ir_variable *const r0031 = new(mem_ctx) ir_variable(glsl_type::uint_type, "b0", ir_var_function_in);
+ sig_parameters.push_tail(r0031);
+ ir_variable *const r0032 = new(mem_ctx) ir_variable(glsl_type::uint_type, "b1", ir_var_function_in);
+ sig_parameters.push_tail(r0032);
+ ir_expression *const r0033 = less(r002F, r0031);
+ ir_expression *const r0034 = equal(r002F, r0031);
+ ir_expression *const r0035 = lequal(r0030, r0032);
+ ir_expression *const r0036 = logic_and(r0034, r0035);
+ ir_expression *const r0037 = logic_or(r0033, r0036);
+ body.emit(ret(r0037));
+
+ sig->replace_parameters(&sig_parameters);
+ return sig;
+}
+ir_function_signature *
+fle64(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 r0038 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "a", ir_var_function_in);
+ sig_parameters.push_tail(r0038);
+ ir_variable *const r0039 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "b", ir_var_function_in);
+ sig_parameters.push_tail(r0039);
+ ir_variable *const r003A = body.make_temp(glsl_type::bool_type, "return_value");
+ ir_variable *const r003B = new(mem_ctx) ir_variable(glsl_type::bool_type, "isbNaN", ir_var_auto);
+ body.emit(r003B);
+ ir_variable *const r003C = new(mem_ctx) ir_variable(glsl_type::bool_type, "isaNaN", ir_var_auto);
+ body.emit(r003C);
+ ir_variable *const r003D = body.make_temp(glsl_type::uvec2_type, "vec_ctor");
+ body.emit(assign(r003D, bit_and(swizzle_x(r0038), body.constant(1048575u)), 0x01));
+
+ body.emit(assign(r003D, swizzle_y(r0038), 0x02));
+
+ ir_variable *const r003E = body.make_temp(glsl_type::uvec2_type, "vec_ctor");
+ body.emit(assign(r003E, bit_and(swizzle_x(r0039), body.constant(1048575u)), 0x01));
+
+ body.emit(assign(r003E, swizzle_y(r0039), 0x02));
+
+ ir_expression *const r003F = rshift(swizzle_x(r0038), body.constant(int(20)));
+ ir_expression *const r0040 = bit_and(r003F, body.constant(2047u));
+ ir_expression *const r0041 = equal(r0040, body.constant(2047u));
+ ir_expression *const r0042 = bit_or(swizzle_x(r003D), swizzle_y(r0038));
+ ir_expression *const r0043 = nequal(r0042, body.constant(0u));
+ body.emit(assign(r003C, logic_and(r0041, r0043), 0x01));
+
+ ir_expression *const r0044 = rshift(swizzle_x(r0039), body.constant(int(20)));
+ ir_expression *const r0045 = bit_and(r0044, body.constant(2047u));
+ ir_expression *const r0046 = equal(r0045, body.constant(2047u));
+ ir_expression *const r0047 = bit_or(swizzle_x(r003E), swizzle_y(r0039));
+ ir_expression *const r0048 = nequal(r0047, body.constant(0u));
+ body.emit(assign(r003B, logic_and(r0046, r0048), 0x01));
+
+ /* IF CONDITION */
+ ir_expression *const r004A = logic_or(r003C, r003B);
+ ir_if *f0049 = new(mem_ctx) ir_if(operand(r004A).val);
+ exec_list *const f0049_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f0049->then_instructions;
+
+ body.emit(assign(r003A, body.constant(false), 0x01));
+
+
+ /* ELSE INSTRUCTIONS */
+ body.instructions = &f0049->else_instructions;
+
+ ir_variable *const r004B = body.make_temp(glsl_type::uint_type, "extractFloat64Sign_retval");
+ body.emit(assign(r004B, rshift(swizzle_x(r0038), body.constant(int(31))), 0x01));
+
+ ir_variable *const r004C = body.make_temp(glsl_type::uint_type, "extractFloat64Sign_retval");
+ body.emit(assign(r004C, rshift(swizzle_x(r0039), body.constant(int(31))), 0x01));
+
+ /* IF CONDITION */
+ ir_expression *const r004E = nequal(r004B, r004C);
+ ir_if *f004D = new(mem_ctx) ir_if(operand(r004E).val);
+ exec_list *const f004D_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f004D->then_instructions;
+
+ ir_expression *const r004F = nequal(r004B, body.constant(0u));
+ ir_expression *const r0050 = bit_or(swizzle_x(r0038), swizzle_x(r0039));
+ ir_expression *const r0051 = lshift(r0050, body.constant(int(1)));
+ ir_expression *const r0052 = bit_or(r0051, swizzle_y(r0038));
+ ir_expression *const r0053 = bit_or(r0052, swizzle_y(r0039));
+ ir_expression *const r0054 = equal(r0053, body.constant(0u));
+ body.emit(assign(r003A, logic_or(r004F, r0054), 0x01));
+
+
+ /* ELSE INSTRUCTIONS */
+ body.instructions = &f004D->else_instructions;
+
+ ir_variable *const r0055 = body.make_temp(glsl_type::bool_type, "conditional_tmp");
+ /* IF CONDITION */
+ ir_expression *const r0057 = nequal(r004B, body.constant(0u));
+ ir_if *f0056 = new(mem_ctx) ir_if(operand(r0057).val);
+ exec_list *const f0056_parent_instructions = body.instructions;
+
+ /* THEN INSTRUCTIONS */
+ body.instructions = &f0056->then_instructions;
+
+ ir_expression *const r0058 = less(swizzle_x(r0039), swizzle_x(r0038));
+ ir_expression *const r0059 = equal(swizzle_x(r0039), swizzle_x(r0038));
+ ir_expression *const r005A = lequal(swizzle_y(r0039), swizzle_y(r0038));
+ ir_expression *const r005B = logic_and(r0059, r005A);
+ body.emit(assign(r0055, logic_or(r0058, r005B), 0x01));
+
+
+ /* ELSE INSTRUCTIONS */
+ body.instructions = &f0056->else_instructions;
+
+ ir_expression *const r005C = less(swizzle_x(r0038), swizzle_x(r0039));
+ ir_expression *const r005D = equal(swizzle_x(r0038), swizzle_x(r0039));
+ ir_expression *const r005E = lequal(swizzle_y(r0038), swizzle_y(r0039));
+ ir_expression *const r005F = logic_and(r005D, r005E);
+ body.emit(assign(r0055, logic_or(r005C, r005F), 0x01));
+
+
+ body.instructions = f0056_parent_instructions;
+ body.emit(f0056);
+
+ /* END IF */
+
+ body.emit(assign(r003A, r0055, 0x01));
+
+
+ body.instructions = f004D_parent_instructions;
+ body.emit(f004D);
+
+ /* END IF */
+
+
+ body.instructions = f0049_parent_instructions;
+ body.emit(f0049);
+
+ /* END IF */
+
+ body.emit(ret(r003A));
+
+ sig->replace_parameters(&sig_parameters);
+ return sig;
+}
diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp
index 5e73d2469c..65ccf3725f 100644
--- a/src/compiler/glsl/builtin_functions.cpp
+++ b/src/compiler/glsl/builtin_functions.cpp
@@ -3141,6 +3141,10 @@ builtin_builder::create_builtins()
generate_ir::feq64(mem_ctx, integer_functions_supported),
NULL);
+ add_function("__builtin_fle64",
+ generate_ir::fle64(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 741698dc9e..e8b1ea0d79 100644
--- a/src/compiler/glsl/builtin_functions.h
+++ b/src/compiler/glsl/builtin_functions.h
@@ -72,6 +72,9 @@ fneg64(void *mem_ctx, builtin_available_predicate avail);
ir_function_signature *
feq64(void *mem_ctx, builtin_available_predicate avail);
+ir_function_signature *
+fle64(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 dc7668c18b..db86546f49 100644
--- a/src/compiler/glsl/float64.glsl
+++ b/src/compiler/glsl/float64.glsl
@@ -77,3 +77,55 @@ feq64( uvec2 a, uvec2 b )
( ( a.x == b.x ) ||
( ( a.y == 0u ) && ( ( ( a.x | b.x )<<1) == 0u ) ) );
}
+
+/* Returns the sign bit of the double-precision floating-point value `a'.*/
+uint
+extractFloat64Sign( uvec2 a )
+{
+ return (a.x>>31);
+}
+
+/* Returns true if the 64-bit value formed by concatenating `a0' and `a1' is less
+ * than or equal to the 64-bit value formed by concatenating `b0' and `b1'.
+ * Otherwise, returns false.
+ */
+bool
+le64( uint a0, uint a1, uint b0, uint b1 )
+{
+ return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );
+}
+
+/* Returns true if the double-precision floating-point value `a' is less than or
+ * equal to the corresponding value `b', and false otherwise. The comparison is
+ * performed according to the IEEE Standard for Floating-Point Arithmetic.
+ */
+bool
+fle64( uvec2 a, uvec2 b )
+{
+ uint aSign;
+ uint bSign;
+ 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;
+ }
+
+ aSign = extractFloat64Sign( a );
+ bSign = extractFloat64Sign( b );
+ if ( aSign != bSign ) {
+ return ( aSign != 0u ) ||
+ ( ( ( ( ( a.x | b.x )<<1 ) ) | a.y | b.y ) == 0u );
+ }
+ return ( aSign != 0u ) ? le64( b.x, b.y, a.x, a.y )
+ : le64( a.x, a.y, b.x, b.y );
+}
--
2.11.0
More information about the mesa-dev
mailing list