[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