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 | 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 mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev