Signed-off-by: Elie Tournier <[email protected]>
---
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
_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev