Signed-off-by: Elie Tournier <elie.tourn...@collabora.com> --- src/compiler/glsl/builtin_float64.h | 173 ++++++++++++++++++++++++++++++++ src/compiler/glsl/builtin_functions.cpp | 4 + src/compiler/glsl/builtin_functions.h | 3 + src/compiler/glsl/float64.glsl | 50 +++++++++ src/compiler/glsl/glcpp/glcpp-parse.y | 1 + 5 files changed, 231 insertions(+)
diff --git a/src/compiler/glsl/builtin_float64.h b/src/compiler/glsl/builtin_float64.h index 9fc716871d..aa769d9672 100644 --- a/src/compiler/glsl/builtin_float64.h +++ b/src/compiler/glsl/builtin_float64.h @@ -266,3 +266,176 @@ 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 r004B = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "a", ir_var_function_in); + sig_parameters.push_tail(r004B); + ir_expression *const r004C = rshift(swizzle_y(r004B), body.constant(int(31))); + body.emit(ret(r004C)); + + 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 r004D = new(mem_ctx) ir_variable(glsl_type::uint_type, "a0", ir_var_function_in); + sig_parameters.push_tail(r004D); + ir_variable *const r004E = new(mem_ctx) ir_variable(glsl_type::uint_type, "a1", ir_var_function_in); + sig_parameters.push_tail(r004E); + ir_variable *const r004F = new(mem_ctx) ir_variable(glsl_type::uint_type, "b0", ir_var_function_in); + sig_parameters.push_tail(r004F); + ir_variable *const r0050 = new(mem_ctx) ir_variable(glsl_type::uint_type, "b1", ir_var_function_in); + sig_parameters.push_tail(r0050); + ir_expression *const r0051 = less(r004D, r004F); + ir_expression *const r0052 = equal(r004D, r004F); + ir_expression *const r0053 = lequal(r004E, r0050); + ir_expression *const r0054 = logic_and(r0052, r0053); + ir_expression *const r0055 = logic_or(r0051, r0054); + body.emit(ret(r0055)); + + 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 r0056 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "a", ir_var_function_in); + sig_parameters.push_tail(r0056); + ir_variable *const r0057 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "b", ir_var_function_in); + sig_parameters.push_tail(r0057); + ir_variable *const r0058 = body.make_temp(glsl_type::bool_type, "return_value"); + ir_variable *const r0059 = new(mem_ctx) ir_variable(glsl_type::bool_type, "isbNaN", ir_var_auto); + body.emit(r0059); + ir_variable *const r005A = new(mem_ctx) ir_variable(glsl_type::bool_type, "isaNaN", ir_var_auto); + body.emit(r005A); + ir_expression *const r005B = rshift(swizzle_y(r0056), body.constant(int(20))); + ir_expression *const r005C = bit_and(r005B, body.constant(2047u)); + ir_expression *const r005D = expr(ir_unop_u2i, r005C); + ir_expression *const r005E = equal(r005D, body.constant(int(2047))); + ir_expression *const r005F = bit_and(swizzle_y(r0056), body.constant(1048575u)); + ir_expression *const r0060 = bit_or(r005F, swizzle_x(r0056)); + ir_expression *const r0061 = nequal(r0060, body.constant(0u)); + body.emit(assign(r005A, logic_and(r005E, r0061), 0x01)); + + ir_expression *const r0062 = rshift(swizzle_y(r0057), body.constant(int(20))); + ir_expression *const r0063 = bit_and(r0062, body.constant(2047u)); + ir_expression *const r0064 = expr(ir_unop_u2i, r0063); + ir_expression *const r0065 = equal(r0064, body.constant(int(2047))); + ir_expression *const r0066 = bit_and(swizzle_y(r0057), body.constant(1048575u)); + ir_expression *const r0067 = bit_or(r0066, swizzle_x(r0057)); + ir_expression *const r0068 = nequal(r0067, body.constant(0u)); + body.emit(assign(r0059, logic_and(r0065, r0068), 0x01)); + + /* IF CONDITION */ + ir_expression *const r006A = logic_or(r005A, r0059); + ir_if *f0069 = new(mem_ctx) ir_if(operand(r006A).val); + exec_list *const f0069_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f0069->then_instructions; + + body.emit(assign(r0058, body.constant(false), 0x01)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f0069->else_instructions; + + ir_variable *const r006B = body.make_temp(glsl_type::uint_type, "extractFloat64Sign_retval"); + body.emit(assign(r006B, rshift(swizzle_y(r0056), body.constant(int(31))), 0x01)); + + ir_variable *const r006C = body.make_temp(glsl_type::uint_type, "extractFloat64Sign_retval"); + body.emit(assign(r006C, rshift(swizzle_y(r0057), body.constant(int(31))), 0x01)); + + /* IF CONDITION */ + ir_expression *const r006E = nequal(r006B, r006C); + ir_if *f006D = new(mem_ctx) ir_if(operand(r006E).val); + exec_list *const f006D_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f006D->then_instructions; + + ir_expression *const r006F = nequal(r006B, body.constant(0u)); + ir_expression *const r0070 = bit_or(swizzle_y(r0056), swizzle_y(r0057)); + ir_expression *const r0071 = lshift(r0070, body.constant(int(1))); + ir_expression *const r0072 = bit_or(r0071, swizzle_x(r0056)); + ir_expression *const r0073 = bit_or(r0072, swizzle_x(r0057)); + ir_expression *const r0074 = equal(r0073, body.constant(0u)); + body.emit(assign(r0058, logic_or(r006F, r0074), 0x01)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f006D->else_instructions; + + ir_variable *const r0075 = body.make_temp(glsl_type::bool_type, "conditional_tmp"); + /* IF CONDITION */ + ir_expression *const r0077 = nequal(r006B, body.constant(0u)); + ir_if *f0076 = new(mem_ctx) ir_if(operand(r0077).val); + exec_list *const f0076_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f0076->then_instructions; + + ir_expression *const r0078 = less(swizzle_y(r0057), swizzle_y(r0056)); + ir_expression *const r0079 = equal(swizzle_y(r0057), swizzle_y(r0056)); + ir_expression *const r007A = lequal(swizzle_x(r0057), swizzle_x(r0056)); + ir_expression *const r007B = logic_and(r0079, r007A); + body.emit(assign(r0075, logic_or(r0078, r007B), 0x01)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f0076->else_instructions; + + ir_expression *const r007C = less(swizzle_y(r0056), swizzle_y(r0057)); + ir_expression *const r007D = equal(swizzle_y(r0056), swizzle_y(r0057)); + ir_expression *const r007E = lequal(swizzle_x(r0056), swizzle_x(r0057)); + ir_expression *const r007F = logic_and(r007D, r007E); + body.emit(assign(r0075, logic_or(r007C, r007F), 0x01)); + + + body.instructions = f0076_parent_instructions; + body.emit(f0076); + + /* END IF */ + + body.emit(assign(r0058, r0075, 0x01)); + + + body.instructions = f006D_parent_instructions; + body.emit(f006D); + + /* END IF */ + + + body.instructions = f0069_parent_instructions; + body.emit(f0069); + + /* END IF */ + + body.emit(ret(r0058)); + + sig->replace_parameters(&sig_parameters); + return sig; +} diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp index 1a06876b89..99b4f4ddde 100644 --- a/src/compiler/glsl/builtin_functions.cpp +++ b/src/compiler/glsl/builtin_functions.cpp @@ -3340,6 +3340,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 8cfdf49bbf..b4106172a6 100644 --- a/src/compiler/glsl/builtin_functions.h +++ b/src/compiler/glsl/builtin_functions.h @@ -79,6 +79,9 @@ fsign64(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 b35aeb36ad..2f55ee8887 100644 --- a/src/compiler/glsl/float64.glsl +++ b/src/compiler/glsl/float64.glsl @@ -108,3 +108,53 @@ feq64(uvec2 a, uvec2 b) return (a.x == b.x) && ((a.y == b.y) || ((a.x == 0u) && (((a.y | b.y)<<1) == 0u))); } + +/* Returns the sign bit of the double-precision floating-point value `a'.*/ +uint +extractFloat64Sign(uvec2 a) +{ + return (a.y>>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; + bool isaNaN; + bool isbNaN; + + uint aFracLo = extractFloat64FracLo(a); + uint aFracHi = extractFloat64FracHi(a); + uint bFracLo = extractFloat64FracLo(b); + uint bFracHi = extractFloat64FracHi(b); + isaNaN = (extractFloat64Exp(a) == 0x7FF) && + ((aFracHi | aFracLo) != 0u); + isbNaN = (extractFloat64Exp(b) == 0x7FF) && + ((bFracHi | bFracLo) != 0u); + + if (isaNaN || isbNaN) + return false; + + aSign = extractFloat64Sign(a); + bSign = extractFloat64Sign(b); + if (aSign != bSign) + return (aSign != 0u) || ((((a.y | b.y)<<1) | a.x | b.x) == 0u); + + return (aSign != 0u) ? le64(b.y, b.x, a.y, a.x) + : le64(a.y, a.x, b.y, b.x); +} diff --git a/src/compiler/glsl/glcpp/glcpp-parse.y b/src/compiler/glsl/glcpp/glcpp-parse.y index c341432010..8383aad5ce 100644 --- a/src/compiler/glsl/glcpp/glcpp-parse.y +++ b/src/compiler/glsl/glcpp/glcpp-parse.y @@ -2453,6 +2453,7 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio add_builtin_define(parser, "__have_builtin_builtin_fneg64", 1); add_builtin_define(parser, "__have_builtin_builtin_fsign64", 1); add_builtin_define(parser, "__have_builtin_builtin_feq64", 1); + add_builtin_define(parser, "__have_builtin_builtin_fle64", 1); } } -- 2.14.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev