[Builtins] Implement half-precision conversions.
Mostly uninteresting, except:
- in __extendXfYf2, when checking if the number is normal, the old
code relied on the unsignedness of src_rep_t, which is a problem
when sizeof(src_rep_t) < sizeof(int): the result gets promoted to
int, the signedness of which breaks the comparison.
I added an explicit cast; it shouldn't affect other types.
- we can't pass __fp16, so src_t and src_rep_t are the same.
- the gnu_*_ieee symbols are simply duplicated definitions, as aliases
are problematic on mach-o (where only weak aliases are supported;
that's not what we want).
Differential Revision: http://reviews.llvm.org/D9693
llvm-svn: 237161
diff --git a/compiler-rt/lib/builtins/fp_extend.h b/compiler-rt/lib/builtins/fp_extend.h
index fff676e..5c2b923 100644
--- a/compiler-rt/lib/builtins/fp_extend.h
+++ b/compiler-rt/lib/builtins/fp_extend.h
@@ -39,11 +39,24 @@
#endif
}
+#elif defined SRC_HALF
+typedef uint16_t src_t;
+typedef uint16_t src_rep_t;
+#define SRC_REP_C UINT16_C
+static const int srcSigBits = 10;
+#define src_rep_t_clz __builtin_clz
+
#else
-#error Source should be single precision or double precision!
+#error Source should be half, single, or double precision!
#endif //end source precision
-#if defined DST_DOUBLE
+#if defined DST_SINGLE
+typedef float dst_t;
+typedef uint32_t dst_rep_t;
+#define DST_REP_C UINT32_C
+static const int dstSigBits = 23;
+
+#elif defined DST_DOUBLE
typedef double dst_t;
typedef uint64_t dst_rep_t;
#define DST_REP_C UINT64_C
@@ -56,7 +69,7 @@
static const int dstSigBits = 112;
#else
-#error Destination should be double precision or quad precision!
+#error Destination should be single, double, or quad precision!
#endif //end destination precision
// End of specialization parameters. Two helper routines for conversion to and