aboutsummaryrefslogtreecommitdiff
path: root/src/common.cpp
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-11-22 00:13:52 +0000
committerGinger Bill <bill@gingerbill.org>2016-11-22 00:13:52 +0000
commit36ad9dae43cd21d8532994cd0d0e92a89af0ed04 (patch)
tree2ab180093e4d5ac1e6ed39ed3b8ce5437255ffb5 /src/common.cpp
parent24347ced45aabd3ce4f4a261b8140a976cadff2e (diff)
128 bit integers
Kind of works but may be buggy due to LLVM not actually sure
Diffstat (limited to 'src/common.cpp')
-rw-r--r--src/common.cpp51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/common.cpp b/src/common.cpp
index d0703378c..e07ea362a 100644
--- a/src/common.cpp
+++ b/src/common.cpp
@@ -167,6 +167,57 @@ i64 prev_pow2(i64 n) {
return n - (n >> 1);
}
+i16 f32_to_f16(f32 value) {
+ union { u32 i; f32 f; } v;
+ i32 i, s, e, m;
+
+ v.f = value;
+ i = (i32)v.i;
+
+ s = (i >> 16) & 0x00008000;
+ e = ((i >> 23) & 0x000000ff) - (127 - 15);
+ m = i & 0x007fffff;
+
+
+ if (e <= 0) {
+ if (e < -10) return cast(i16)s;
+ m = (m | 0x00800000) >> (1 - e);
+
+ if (m & 0x00001000)
+ m += 0x00002000;
+
+ return cast(i16)(s | (m >> 13));
+ } else if (e == 0xff - (127 - 15)) {
+ if (m == 0) {
+ return cast(i16)(s | 0x7c00); /* NOTE(bill): infinity */
+ } else {
+ /* NOTE(bill): NAN */
+ m >>= 13;
+ return cast(i16)(s | 0x7c00 | m | (m == 0));
+ }
+ } else {
+ if (m & 0x00001000) {
+ m += 0x00002000;
+ if (m & 0x00800000) {
+ m = 0;
+ e += 1;
+ }
+ }
+
+ if (e > 30) {
+ float volatile f = 1e12f;
+ int j;
+ for (j = 0; j < 10; j++)
+ f *= f; /* NOTE(bill): Cause overflow */
+
+ return cast(i16)(s | 0x7c00);
+ }
+
+ return cast(i16)(s | (e << 10) | (m >> 13));
+ }
+}
+
+
#define for_array(index_, array_) for (isize index_ = 0; index_ < (array_).count; index_++)