Commit 634d11ab28

Wink Saville <wink@saville.com>
2018-12-06 01:50:33
Add add compiler_rt routines for float to signed integer conversion
And add std.math.f128_* constants. The routines are: __fixdfdi, __fixdfsi, __fixdfti, __fixsfdi, __fixsfsi, __fixsfti, __fixtfdi, __fixtfsi, __fixtfti. These all call fixint which is a generic zig function that does the conversion: pub fn fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t) fixint_t There are also a set tests: __fixdfdi_test, __fixdfsi_test, __fixdfti_test, __fixsfdi_test, __fixsfsi_test, __fixsfti_test, __fixtfdi_test, __fixtfsi_test, __fixtfti_test.
1 parent 5f5364a
std/math/index.zig
@@ -6,6 +6,13 @@ const assert = std.debug.assert;
 pub const e = 2.71828182845904523536028747135266249775724709369995;
 pub const pi = 3.14159265358979323846264338327950288419716939937510;
 
+// From a small c++ [program using boost float128](https://github.com/winksaville/cpp_boost_float128)
+pub const f128_true_min = @bitCast(f128, u128(0x00000000000000000000000000000001));
+pub const f128_min = @bitCast(f128, u128(0x00010000000000000000000000000000));
+pub const f128_max = @bitCast(f128, u128(0x7FFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF));
+pub const f128_epsilon = @bitCast(f128, u128(0x3F8F0000000000000000000000000000));
+pub const f128_toint = 1.0 / f128_epsilon;
+
 // float.h details
 pub const f64_true_min = 4.94065645841246544177e-324;
 pub const f64_min = 2.2250738585072014e-308;
std/special/compiler_rt/fixdfdi.zig
@@ -0,0 +1,11 @@
+const fixint = @import("fixint.zig").fixint;
+const builtin = @import("builtin");
+
+pub extern fn __fixdfdi(a: f64) i64 {
+    @setRuntimeSafety(builtin.is_test);
+    return fixint(f64, i64, a);
+}
+
+test "import fixdfdi" {
+    _ = @import("fixdfdi_test.zig");
+}
std/special/compiler_rt/fixdfdi_test.zig
@@ -0,0 +1,66 @@
+const __fixdfdi = @import("fixdfdi.zig").__fixdfdi;
+const std = @import("std");
+const math = std.math;
+const assert = std.debug.assert;
+const warn = std.debug.warn;
+
+fn test__fixdfdi(a: f64, expected: i64) void {
+    const x = __fixdfdi(a);
+    //warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u64, expected));
+    assert(x == expected);
+}
+
+test "fixdfdi" {
+    //warn("\n");
+
+    test__fixdfdi(-math.f64_max, math.minInt(i64));
+
+    test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
+    test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
+
+    test__fixdfdi(-0x1.0000000000000p+127, -0x8000000000000000);
+    test__fixdfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
+    test__fixdfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
+
+    test__fixdfdi(-0x1.0000000000001p+63, -0x8000000000000000);
+    test__fixdfdi(-0x1.0000000000000p+63, -0x8000000000000000);
+    test__fixdfdi(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
+    test__fixdfdi(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
+
+    test__fixdfdi(-0x1.FFFFFEp+62, -0x7fffff8000000000);
+    test__fixdfdi(-0x1.FFFFFCp+62, -0x7fffff0000000000);
+
+    test__fixdfdi(-2.01, -2);
+    test__fixdfdi(-2.0, -2);
+    test__fixdfdi(-1.99, -1);
+    test__fixdfdi(-1.0, -1);
+    test__fixdfdi(-0.99, 0);
+    test__fixdfdi(-0.5, 0);
+    test__fixdfdi(-math.f64_min, 0);
+    test__fixdfdi(0.0, 0);
+    test__fixdfdi(math.f64_min, 0);
+    test__fixdfdi(0.5, 0);
+    test__fixdfdi(0.99, 0);
+    test__fixdfdi(1.0, 1);
+    test__fixdfdi(1.5, 1);
+    test__fixdfdi(1.99, 1);
+    test__fixdfdi(2.0, 2);
+    test__fixdfdi(2.01, 2);
+
+    test__fixdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
+    test__fixdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
+
+    test__fixdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
+    test__fixdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
+    test__fixdfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
+    test__fixdfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
+
+    test__fixdfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
+    test__fixdfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
+    test__fixdfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
+
+    test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
+    test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
+
+    test__fixdfdi(math.f64_max, math.maxInt(i64));
+}
std/special/compiler_rt/fixdfsi.zig
@@ -0,0 +1,11 @@
+const fixint = @import("fixint.zig").fixint;
+const builtin = @import("builtin");
+
+pub extern fn __fixdfsi(a: f64) i32 {
+    @setRuntimeSafety(builtin.is_test);
+    return fixint(f64, i32, a);
+}
+
+test "import fixdfsi" {
+    _ = @import("fixdfsi_test.zig");
+}
std/special/compiler_rt/fixdfsi_test.zig
@@ -0,0 +1,74 @@
+const __fixdfsi = @import("fixdfsi.zig").__fixdfsi;
+const std = @import("std");
+const math = std.math;
+const assert = std.debug.assert;
+const warn = std.debug.warn;
+
+fn test__fixdfsi(a: f64, expected: i32) void {
+    const x = __fixdfsi(a);
+    //warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u32, expected));
+    assert(x == expected);
+}
+
+test "fixdfsi" {
+    //warn("\n");
+
+    test__fixdfsi(-math.f64_max, math.minInt(i32));
+
+    test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
+    test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
+
+    test__fixdfsi(-0x1.0000000000000p+127, -0x80000000);
+    test__fixdfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
+    test__fixdfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
+
+    test__fixdfsi(-0x1.0000000000001p+63,  -0x80000000);
+    test__fixdfsi(-0x1.0000000000000p+63,  -0x80000000);
+    test__fixdfsi(-0x1.FFFFFFFFFFFFFp+62,  -0x80000000);
+    test__fixdfsi(-0x1.FFFFFFFFFFFFEp+62,  -0x80000000);
+
+    test__fixdfsi(-0x1.FFFFFEp+62, -0x80000000);
+    test__fixdfsi(-0x1.FFFFFCp+62, -0x80000000);
+
+    test__fixdfsi(-0x1.000000p+31, -0x80000000);
+    test__fixdfsi(-0x1.FFFFFFp+30, -0x7FFFFFC0);
+    test__fixdfsi(-0x1.FFFFFEp+30, -0x7FFFFF80);
+
+    test__fixdfsi(-2.01, -2);
+    test__fixdfsi(-2.0, -2);
+    test__fixdfsi(-1.99, -1);
+    test__fixdfsi(-1.0, -1);
+    test__fixdfsi(-0.99, 0);
+    test__fixdfsi(-0.5, 0);
+    test__fixdfsi(-math.f64_min, 0);
+    test__fixdfsi(0.0, 0);
+    test__fixdfsi(math.f64_min, 0);
+    test__fixdfsi(0.5, 0);
+    test__fixdfsi(0.99, 0);
+    test__fixdfsi(1.0, 1);
+    test__fixdfsi(1.5, 1);
+    test__fixdfsi(1.99, 1);
+    test__fixdfsi(2.0, 2);
+    test__fixdfsi(2.01, 2);
+
+    test__fixdfsi(0x1.FFFFFEp+30, 0x7FFFFF80);
+    test__fixdfsi(0x1.FFFFFFp+30, 0x7FFFFFC0);
+    test__fixdfsi(0x1.000000p+31, 0x7FFFFFFF);
+
+    test__fixdfsi(0x1.FFFFFCp+62, 0x7FFFFFFF);
+    test__fixdfsi(0x1.FFFFFEp+62, 0x7FFFFFFF);
+
+    test__fixdfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
+    test__fixdfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
+    test__fixdfsi(0x1.0000000000000p+63, 0x7FFFFFFF);
+    test__fixdfsi(0x1.0000000000001p+63, 0x7FFFFFFF);
+
+    test__fixdfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
+    test__fixdfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
+    test__fixdfsi(0x1.0000000000000p+127, 0x7FFFFFFF);
+
+    test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
+    test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
+
+    test__fixdfsi(math.f64_max, math.maxInt(i32));
+}
std/special/compiler_rt/fixdfti.zig
@@ -0,0 +1,11 @@
+const fixint = @import("fixint.zig").fixint;
+const builtin = @import("builtin");
+
+pub extern fn __fixdfti(a: f64) i128 {
+    @setRuntimeSafety(builtin.is_test);
+    return fixint(f64, i128, a);
+}
+
+test "import fixdfti" {
+    _ = @import("fixdfti_test.zig");
+}
std/special/compiler_rt/fixdfti_test.zig
@@ -0,0 +1,66 @@
+const __fixdfti = @import("fixdfti.zig").__fixdfti;
+const std = @import("std");
+const math = std.math;
+const assert = std.debug.assert;
+const warn = std.debug.warn;
+
+fn test__fixdfti(a: f64, expected: i128) void {
+    const x = __fixdfti(a);
+    //warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u128, expected));
+    assert(x == expected);
+}
+
+test "fixdfti" {
+    //warn("\n");
+
+    test__fixdfti(-math.f64_max, math.minInt(i128));
+
+    test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
+    test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
+
+    test__fixdfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
+    test__fixdfti(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000);
+    test__fixdfti(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000);
+
+    test__fixdfti(-0x1.0000000000001p+63, -0x8000000000000800);
+    test__fixdfti(-0x1.0000000000000p+63, -0x8000000000000000);
+    test__fixdfti(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
+    test__fixdfti(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
+
+    test__fixdfti(-0x1.FFFFFEp+62, -0x7fffff8000000000);
+    test__fixdfti(-0x1.FFFFFCp+62, -0x7fffff0000000000);
+
+    test__fixdfti(-2.01, -2);
+    test__fixdfti(-2.0, -2);
+    test__fixdfti(-1.99, -1);
+    test__fixdfti(-1.0, -1);
+    test__fixdfti(-0.99, 0);
+    test__fixdfti(-0.5, 0);
+    test__fixdfti(-math.f64_min, 0);
+    test__fixdfti(0.0, 0);
+    test__fixdfti(math.f64_min, 0);
+    test__fixdfti(0.5, 0);
+    test__fixdfti(0.99, 0);
+    test__fixdfti(1.0, 1);
+    test__fixdfti(1.5, 1);
+    test__fixdfti(1.99, 1);
+    test__fixdfti(2.0, 2);
+    test__fixdfti(2.01, 2);
+
+    test__fixdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
+    test__fixdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
+
+    test__fixdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
+    test__fixdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
+    test__fixdfti(0x1.0000000000000p+63, 0x8000000000000000);
+    test__fixdfti(0x1.0000000000001p+63, 0x8000000000000800);
+
+    test__fixdfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);
+    test__fixdfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);
+    test__fixdfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
+
+    test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
+    test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
+
+    test__fixdfti(math.f64_max, math.maxInt(i128));
+}
std/special/compiler_rt/fixint.zig
@@ -0,0 +1,74 @@
+const is_test = @import("builtin").is_test;
+const std = @import("std");
+const math = std.math;
+const Log2Int = std.math.Log2Int;
+const maxInt = std.math.maxInt;
+const minInt = std.math.minInt;
+
+const DBG = false;
+
+pub fn fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t) fixint_t {
+    @setRuntimeSafety(is_test);
+
+    const rep_t = switch (fp_t) {
+        f32 => u32,
+        f64 => u64,
+        f128 => u128,
+        else => unreachable,
+    };
+    const significandBits = switch (fp_t) {
+        f32 => 23,
+        f64 => 52,
+        f128 => 112,
+        else => unreachable,
+    };
+
+    const typeWidth = rep_t.bit_count;
+    const exponentBits = (typeWidth - significandBits - 1);
+    const signBit = (rep_t(1) << (significandBits + exponentBits));
+    const maxExponent = ((1 << exponentBits) - 1);
+    const exponentBias = (maxExponent >> 1);
+
+    const implicitBit = (rep_t(1) << significandBits);
+    const significandMask = (implicitBit - 1);
+
+    // Break a into sign, exponent, significand
+    const aRep: rep_t = @bitCast(rep_t, a);
+    const absMask = signBit - 1;
+    const aAbs: rep_t = aRep & absMask;
+
+    const negative = (aRep & signBit) != 0;
+    const exponent = @intCast(i32, aAbs >> significandBits) - exponentBias;
+    const significand: rep_t = (aAbs & significandMask) | implicitBit;
+
+    // If exponent is negative, the uint_result is zero.
+    if (exponent < 0) return 0;
+
+    // The unsigned result needs to be large enough to handle an fixint_t or rep_t
+    const fixuint_t = @IntType(false, fixint_t.bit_count);
+    const UintResultType = if (fixint_t.bit_count > rep_t.bit_count) fixuint_t else rep_t;
+    var uint_result: UintResultType = undefined;
+
+    // If the value is too large for the integer type, saturate.
+    if (@intCast(usize, exponent) >= fixint_t.bit_count) {
+        return if (negative) fixint_t(minInt(fixint_t)) else fixint_t(maxInt(fixint_t));
+    }
+
+    // If 0 <= exponent < significandBits, right shift else left shift
+    if (exponent < significandBits) {
+        uint_result = @intCast(UintResultType, significand) >> @intCast(Log2Int(UintResultType), significandBits - exponent);
+    } else {
+        uint_result = @intCast(UintResultType, significand) << @intCast(Log2Int(UintResultType), exponent - significandBits);
+    }
+
+    // Cast to final signed result
+    if (negative) {
+        return if (uint_result >= -math.minInt(fixint_t)) math.minInt(fixint_t) else -@intCast(fixint_t, uint_result);
+    } else {
+        return if (uint_result >= math.maxInt(fixint_t)) math.maxInt(fixint_t) else @intCast(fixint_t, uint_result);
+    }
+}
+
+test "import fixint" {
+    _ = @import("fixint_test.zig");
+}
std/special/compiler_rt/fixint_test.zig
@@ -0,0 +1,152 @@
+const is_test = @import("builtin").is_test;
+const std = @import("std");
+const math = std.math;
+const assert = std.debug.assert;
+const warn = std.debug.warn;
+
+const fixint = @import("fixint.zig").fixint;
+
+fn test__fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t, expected: fixint_t) void {
+    const x = fixint(fp_t, fixint_t, a);
+    //warn("a={} x={}:{x} expected={}:{x})\n", a, x, x, expected, expected);
+    assert(x == expected);
+}
+
+test "fixint.i1" {
+    test__fixint(f32, i1, -math.inf_f32, -1);
+    test__fixint(f32, i1, -math.f32_max, -1);
+    test__fixint(f32, i1, -2.0, -1);
+    test__fixint(f32, i1, -1.1, -1);
+    test__fixint(f32, i1, -1.0, -1);
+    test__fixint(f32, i1, -0.9, 0);
+    test__fixint(f32, i1, -0.1, 0);
+    test__fixint(f32, i1, -math.f32_min, 0);
+    test__fixint(f32, i1, -0.0, 0);
+    test__fixint(f32, i1, 0.0, 0);
+    test__fixint(f32, i1, math.f32_min, 0);
+    test__fixint(f32, i1, 0.1, 0);
+    test__fixint(f32, i1, 0.9, 0);
+    test__fixint(f32, i1, 1.0, 0);
+    test__fixint(f32, i1, 2.0, 0);
+    test__fixint(f32, i1, math.f32_max, 0);
+    test__fixint(f32, i1, math.inf_f32, 0);
+}
+
+test "fixint.i2" {
+    test__fixint(f32, i2, -math.inf_f32, -2);
+    test__fixint(f32, i2, -math.f32_max, -2);
+    test__fixint(f32, i2, -2.0, -2);
+    test__fixint(f32, i2, -1.9, -1);
+    test__fixint(f32, i2, -1.1, -1);
+    test__fixint(f32, i2, -1.0, -1);
+    test__fixint(f32, i2, -0.9, 0);
+    test__fixint(f32, i2, -0.1, 0);
+    test__fixint(f32, i2, -math.f32_min, 0);
+    test__fixint(f32, i2, -0.0, 0);
+    test__fixint(f32, i2, 0.0, 0);
+    test__fixint(f32, i2, math.f32_min, 0);
+    test__fixint(f32, i2, 0.1, 0);
+    test__fixint(f32, i2, 0.9, 0);
+    test__fixint(f32, i2, 1.0, 1);
+    test__fixint(f32, i2, 2.0, 1);
+    test__fixint(f32, i2, math.f32_max, 1);
+    test__fixint(f32, i2, math.inf_f32, 1);
+}
+
+test "fixint.i3" {
+    test__fixint(f32, i3, -math.inf_f32, -4);
+    test__fixint(f32, i3, -math.f32_max, -4);
+    test__fixint(f32, i3, -4.0, -4);
+    test__fixint(f32, i3, -3.0, -3);
+    test__fixint(f32, i3, -2.0, -2);
+    test__fixint(f32, i3, -1.9, -1);
+    test__fixint(f32, i3, -1.1, -1);
+    test__fixint(f32, i3, -1.0, -1);
+    test__fixint(f32, i3, -0.9, 0);
+    test__fixint(f32, i3, -0.1, 0);
+    test__fixint(f32, i3, -math.f32_min, 0);
+    test__fixint(f32, i3, -0.0, 0);
+    test__fixint(f32, i3, 0.0, 0);
+    test__fixint(f32, i3, math.f32_min, 0);
+    test__fixint(f32, i3, 0.1, 0);
+    test__fixint(f32, i3, 0.9, 0);
+    test__fixint(f32, i3, 1.0, 1);
+    test__fixint(f32, i3, 2.0, 2);
+    test__fixint(f32, i3, 3.0, 3);
+    test__fixint(f32, i3, 4.0, 3);
+    test__fixint(f32, i3, math.f32_max, 3);
+    test__fixint(f32, i3, math.inf_f32, 3);
+}
+
+test "fixint.i32" {
+    test__fixint(f64, i32, -math.inf_f64, math.minInt(i32));
+    test__fixint(f64, i32, -math.f64_max, math.minInt(i32));
+    test__fixint(f64, i32, f64(math.minInt(i32)), math.minInt(i32));
+    test__fixint(f64, i32, f64(math.minInt(i32))+1, math.minInt(i32)+1);
+    test__fixint(f64, i32, -2.0, -2);
+    test__fixint(f64, i32, -1.9, -1);
+    test__fixint(f64, i32, -1.1, -1);
+    test__fixint(f64, i32, -1.0, -1);
+    test__fixint(f64, i32, -0.9, 0);
+    test__fixint(f64, i32, -0.1, 0);
+    test__fixint(f64, i32, -math.f32_min, 0);
+    test__fixint(f64, i32, -0.0, 0);
+    test__fixint(f64, i32, 0.0, 0);
+    test__fixint(f64, i32, math.f32_min, 0);
+    test__fixint(f64, i32, 0.1, 0);
+    test__fixint(f64, i32, 0.9, 0);
+    test__fixint(f64, i32, 1.0, 1);
+    test__fixint(f64, i32, f64(math.maxInt(i32))-1, math.maxInt(i32)-1);
+    test__fixint(f64, i32, f64(math.maxInt(i32)), math.maxInt(i32));
+    test__fixint(f64, i32, math.f64_max, math.maxInt(i32));
+    test__fixint(f64, i32, math.inf_f64, math.maxInt(i32));
+}
+
+test "fixint.i64" {
+    test__fixint(f64, i64, -math.inf_f64, math.minInt(i64));
+    test__fixint(f64, i64, -math.f64_max, math.minInt(i64));
+    test__fixint(f64, i64, f64(math.minInt(i64)), math.minInt(i64));
+    test__fixint(f64, i64, f64(math.minInt(i64))+1, math.minInt(i64));
+    test__fixint(f64, i64, f64(math.minInt(i64)/2), math.minInt(i64)/2);
+    test__fixint(f64, i64, -2.0, -2);
+    test__fixint(f64, i64, -1.9, -1);
+    test__fixint(f64, i64, -1.1, -1);
+    test__fixint(f64, i64, -1.0, -1);
+    test__fixint(f64, i64, -0.9, 0);
+    test__fixint(f64, i64, -0.1, 0);
+    test__fixint(f64, i64, -math.f32_min, 0);
+    test__fixint(f64, i64, -0.0, 0);
+    test__fixint(f64, i64, 0.0, 0);
+    test__fixint(f64, i64, math.f32_min, 0);
+    test__fixint(f64, i64, 0.1, 0);
+    test__fixint(f64, i64, 0.9, 0);
+    test__fixint(f64, i64, 1.0, 1);
+    test__fixint(f64, i64, f64(math.maxInt(i64))-1, math.maxInt(i64));
+    test__fixint(f64, i64, f64(math.maxInt(i64)), math.maxInt(i64));
+    test__fixint(f64, i64, math.f64_max, math.maxInt(i64));
+    test__fixint(f64, i64, math.inf_f64, math.maxInt(i64));
+}
+
+test "fixint.i128" {
+    test__fixint(f64, i128, -math.inf_f64, math.minInt(i128));
+    test__fixint(f64, i128, -math.f64_max, math.minInt(i128));
+    test__fixint(f64, i128, f64(math.minInt(i128)), math.minInt(i128));
+    test__fixint(f64, i128, f64(math.minInt(i128))+1, math.minInt(i128));
+    test__fixint(f64, i128, -2.0, -2);
+    test__fixint(f64, i128, -1.9, -1);
+    test__fixint(f64, i128, -1.1, -1);
+    test__fixint(f64, i128, -1.0, -1);
+    test__fixint(f64, i128, -0.9, 0);
+    test__fixint(f64, i128, -0.1, 0);
+    test__fixint(f64, i128, -math.f32_min, 0);
+    test__fixint(f64, i128, -0.0, 0);
+    test__fixint(f64, i128, 0.0, 0);
+    test__fixint(f64, i128, math.f32_min, 0);
+    test__fixint(f64, i128, 0.1, 0);
+    test__fixint(f64, i128, 0.9, 0);
+    test__fixint(f64, i128, 1.0, 1);
+    test__fixint(f64, i128, f64(math.maxInt(i128))-1, math.maxInt(i128));
+    test__fixint(f64, i128, f64(math.maxInt(i128)), math.maxInt(i128));
+    test__fixint(f64, i128, math.f64_max, math.maxInt(i128));
+    test__fixint(f64, i128, math.inf_f64, math.maxInt(i128));
+}
std/special/compiler_rt/fixsfdi.zig
@@ -0,0 +1,11 @@
+const fixint = @import("fixint.zig").fixint;
+const builtin = @import("builtin");
+
+pub extern fn __fixsfdi(a: f32) i64 {
+    @setRuntimeSafety(builtin.is_test);
+    return fixint(f32, i64, a);
+}
+
+test "import fixsfdi" {
+    _ = @import("fixsfdi_test.zig");
+}
std/special/compiler_rt/fixsfdi_test.zig
@@ -0,0 +1,68 @@
+const __fixsfdi = @import("fixsfdi.zig").__fixsfdi;
+const std = @import("std");
+const math = std.math;
+const assert = std.debug.assert;
+const warn = std.debug.warn;
+
+fn test__fixsfdi(a: f32, expected: i64) void {
+    const x = __fixsfdi(a);
+    //warn("a={}:{x} x={}:{x} expected={}:{x}:u32({x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u64, expected));
+    assert(x == expected);
+}
+
+test "fixsfdi" {
+    //warn("\n");
+
+    test__fixsfdi(-math.f32_max, math.minInt(i64));
+
+    test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
+    test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
+
+    test__fixsfdi(-0x1.0000000000000p+127, -0x8000000000000000);
+    test__fixsfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
+    test__fixsfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
+
+    test__fixsfdi(-0x1.0000000000001p+63, -0x8000000000000000);
+    test__fixsfdi(-0x1.0000000000000p+63, -0x8000000000000000);
+    test__fixsfdi(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000);
+    test__fixsfdi(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000);
+
+    test__fixsfdi(-0x1.FFFFFFp+62, -0x8000000000000000);
+    test__fixsfdi(-0x1.FFFFFEp+62, -0x7fffff8000000000);
+    test__fixsfdi(-0x1.FFFFFCp+62, -0x7fffff0000000000);
+
+    test__fixsfdi(-2.01, -2);
+    test__fixsfdi(-2.0, -2);
+    test__fixsfdi(-1.99, -1);
+    test__fixsfdi(-1.0, -1);
+    test__fixsfdi(-0.99, 0);
+    test__fixsfdi(-0.5, 0);
+    test__fixsfdi(-math.f32_min, 0);
+    test__fixsfdi(0.0, 0);
+    test__fixsfdi(math.f32_min, 0);
+    test__fixsfdi(0.5, 0);
+    test__fixsfdi(0.99, 0);
+    test__fixsfdi(1.0, 1);
+    test__fixsfdi(1.5, 1);
+    test__fixsfdi(1.99, 1);
+    test__fixsfdi(2.0, 2);
+    test__fixsfdi(2.01, 2);
+
+    test__fixsfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
+    test__fixsfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
+    test__fixsfdi(0x1.FFFFFFp+62, 0x7FFFFFFFFFFFFFFF);
+
+    test__fixsfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFFFFF);
+    test__fixsfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFFFF);
+    test__fixsfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
+    test__fixsfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
+
+    test__fixsfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
+    test__fixsfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
+    test__fixsfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
+
+    test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
+    test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
+
+    test__fixsfdi(math.f64_max, math.maxInt(i64));
+}
std/special/compiler_rt/fixsfsi.zig
@@ -0,0 +1,11 @@
+const fixint = @import("fixint.zig").fixint;
+const builtin = @import("builtin");
+
+pub extern fn __fixsfsi(a: f32) i32 {
+    @setRuntimeSafety(builtin.is_test);
+    return fixint(f32, i32, a);
+}
+
+test "import fixsfsi" {
+    _ = @import("fixsfsi_test.zig");
+}
std/special/compiler_rt/fixsfsi_test.zig
@@ -0,0 +1,76 @@
+const __fixsfsi = @import("fixsfsi.zig").__fixsfsi;
+const std = @import("std");
+const math = std.math;
+const assert = std.debug.assert;
+const warn = std.debug.warn;
+
+fn test__fixsfsi(a: f32, expected: i32) void {
+    const x = __fixsfsi(a);
+    //warn("a={}:{x} x={}:{x} expected={}:{x}:u32({x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u32, expected));
+    assert(x == expected);
+}
+
+test "fixsfsi" {
+    //warn("\n");
+
+    test__fixsfsi(-math.f32_max, math.minInt(i32));
+
+    test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
+    test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
+
+    test__fixsfsi(-0x1.0000000000000p+127, -0x80000000);
+    test__fixsfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
+    test__fixsfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
+
+    test__fixsfsi(-0x1.0000000000001p+63,  -0x80000000);
+    test__fixsfsi(-0x1.0000000000000p+63,  -0x80000000);
+    test__fixsfsi(-0x1.FFFFFFFFFFFFFp+62,  -0x80000000);
+    test__fixsfsi(-0x1.FFFFFFFFFFFFEp+62,  -0x80000000);
+
+    test__fixsfsi(-0x1.FFFFFEp+62, -0x80000000);
+    test__fixsfsi(-0x1.FFFFFCp+62, -0x80000000);
+
+    test__fixsfsi(-0x1.000000p+31, -0x80000000);
+    test__fixsfsi(-0x1.FFFFFFp+30, -0x80000000);
+    test__fixsfsi(-0x1.FFFFFEp+30, -0x7FFFFF80);
+    test__fixsfsi(-0x1.FFFFFCp+30, -0x7FFFFF00);
+
+    test__fixsfsi(-2.01, -2);
+    test__fixsfsi(-2.0, -2);
+    test__fixsfsi(-1.99, -1);
+    test__fixsfsi(-1.0, -1);
+    test__fixsfsi(-0.99, 0);
+    test__fixsfsi(-0.5, 0);
+    test__fixsfsi(-math.f32_min, 0);
+    test__fixsfsi(0.0, 0);
+    test__fixsfsi(math.f32_min, 0);
+    test__fixsfsi(0.5, 0);
+    test__fixsfsi(0.99, 0);
+    test__fixsfsi(1.0, 1);
+    test__fixsfsi(1.5, 1);
+    test__fixsfsi(1.99, 1);
+    test__fixsfsi(2.0, 2);
+    test__fixsfsi(2.01, 2);
+
+    test__fixsfsi(0x1.FFFFFCp+30, 0x7FFFFF00);
+    test__fixsfsi(0x1.FFFFFEp+30, 0x7FFFFF80);
+    test__fixsfsi(0x1.FFFFFFp+30, 0x7FFFFFFF);
+    test__fixsfsi(0x1.000000p+31, 0x7FFFFFFF);
+
+    test__fixsfsi(0x1.FFFFFCp+62, 0x7FFFFFFF);
+    test__fixsfsi(0x1.FFFFFEp+62, 0x7FFFFFFF);
+
+    test__fixsfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
+    test__fixsfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
+    test__fixsfsi(0x1.0000000000000p+63, 0x7FFFFFFF);
+    test__fixsfsi(0x1.0000000000001p+63, 0x7FFFFFFF);
+
+    test__fixsfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
+    test__fixsfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
+    test__fixsfsi(0x1.0000000000000p+127, 0x7FFFFFFF);
+
+    test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
+    test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
+
+    test__fixsfsi(math.f32_max, math.maxInt(i32));
+}
std/special/compiler_rt/fixsfti.zig
@@ -0,0 +1,11 @@
+const fixint = @import("fixint.zig").fixint;
+const builtin = @import("builtin");
+
+pub extern fn __fixsfti(a: f32) i128 {
+    @setRuntimeSafety(builtin.is_test);
+    return fixint(f32, i128, a);
+}
+
+test "import fixsfti" {
+    _ = @import("fixsfti_test.zig");
+}
std/special/compiler_rt/fixsfti_test.zig
@@ -0,0 +1,84 @@
+const __fixsfti = @import("fixsfti.zig").__fixsfti;
+const std = @import("std");
+const math = std.math;
+const assert = std.debug.assert;
+const warn = std.debug.warn;
+
+fn test__fixsfti(a: f32, expected: i128) void {
+    const x = __fixsfti(a);
+    //warn("a={}:{x} x={}:{x} expected={}:{x}:u128({x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u128, expected));
+    assert(x == expected);
+}
+
+test "fixsfti" {
+    //warn("\n");
+
+    test__fixsfti(-math.f32_max, math.minInt(i128));
+
+    test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
+    test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
+
+    test__fixsfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
+    test__fixsfti(-0x1.FFFFFFFFFFFFFp+126, -0x80000000000000000000000000000000);
+    test__fixsfti(-0x1.FFFFFFFFFFFFEp+126, -0x80000000000000000000000000000000);
+    test__fixsfti(-0x1.FFFFFF0000000p+126, -0x80000000000000000000000000000000);
+    test__fixsfti(-0x1.FFFFFE0000000p+126, -0x7FFFFF80000000000000000000000000);
+    test__fixsfti(-0x1.FFFFFC0000000p+126, -0x7FFFFF00000000000000000000000000);
+
+    test__fixsfti(-0x1.0000000000001p+63, -0x8000000000000000);
+    test__fixsfti(-0x1.0000000000000p+63, -0x8000000000000000);
+    test__fixsfti(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000);
+    test__fixsfti(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000);
+
+    test__fixsfti(-0x1.FFFFFFp+62,   -0x8000000000000000);
+    test__fixsfti(-0x1.FFFFFEp+62, -0x7fffff8000000000);
+    test__fixsfti(-0x1.FFFFFCp+62, -0x7fffff0000000000);
+
+    test__fixsfti(-0x1.000000p+31, -0x80000000);
+    test__fixsfti(-0x1.FFFFFFp+30, -0x80000000);
+    test__fixsfti(-0x1.FFFFFEp+30, -0x7FFFFF80);
+    test__fixsfti(-0x1.FFFFFCp+30, -0x7FFFFF00);
+
+    test__fixsfti(-2.01, -2);
+    test__fixsfti(-2.0, -2);
+    test__fixsfti(-1.99, -1);
+    test__fixsfti(-1.0, -1);
+    test__fixsfti(-0.99, 0);
+    test__fixsfti(-0.5, 0);
+    test__fixsfti(-math.f32_min, 0);
+    test__fixsfti(0.0, 0);
+    test__fixsfti(math.f32_min, 0);
+    test__fixsfti(0.5, 0);
+    test__fixsfti(0.99, 0);
+    test__fixsfti(1.0, 1);
+    test__fixsfti(1.5, 1);
+    test__fixsfti(1.99, 1);
+    test__fixsfti(2.0, 2);
+    test__fixsfti(2.01, 2);
+
+    test__fixsfti(0x1.FFFFFCp+30, 0x7FFFFF00);
+    test__fixsfti(0x1.FFFFFEp+30, 0x7FFFFF80);
+    test__fixsfti(0x1.FFFFFFp+30, 0x80000000);
+    test__fixsfti(0x1.000000p+31, 0x80000000);
+
+    test__fixsfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
+    test__fixsfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
+    test__fixsfti(0x1.FFFFFFp+62, 0x8000000000000000);
+
+    test__fixsfti(0x1.FFFFFFFFFFFFEp+62, 0x8000000000000000);
+    test__fixsfti(0x1.FFFFFFFFFFFFFp+62, 0x8000000000000000);
+    test__fixsfti(0x1.0000000000000p+63, 0x8000000000000000);
+    test__fixsfti(0x1.0000000000001p+63, 0x8000000000000000);
+
+    test__fixsfti(0x1.FFFFFC0000000p+126, 0x7FFFFF00000000000000000000000000);
+    test__fixsfti(0x1.FFFFFE0000000p+126, 0x7FFFFF80000000000000000000000000);
+    test__fixsfti(0x1.FFFFFF0000000p+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
+    test__fixsfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
+    test__fixsfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
+    test__fixsfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
+
+    test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
+    test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
+
+    test__fixsfti(math.f32_max, math.maxInt(i128));
+}
std/special/compiler_rt/fixtfdi.zig
@@ -0,0 +1,11 @@
+const fixint = @import("fixint.zig").fixint;
+const builtin = @import("builtin");
+
+pub extern fn __fixtfdi(a: f128) i64 {
+    @setRuntimeSafety(builtin.is_test);
+    return fixint(f128, i64, a);
+}
+
+test "import fixtfdi" {
+    _ = @import("fixtfdi_test.zig");
+}
std/special/compiler_rt/fixtfdi_test.zig
@@ -0,0 +1,76 @@
+const __fixtfdi = @import("fixtfdi.zig").__fixtfdi;
+const std = @import("std");
+const math = std.math;
+const assert = std.debug.assert;
+const warn = std.debug.warn;
+
+fn test__fixtfdi(a: f128, expected: i64) void {
+    const x = __fixtfdi(a);
+    //warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u64, expected));
+    assert(x == expected);
+}
+
+test "fixtfdi" {
+    //warn("\n");
+
+    test__fixtfdi(-math.f128_max, math.minInt(i64));
+
+    test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
+    test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
+
+    test__fixtfdi(-0x1.0000000000000p+127, -0x8000000000000000);
+    test__fixtfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
+    test__fixtfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
+
+    test__fixtfdi(-0x1.0000000000001p+63,  -0x8000000000000000);
+    test__fixtfdi(-0x1.0000000000000p+63,  -0x8000000000000000);
+    test__fixtfdi(-0x1.FFFFFFFFFFFFFp+62,  -0x7FFFFFFFFFFFFC00);
+    test__fixtfdi(-0x1.FFFFFFFFFFFFEp+62,  -0x7FFFFFFFFFFFF800);
+
+    test__fixtfdi(-0x1.FFFFFEp+62, -0x7FFFFF8000000000);
+    test__fixtfdi(-0x1.FFFFFCp+62, -0x7FFFFF0000000000);
+
+    test__fixtfdi(-0x1.000000p+31, -0x80000000);
+    test__fixtfdi(-0x1.FFFFFFp+30, -0x7FFFFFC0);
+    test__fixtfdi(-0x1.FFFFFEp+30, -0x7FFFFF80);
+    test__fixtfdi(-0x1.FFFFFCp+30, -0x7FFFFF00);
+
+    test__fixtfdi(-2.01, -2);
+    test__fixtfdi(-2.0, -2);
+    test__fixtfdi(-1.99, -1);
+    test__fixtfdi(-1.0, -1);
+    test__fixtfdi(-0.99, 0);
+    test__fixtfdi(-0.5, 0);
+    test__fixtfdi(-math.f64_min, 0);
+    test__fixtfdi(0.0, 0);
+    test__fixtfdi(math.f64_min, 0);
+    test__fixtfdi(0.5, 0);
+    test__fixtfdi(0.99, 0);
+    test__fixtfdi(1.0, 1);
+    test__fixtfdi(1.5, 1);
+    test__fixtfdi(1.99, 1);
+    test__fixtfdi(2.0, 2);
+    test__fixtfdi(2.01, 2);
+
+    test__fixtfdi(0x1.FFFFFCp+30, 0x7FFFFF00);
+    test__fixtfdi(0x1.FFFFFEp+30, 0x7FFFFF80);
+    test__fixtfdi(0x1.FFFFFFp+30, 0x7FFFFFC0);
+    test__fixtfdi(0x1.000000p+31, 0x80000000);
+
+    test__fixtfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
+    test__fixtfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
+
+    test__fixtfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
+    test__fixtfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
+    test__fixtfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
+    test__fixtfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
+
+    test__fixtfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
+    test__fixtfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
+    test__fixtfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
+
+    test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
+    test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
+
+    test__fixtfdi(math.f128_max, math.maxInt(i64));
+}
std/special/compiler_rt/fixtfsi.zig
@@ -0,0 +1,11 @@
+const fixint = @import("fixint.zig").fixint;
+const builtin = @import("builtin");
+
+pub extern fn __fixtfsi(a: f128) i32 {
+    @setRuntimeSafety(builtin.is_test);
+    return fixint(f128, i32, a);
+}
+
+test "import fixtfsi" {
+    _ = @import("fixtfsi_test.zig");
+}
std/special/compiler_rt/fixtfsi_test.zig
@@ -0,0 +1,76 @@
+const __fixtfsi = @import("fixtfsi.zig").__fixtfsi;
+const std = @import("std");
+const math = std.math;
+const assert = std.debug.assert;
+const warn = std.debug.warn;
+
+fn test__fixtfsi(a: f128, expected: i32) void {
+    const x = __fixtfsi(a);
+    //warn("a={}:{x} x={}:{x} expected={}:{x}:u32({x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u32, expected));
+    assert(x == expected);
+}
+
+test "fixtfsi" {
+    //warn("\n");
+
+    test__fixtfsi(-math.f128_max, math.minInt(i32));
+
+    test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
+    test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
+
+    test__fixtfsi(-0x1.0000000000000p+127, -0x80000000);
+    test__fixtfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
+    test__fixtfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
+
+    test__fixtfsi(-0x1.0000000000001p+63,  -0x80000000);
+    test__fixtfsi(-0x1.0000000000000p+63,  -0x80000000);
+    test__fixtfsi(-0x1.FFFFFFFFFFFFFp+62,  -0x80000000);
+    test__fixtfsi(-0x1.FFFFFFFFFFFFEp+62,  -0x80000000);
+
+    test__fixtfsi(-0x1.FFFFFEp+62, -0x80000000);
+    test__fixtfsi(-0x1.FFFFFCp+62, -0x80000000);
+
+    test__fixtfsi(-0x1.000000p+31, -0x80000000);
+    test__fixtfsi(-0x1.FFFFFFp+30, -0x7FFFFFC0);
+    test__fixtfsi(-0x1.FFFFFEp+30, -0x7FFFFF80);
+    test__fixtfsi(-0x1.FFFFFCp+30, -0x7FFFFF00);
+
+    test__fixtfsi(-2.01, -2);
+    test__fixtfsi(-2.0, -2);
+    test__fixtfsi(-1.99, -1);
+    test__fixtfsi(-1.0, -1);
+    test__fixtfsi(-0.99, 0);
+    test__fixtfsi(-0.5, 0);
+    test__fixtfsi(-math.f32_min, 0);
+    test__fixtfsi(0.0, 0);
+    test__fixtfsi(math.f32_min, 0);
+    test__fixtfsi(0.5, 0);
+    test__fixtfsi(0.99, 0);
+    test__fixtfsi(1.0, 1);
+    test__fixtfsi(1.5, 1);
+    test__fixtfsi(1.99, 1);
+    test__fixtfsi(2.0, 2);
+    test__fixtfsi(2.01, 2);
+
+    test__fixtfsi(0x1.FFFFFCp+30, 0x7FFFFF00);
+    test__fixtfsi(0x1.FFFFFEp+30, 0x7FFFFF80);
+    test__fixtfsi(0x1.FFFFFFp+30, 0x7FFFFFC0);
+    test__fixtfsi(0x1.000000p+31, 0x7FFFFFFF);
+
+    test__fixtfsi(0x1.FFFFFCp+62, 0x7FFFFFFF);
+    test__fixtfsi(0x1.FFFFFEp+62, 0x7FFFFFFF);
+
+    test__fixtfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
+    test__fixtfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
+    test__fixtfsi(0x1.0000000000000p+63, 0x7FFFFFFF);
+    test__fixtfsi(0x1.0000000000001p+63, 0x7FFFFFFF);
+
+    test__fixtfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
+    test__fixtfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
+    test__fixtfsi(0x1.0000000000000p+127, 0x7FFFFFFF);
+
+    test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
+    test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
+
+    test__fixtfsi(math.f128_max, math.maxInt(i32));
+}
std/special/compiler_rt/fixtfti.zig
@@ -0,0 +1,11 @@
+const fixint = @import("fixint.zig").fixint;
+const builtin = @import("builtin");
+
+pub extern fn __fixtfti(a: f128) i128 {
+    @setRuntimeSafety(builtin.is_test);
+    return fixint(f128, i128, a);
+}
+
+test "import fixtfti" {
+    _ = @import("fixtfti_test.zig");
+}
std/special/compiler_rt/fixtfti_test.zig
@@ -0,0 +1,66 @@
+const __fixtfti = @import("fixtfti.zig").__fixtfti;
+const std = @import("std");
+const math = std.math;
+const assert = std.debug.assert;
+const warn = std.debug.warn;
+
+fn test__fixtfti(a: f128, expected: i128) void {
+    const x = __fixtfti(a);
+    //warn("a={}:{x} x={}:{x} expected={}:{x}:u128({x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u128, expected));
+    assert(x == expected);
+}
+
+test "fixtfti" {
+    //warn("\n");
+
+    test__fixtfti(-math.f128_max, math.minInt(i128));
+
+    test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
+    test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
+
+    test__fixtfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
+    test__fixtfti(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000);
+    test__fixtfti(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000);
+
+    test__fixtfti(-0x1.0000000000001p+63, -0x8000000000000800);
+    test__fixtfti(-0x1.0000000000000p+63, -0x8000000000000000);
+    test__fixtfti(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
+    test__fixtfti(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
+
+    test__fixtfti(-0x1.FFFFFEp+62, -0x7fffff8000000000);
+    test__fixtfti(-0x1.FFFFFCp+62, -0x7fffff0000000000);
+
+    test__fixtfti(-2.01, -2);
+    test__fixtfti(-2.0, -2);
+    test__fixtfti(-1.99, -1);
+    test__fixtfti(-1.0, -1);
+    test__fixtfti(-0.99, 0);
+    test__fixtfti(-0.5, 0);
+    test__fixtfti(-math.f128_min, 0);
+    test__fixtfti(0.0, 0);
+    test__fixtfti(math.f128_min, 0);
+    test__fixtfti(0.5, 0);
+    test__fixtfti(0.99, 0);
+    test__fixtfti(1.0, 1);
+    test__fixtfti(1.5, 1);
+    test__fixtfti(1.99, 1);
+    test__fixtfti(2.0, 2);
+    test__fixtfti(2.01, 2);
+
+    test__fixtfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
+    test__fixtfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
+
+    test__fixtfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
+    test__fixtfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
+    test__fixtfti(0x1.0000000000000p+63, 0x8000000000000000);
+    test__fixtfti(0x1.0000000000001p+63, 0x8000000000000800);
+
+    test__fixtfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);
+    test__fixtfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);
+    test__fixtfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
+
+    test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
+    test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
+
+    test__fixtfti(math.f128_max, math.maxInt(i128));
+}
std/special/compiler_rt/index.zig
@@ -52,6 +52,16 @@ comptime {
     @export("__fixunstfdi", @import("fixunstfdi.zig").__fixunstfdi, linkage);
     @export("__fixunstfti", @import("fixunstfti.zig").__fixunstfti, linkage);
 
+    @export("__fixdfdi", @import("fixdfdi.zig").__fixdfdi, linkage);
+    @export("__fixdfsi", @import("fixdfsi.zig").__fixdfsi, linkage);
+    @export("__fixdfti", @import("fixdfti.zig").__fixdfti, linkage);
+    @export("__fixsfdi", @import("fixsfdi.zig").__fixsfdi, linkage);
+    @export("__fixsfsi", @import("fixsfsi.zig").__fixsfsi, linkage);
+    @export("__fixsfti", @import("fixsfti.zig").__fixsfti, linkage);
+    @export("__fixtfdi", @import("fixtfdi.zig").__fixtfdi, linkage);
+    @export("__fixtfsi", @import("fixtfsi.zig").__fixtfsi, linkage);
+    @export("__fixtfti", @import("fixtfti.zig").__fixtfti, linkage);
+
     @export("__udivmoddi4", @import("udivmoddi4.zig").__udivmoddi4, linkage);
 
     @export("__udivsi3", __udivsi3, linkage);
CMakeLists.txt
@@ -623,6 +623,16 @@ set(ZIG_STD_FILES
     "special/compiler_rt/fixunstfdi.zig"
     "special/compiler_rt/fixunstfsi.zig"
     "special/compiler_rt/fixunstfti.zig"
+    "special/compiler_rt/fixint.zig"
+    "special/compiler_rt/fixdfdi.zig"
+    "special/compiler_rt/fixdfsi.zig"
+    "special/compiler_rt/fixdfti.zig"
+    "special/compiler_rt/fixsfdi.zig"
+    "special/compiler_rt/fixsfsi.zig"
+    "special/compiler_rt/fixsfti.zig"
+    "special/compiler_rt/fixtfdi.zig"
+    "special/compiler_rt/fixtfsi.zig"
+    "special/compiler_rt/fixtfti.zig"
     "special/compiler_rt/floattidf.zig"
     "special/compiler_rt/floattisf.zig"
     "special/compiler_rt/floattitf.zig"