// SPDX-License-Identifier: MIT // Copyright (c) 2015-2020 Zig Contributors // This file is part of [zig](https://ziglang.org/), which is MIT licensed. // The MIT license requires this copyright notice to be included in all copies // and substantial portions of the software. const builtin = @import("builtin"); const std = @import("std"); const maxInt = std.math.maxInt; const significandBits = 23; const exponentBias = 127; const implicitBit = @as(u32, 1) << significandBits; pub fn __floatunsisf(arg: u32) callconv(.C) f32 { @setRuntimeSafety(builtin.is_test); if (arg == 0) return 0.0; // The exponent is the width of abs(a) const exp = @as(u32, 31) - @clz(u32, arg); var mantissa: u32 = undefined; if (exp <= significandBits) { // Shift a into the significand field and clear the implicit bit const shift = @intCast(u5, significandBits - exp); mantissa = @as(u32, arg) << shift ^ implicitBit; } else { const shift = @intCast(u5, exp - significandBits); // Round to the nearest number after truncation mantissa = @as(u32, arg) >> shift ^ implicitBit; // Align to the left and check if the truncated part is halfway over const round = arg << @intCast(u5, 31 - shift); mantissa += @boolToInt(round > 0x80000000); // Tie to even mantissa += mantissa & 1; } // Use the addition instead of a or since we may have a carry from the // mantissa to the exponent var result = mantissa; result += (exp + exponentBias) << significandBits; return @bitCast(f32, result); } pub fn __aeabi_ui2f(arg: u32) callconv(.AAPCS) f32 { @setRuntimeSafety(false); return @call(.{ .modifier = .always_inline }, __floatunsisf, .{arg}); } fn test_one_floatunsisf(a: u32, expected: u32) void { const r = __floatunsisf(a); std.testing.expect(@bitCast(u32, r) == expected); } test "floatunsisf" { // Test the produced bit pattern test_one_floatunsisf(0, 0); test_one_floatunsisf(1, 0x3f800000); test_one_floatunsisf(0x7FFFFFFF, 0x4f000000); test_one_floatunsisf(0x80000000, 0x4f000000); test_one_floatunsisf(0xFFFFFFFF, 0x4f800000); }