[Mesa-dev] [RFC 09/11] glsl: Add "built-in" functions to do fp32_to_fp64(fp32)
Elie Tournier
tournier.elie at gmail.com
Fri Mar 3 16:23:05 UTC 2017
Signed-off-by: Elie Tournier <elie.tournier at 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
More information about the mesa-dev
mailing list