Signed-off-by: Elie Tournier <elie.tourn...@collabora.com> --- src/compiler/glsl/builtin_float64.h | 490 ++++++++++++++++++++++++++++++++ src/compiler/glsl/builtin_functions.cpp | 4 + src/compiler/glsl/builtin_functions.h | 3 + src/compiler/glsl/float64.glsl | 77 +++++ 4 files changed, 574 insertions(+)
diff --git a/src/compiler/glsl/builtin_float64.h b/src/compiler/glsl/builtin_float64.h index a795d404c1..b50ebc2dc2 100644 --- a/src/compiler/glsl/builtin_float64.h +++ b/src/compiler/glsl/builtin_float64.h @@ -23162,3 +23162,493 @@ r1189_data.u[1] = 4294967295; sig->replace_parameters(&sig_parameters); return sig; } +ir_function_signature * +normalizeFloat32Subnormal(void *mem_ctx, builtin_available_predicate avail) +{ + ir_function_signature *const sig = + new(mem_ctx) ir_function_signature(glsl_type::void_type, avail); + ir_factory body(&sig->body, mem_ctx); + sig->is_defined = true; + + exec_list sig_parameters; + + ir_variable *const r1354 = new(mem_ctx) ir_variable(glsl_type::uint_type, "aFrac", ir_var_function_in); + sig_parameters.push_tail(r1354); + ir_variable *const r1355 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zExpPtr", ir_var_function_inout); + sig_parameters.push_tail(r1355); + ir_variable *const r1356 = new(mem_ctx) ir_variable(glsl_type::uint_type, "zFracPtr", ir_var_function_inout); + sig_parameters.push_tail(r1356); + ir_variable *const r1357 = new(mem_ctx) ir_variable(glsl_type::uint_type, "shiftCount", ir_var_auto); + body.emit(r1357); + ir_variable *const r1358 = body.make_temp(glsl_type::uint_type, "a"); + body.emit(assign(r1358, r1354, 0x01)); + + ir_variable *const r1359 = body.make_temp(glsl_type::uint_type, "return_value"); + ir_variable *const r135A = new(mem_ctx) ir_variable(glsl_type::uint_type, "shiftCount", ir_var_auto); + body.emit(r135A); + /* IF CONDITION */ + ir_expression *const r135C = equal(r1354, body.constant(0u)); + ir_if *f135B = new(mem_ctx) ir_if(operand(r135C).val); + exec_list *const f135B_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f135B->then_instructions; + + body.emit(assign(r1359, body.constant(32u), 0x01)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f135B->else_instructions; + + body.emit(assign(r135A, body.constant(0u), 0x01)); + + /* IF CONDITION */ + ir_expression *const r135E = bit_and(r1354, body.constant(4294901760u)); + ir_expression *const r135F = equal(r135E, body.constant(0u)); + ir_if *f135D = new(mem_ctx) ir_if(operand(r135F).val); + exec_list *const f135D_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f135D->then_instructions; + + body.emit(assign(r135A, body.constant(16u), 0x01)); + + body.emit(assign(r1358, lshift(r1354, body.constant(int(16))), 0x01)); + + + body.instructions = f135D_parent_instructions; + body.emit(f135D); + + /* END IF */ + + /* IF CONDITION */ + ir_expression *const r1361 = bit_and(r1358, body.constant(4278190080u)); + ir_expression *const r1362 = equal(r1361, body.constant(0u)); + ir_if *f1360 = new(mem_ctx) ir_if(operand(r1362).val); + exec_list *const f1360_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f1360->then_instructions; + + body.emit(assign(r135A, add(r135A, body.constant(8u)), 0x01)); + + body.emit(assign(r1358, lshift(r1358, body.constant(int(8))), 0x01)); + + + body.instructions = f1360_parent_instructions; + body.emit(f1360); + + /* END IF */ + + /* IF CONDITION */ + ir_expression *const r1364 = bit_and(r1358, body.constant(4026531840u)); + ir_expression *const r1365 = equal(r1364, body.constant(0u)); + ir_if *f1363 = new(mem_ctx) ir_if(operand(r1365).val); + exec_list *const f1363_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f1363->then_instructions; + + body.emit(assign(r135A, add(r135A, body.constant(4u)), 0x01)); + + body.emit(assign(r1358, lshift(r1358, body.constant(int(4))), 0x01)); + + + body.instructions = f1363_parent_instructions; + body.emit(f1363); + + /* END IF */ + + /* IF CONDITION */ + ir_expression *const r1367 = bit_and(r1358, body.constant(3221225472u)); + ir_expression *const r1368 = equal(r1367, body.constant(0u)); + ir_if *f1366 = new(mem_ctx) ir_if(operand(r1368).val); + exec_list *const f1366_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f1366->then_instructions; + + body.emit(assign(r135A, add(r135A, body.constant(2u)), 0x01)); + + body.emit(assign(r1358, lshift(r1358, body.constant(int(2))), 0x01)); + + + body.instructions = f1366_parent_instructions; + body.emit(f1366); + + /* END IF */ + + /* IF CONDITION */ + ir_expression *const r136A = bit_and(r1358, body.constant(2147483648u)); + ir_expression *const r136B = equal(r136A, body.constant(0u)); + ir_if *f1369 = new(mem_ctx) ir_if(operand(r136B).val); + exec_list *const f1369_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f1369->then_instructions; + + body.emit(assign(r135A, add(r135A, body.constant(1u)), 0x01)); + + + body.instructions = f1369_parent_instructions; + body.emit(f1369); + + /* END IF */ + + body.emit(assign(r1359, r135A, 0x01)); + + + body.instructions = f135B_parent_instructions; + body.emit(f135B); + + /* END IF */ + + body.emit(assign(r1357, add(r1359, body.constant(4294967288u)), 0x01)); + + body.emit(assign(r1356, lshift(r1354, r1357), 0x01)); + + body.emit(assign(r1355, sub(body.constant(1u), r1357), 0x01)); + + sig->replace_parameters(&sig_parameters); + return sig; +} +ir_function_signature * +extractFloat32Frac(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 r136C = new(mem_ctx) ir_variable(glsl_type::uint_type, "a", ir_var_function_in); + sig_parameters.push_tail(r136C); + ir_expression *const r136D = bit_and(r136C, body.constant(8388607u)); + body.emit(ret(r136D)); + + sig->replace_parameters(&sig_parameters); + return sig; +} +ir_function_signature * +extractFloat32Exp(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 r136E = new(mem_ctx) ir_variable(glsl_type::uint_type, "a", ir_var_function_in); + sig_parameters.push_tail(r136E); + ir_expression *const r136F = rshift(r136E, body.constant(int(23))); + ir_expression *const r1370 = bit_and(r136F, body.constant(255u)); + body.emit(ret(r1370)); + + sig->replace_parameters(&sig_parameters); + return sig; +} +ir_function_signature * +extractFloat32Sign(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 r1371 = new(mem_ctx) ir_variable(glsl_type::uint_type, "a", ir_var_function_in); + sig_parameters.push_tail(r1371); + ir_expression *const r1372 = rshift(r1371, body.constant(int(31))); + body.emit(ret(r1372)); + + sig->replace_parameters(&sig_parameters); + return sig; +} +ir_function_signature * +fp32_to_fp64(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 r1373 = new(mem_ctx) ir_variable(glsl_type::uint_type, "a", ir_var_function_in); + sig_parameters.push_tail(r1373); + ir_variable *const r1374 = body.make_temp(glsl_type::uvec2_type, "return_value"); + ir_variable *const r1375 = new(mem_ctx) ir_variable(glsl_type::uint_type, "aExp", ir_var_auto); + body.emit(r1375); + ir_variable *const r1376 = new(mem_ctx) ir_variable(glsl_type::uint_type, "aFrac", ir_var_auto); + body.emit(r1376); + ir_variable *const r1377 = body.make_temp(glsl_type::uint_type, "extractFloat32Frac_retval"); + body.emit(assign(r1377, bit_and(r1373, body.constant(8388607u)), 0x01)); + + body.emit(assign(r1376, r1377, 0x01)); + + ir_variable *const r1378 = body.make_temp(glsl_type::uint_type, "extractFloat32Exp_retval"); + ir_expression *const r1379 = rshift(r1373, body.constant(int(23))); + body.emit(assign(r1378, bit_and(r1379, body.constant(255u)), 0x01)); + + body.emit(assign(r1375, r1378, 0x01)); + + ir_variable *const r137A = body.make_temp(glsl_type::uint_type, "extractFloat32Sign_retval"); + body.emit(assign(r137A, rshift(r1373, body.constant(int(31))), 0x01)); + + /* IF CONDITION */ + ir_expression *const r137C = equal(r1378, body.constant(255u)); + ir_if *f137B = new(mem_ctx) ir_if(operand(r137C).val); + exec_list *const f137B_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f137B->then_instructions; + + /* IF CONDITION */ + ir_expression *const r137E = nequal(r1377, body.constant(0u)); + ir_if *f137D = new(mem_ctx) ir_if(operand(r137E).val); + exec_list *const f137D_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f137D->then_instructions; + + ir_variable *const r137F = body.make_temp(glsl_type::uvec2_type, "vec_ctor"); + ir_expression *const r1380 = lshift(r137A, body.constant(int(31))); + ir_expression *const r1381 = bit_or(r1380, body.constant(2146435072u)); + ir_expression *const r1382 = rshift(r1377, body.constant(int(3))); + body.emit(assign(r137F, bit_or(r1381, r1382), 0x01)); + + body.emit(assign(r137F, lshift(r1377, body.constant(int(29))), 0x02)); + + body.emit(assign(r1374, r137F, 0x03)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f137D->else_instructions; + + ir_variable *const r1383 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "z", ir_var_auto); + body.emit(r1383); + ir_expression *const r1384 = lshift(r137A, body.constant(int(31))); + body.emit(assign(r1383, add(r1384, body.constant(2146435072u)), 0x01)); + + body.emit(assign(r1383, body.constant(0u), 0x02)); + + body.emit(assign(r1374, r1383, 0x03)); + + + body.instructions = f137D_parent_instructions; + body.emit(f137D); + + /* END IF */ + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f137B->else_instructions; + + /* IF CONDITION */ + ir_expression *const r1386 = equal(r1378, body.constant(0u)); + ir_if *f1385 = new(mem_ctx) ir_if(operand(r1386).val); + exec_list *const f1385_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f1385->then_instructions; + + /* IF CONDITION */ + ir_expression *const r1388 = nequal(r1377, body.constant(0u)); + ir_if *f1387 = new(mem_ctx) ir_if(operand(r1388).val); + exec_list *const f1387_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f1387->then_instructions; + + ir_variable *const r1389 = body.make_temp(glsl_type::uint_type, "zExpPtr"); + body.emit(assign(r1389, r1378, 0x01)); + + ir_variable *const r138A = body.make_temp(glsl_type::uint_type, "zFracPtr"); + body.emit(assign(r138A, r1377, 0x01)); + + ir_variable *const r138B = new(mem_ctx) ir_variable(glsl_type::uint_type, "shiftCount", ir_var_auto); + body.emit(r138B); + ir_variable *const r138C = body.make_temp(glsl_type::uint_type, "a"); + body.emit(assign(r138C, r1377, 0x01)); + + ir_variable *const r138D = body.make_temp(glsl_type::uint_type, "return_value"); + ir_variable *const r138E = new(mem_ctx) ir_variable(glsl_type::uint_type, "shiftCount", ir_var_auto); + body.emit(r138E); + /* IF CONDITION */ + ir_expression *const r1390 = equal(r1377, body.constant(0u)); + ir_if *f138F = new(mem_ctx) ir_if(operand(r1390).val); + exec_list *const f138F_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f138F->then_instructions; + + body.emit(assign(r138D, body.constant(32u), 0x01)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f138F->else_instructions; + + body.emit(assign(r138E, body.constant(0u), 0x01)); + + /* IF CONDITION */ + ir_expression *const r1392 = bit_and(r1377, body.constant(4294901760u)); + ir_expression *const r1393 = equal(r1392, body.constant(0u)); + ir_if *f1391 = new(mem_ctx) ir_if(operand(r1393).val); + exec_list *const f1391_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f1391->then_instructions; + + body.emit(assign(r138E, body.constant(16u), 0x01)); + + body.emit(assign(r138C, lshift(r1377, body.constant(int(16))), 0x01)); + + + body.instructions = f1391_parent_instructions; + body.emit(f1391); + + /* END IF */ + + /* IF CONDITION */ + ir_expression *const r1395 = bit_and(r138C, body.constant(4278190080u)); + ir_expression *const r1396 = equal(r1395, body.constant(0u)); + ir_if *f1394 = new(mem_ctx) ir_if(operand(r1396).val); + exec_list *const f1394_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f1394->then_instructions; + + body.emit(assign(r138E, add(r138E, body.constant(8u)), 0x01)); + + body.emit(assign(r138C, lshift(r138C, body.constant(int(8))), 0x01)); + + + body.instructions = f1394_parent_instructions; + body.emit(f1394); + + /* END IF */ + + /* IF CONDITION */ + ir_expression *const r1398 = bit_and(r138C, body.constant(4026531840u)); + ir_expression *const r1399 = equal(r1398, body.constant(0u)); + ir_if *f1397 = new(mem_ctx) ir_if(operand(r1399).val); + exec_list *const f1397_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f1397->then_instructions; + + body.emit(assign(r138E, add(r138E, body.constant(4u)), 0x01)); + + body.emit(assign(r138C, lshift(r138C, body.constant(int(4))), 0x01)); + + + body.instructions = f1397_parent_instructions; + body.emit(f1397); + + /* END IF */ + + /* IF CONDITION */ + ir_expression *const r139B = bit_and(r138C, body.constant(3221225472u)); + ir_expression *const r139C = equal(r139B, body.constant(0u)); + ir_if *f139A = new(mem_ctx) ir_if(operand(r139C).val); + exec_list *const f139A_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f139A->then_instructions; + + body.emit(assign(r138E, add(r138E, body.constant(2u)), 0x01)); + + body.emit(assign(r138C, lshift(r138C, body.constant(int(2))), 0x01)); + + + body.instructions = f139A_parent_instructions; + body.emit(f139A); + + /* END IF */ + + /* IF CONDITION */ + ir_expression *const r139E = bit_and(r138C, body.constant(2147483648u)); + ir_expression *const r139F = equal(r139E, body.constant(0u)); + ir_if *f139D = new(mem_ctx) ir_if(operand(r139F).val); + exec_list *const f139D_parent_instructions = body.instructions; + + /* THEN INSTRUCTIONS */ + body.instructions = &f139D->then_instructions; + + body.emit(assign(r138E, add(r138E, body.constant(1u)), 0x01)); + + + body.instructions = f139D_parent_instructions; + body.emit(f139D); + + /* END IF */ + + body.emit(assign(r138D, r138E, 0x01)); + + + body.instructions = f138F_parent_instructions; + body.emit(f138F); + + /* END IF */ + + body.emit(assign(r138B, add(r138D, body.constant(4294967288u)), 0x01)); + + body.emit(assign(r138A, lshift(r1377, r138B), 0x01)); + + body.emit(assign(r1389, sub(body.constant(1u), r138B), 0x01)); + + body.emit(assign(r1376, r138A, 0x01)); + + body.emit(assign(r1375, add(r1389, body.constant(4294967295u)), 0x01)); + + + body.instructions = f1387_parent_instructions; + body.emit(f1387); + + /* END IF */ + + ir_variable *const r13A0 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "z", ir_var_auto); + body.emit(r13A0); + body.emit(assign(r13A0, lshift(r137A, body.constant(int(31))), 0x01)); + + body.emit(assign(r13A0, body.constant(0u), 0x02)); + + body.emit(assign(r1374, r13A0, 0x03)); + + + /* ELSE INSTRUCTIONS */ + body.instructions = &f1385->else_instructions; + + ir_variable *const r13A1 = new(mem_ctx) ir_variable(glsl_type::uvec2_type, "z", ir_var_auto); + body.emit(r13A1); + ir_expression *const r13A2 = lshift(r137A, body.constant(int(31))); + ir_expression *const r13A3 = add(r1375, body.constant(896u)); + ir_expression *const r13A4 = lshift(r13A3, body.constant(int(20))); + ir_expression *const r13A5 = add(r13A2, r13A4); + ir_expression *const r13A6 = rshift(r1376, body.constant(int(3))); + body.emit(assign(r13A1, add(r13A5, r13A6), 0x01)); + + body.emit(assign(r13A1, lshift(r1376, body.constant(int(29))), 0x02)); + + body.emit(assign(r1374, r13A1, 0x03)); + + + body.instructions = f1385_parent_instructions; + body.emit(f1385); + + /* END IF */ + + + body.instructions = f137B_parent_instructions; + body.emit(f137B); + + /* END IF */ + + body.emit(ret(r1374)); + + sig->replace_parameters(&sig_parameters); + return sig; +} diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp index d754d82cd2..17192b63f2 100644 --- a/src/compiler/glsl/builtin_functions.cpp +++ b/src/compiler/glsl/builtin_functions.cpp @@ -3161,6 +3161,10 @@ builtin_builder::create_builtins() generate_ir::fdiv64(mem_ctx, integer_functions_supported), NULL); + add_function("__builtin_fp32_to_fp64", + generate_ir::fp32_to_fp64(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 efbd8315c6..a228f17596 100644 --- a/src/compiler/glsl/builtin_functions.h +++ b/src/compiler/glsl/builtin_functions.h @@ -87,6 +87,9 @@ fmul64(void *mem_ctx, builtin_available_predicate avail); ir_function_signature * fdiv64(void *mem_ctx, builtin_available_predicate avail); +ir_function_signature * +fp32_to_fp64(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 658d19076a..ee9224c293 100644 --- a/src/compiler/glsl/float64.glsl +++ b/src/compiler/glsl/float64.glsl @@ -1166,3 +1166,80 @@ fdiv64( uvec2 a, uvec2 b ) shift64ExtraRightJamming( zFrac0, zFrac1, 0u, 11, zFrac0, zFrac1, zFrac2 ); return roundAndPackFloat64( zSign, zExp, zFrac0, zFrac1, zFrac2 ); } + +/* Normalizes the subnormal single-precision floating-point value represented + * by the denormalized significand `aFrac'. The normalized exponent and + * significand are stored at the locations pointed to by `zExpPtr' and + * `zFracPtr', respectively. + */ +void +normalizeFloat32Subnormal( uint aFrac, + inout uint zExpPtr, + inout uint zFracPtr ) +{ + uint shiftCount; + + shiftCount = countLeadingZeros32( aFrac ) - 8u; + zFracPtr = aFrac<<shiftCount; + zExpPtr = 1u - shiftCount; +} + +/* Returns the fraction bits of the single-precision floating-point value `a'.*/ +uint +extractFloat32Frac( uint a ) +{ + return a & 0x007FFFFFu; +} + +/* Returns the exponent bits of the single-precision floating-point value `a'.*/ +uint +extractFloat32Exp( uint a ) +{ + return (a>>23) & 0xFFu; +} + +/* Returns the sign bit of the single-precision floating-point value `a'.*/ +uint +extractFloat32Sign( uint a ) +{ + return a>>31; +} + +/* Returns the result of converting the single-precision floating-point value + * `a' to the double-precision floating-point format. + */ +uvec2 +fp32_to_fp64( uint a ) +{ + uint aFrac; + uint aExp; + uint aSign; + + aFrac = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + + if ( aExp == 0xFFu ) { + if ( aFrac != 0u ) { + /* NaN */ + return uvec2( + ( ( aSign<<31 ) | 0x7FF00000u | ( aFrac>>3 ) ), + ( aFrac<<29 ) + ); + } + /* Inf */ + return packFloat64( aSign, 0x7FFu, 0u, 0u ); + } + + if ( aExp == 0u ) { + if ( aFrac != 0u ) { + /* Denormals */ + normalizeFloat32Subnormal( aFrac, aExp, aFrac ); + --aExp; + } + /* Zero */ + return packFloat64( aSign, 0u, 0u, 0u ); + } + + return packFloat64( aSign, aExp + 0x380u, aFrac>>3, aFrac<<29 ); +} -- 2.11.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev