aboutsummaryrefslogtreecommitdiff
path: root/std/special/compiler_rt/floatunsitf.zig
diff options
context:
space:
mode:
authorAndrea Orru <andrea@orru.io>2018-08-06 01:43:19 -0400
committerAndrea Orru <andrea@orru.io>2018-08-06 01:43:19 -0400
commitd2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d (patch)
treee9fa3caec533a0d1e2b434868b2fde1f9240e5c8 /std/special/compiler_rt/floatunsitf.zig
parent06614b3fa09954464c2e2f32756cacedc178a282 (diff)
parent63a23e848a62d5f167f8d5478de9766cb24aa6eb (diff)
downloadzig-d2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d.tar.gz
zig-d2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d.zip
Merge branch 'master' into zen_stdlib
Diffstat (limited to 'std/special/compiler_rt/floatunsitf.zig')
-rw-r--r--std/special/compiler_rt/floatunsitf.zig29
1 files changed, 29 insertions, 0 deletions
diff --git a/std/special/compiler_rt/floatunsitf.zig b/std/special/compiler_rt/floatunsitf.zig
new file mode 100644
index 0000000000..19a5918bd0
--- /dev/null
+++ b/std/special/compiler_rt/floatunsitf.zig
@@ -0,0 +1,29 @@
+const builtin = @import("builtin");
+const is_test = builtin.is_test;
+const std = @import("std");
+
+pub extern fn __floatunsitf(a: u64) f128 {
+ @setRuntimeSafety(is_test);
+
+ if (a == 0) {
+ return 0;
+ }
+
+ const mantissa_bits = std.math.floatMantissaBits(f128);
+ const exponent_bits = std.math.floatExponentBits(f128);
+ const exponent_bias = (1 << (exponent_bits - 1)) - 1;
+ const implicit_bit = 1 << mantissa_bits;
+
+ const exp = (u64.bit_count - 1) - @clz(a);
+ const shift = mantissa_bits - @intCast(u7, exp);
+
+ // TODO(#1148): @bitCast alignment error
+ var result align(16) = (@intCast(u128, a) << shift) ^ implicit_bit;
+ result += (@intCast(u128, exp) + exponent_bias) << mantissa_bits;
+
+ return @bitCast(f128, result);
+}
+
+test "import floatunsitf" {
+ _ = @import("floatunsitf_test.zig");
+}