| ... | ... | @@ -6,10 +6,28 @@ const std = @import("std"); |
| 6 | 6 | const builtin = @import("builtin"); |
| 7 | 7 | const compiler_rt = @import("../compiler_rt.zig"); |
| 8 | 8 | |
| 9 | pub extern fn __addsf3(a: f32, b: f32) f32 { |
| 10 | return addXf3(f32, a, b); |
| 11 | } |
| 12 | |
| 13 | pub extern fn __adddf3(a: f64, b: f64) f64 { |
| 14 | return addXf3(f64, a, b); |
| 15 | } |
| 16 | |
| 9 | 17 | pub extern fn __addtf3(a: f128, b: f128) f128 { |
| 10 | 18 | return addXf3(f128, a, b); |
| 11 | 19 | } |
| 12 | 20 | |
| 21 | pub extern fn __subsf3(a: f32, b: f32) f32 { |
| 22 | const neg_b = @bitCast(f32, @bitCast(u32, b) ^ (u32(1) << 31)); |
| 23 | return addXf3(f32, a, neg_b); |
| 24 | } |
| 25 | |
| 26 | pub extern fn __subdf3(a: f64, b: f64) f64 { |
| 27 | const neg_b = @bitCast(f64, @bitCast(u64, b) ^ (u64(1) << 63)); |
| 28 | return addXf3(f64, a, neg_b); |
| 29 | } |
| 30 | |
| 13 | 31 | pub extern fn __subtf3(a: f128, b: f128) f128 { |
| 14 | 32 | const neg_b = @bitCast(f128, @bitCast(u128, b) ^ (u128(1) << 127)); |
| 15 | 33 | return addXf3(f128, a, neg_b); |
| ... | ... | @@ -17,16 +35,18 @@ pub extern fn __subtf3(a: f128, b: f128) f128 { |
| 17 | 35 | |
| 18 | 36 | inline fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { |
| 19 | 37 | const Z = @IntType(false, T.bit_count); |
| 38 | const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1)); |
| 20 | 39 | const significandBits = std.math.floatMantissaBits(T); |
| 21 | 40 | const implicitBit = Z(1) << significandBits; |
| 22 | 41 | |
| 23 | 42 | const shift = @clz(significand.*) - @clz(implicitBit); |
| 24 | | significand.* <<= @intCast(u7, shift); |
| 43 | significand.* <<= @intCast(S, shift); |
| 25 | 44 | return 1 - shift; |
| 26 | 45 | } |
| 27 | 46 | |
| 28 | 47 | inline fn addXf3(comptime T: type, a: T, b: T) T { |
| 29 | 48 | const Z = @IntType(false, T.bit_count); |
| 49 | const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1)); |
| 30 | 50 | |
| 31 | 51 | const typeWidth = T.bit_count; |
| 32 | 52 | const significandBits = std.math.floatMantissaBits(T); |
| ... | ... | @@ -126,8 +146,8 @@ inline fn addXf3(comptime T: type, a: T, b: T) T { |
| 126 | 146 | const @"align" = @intCast(Z, aExponent - bExponent); |
| 127 | 147 | if (@"align" != 0) { |
| 128 | 148 | if (@"align" < typeWidth) { |
| 129 | | const sticky = if (bSignificand << @intCast(u7, typeWidth - @"align") != 0) Z(1) else 0; |
| 130 | | bSignificand = (bSignificand >> @truncate(u7, @"align")) | sticky; |
| 149 | const sticky = if (bSignificand << @intCast(S, typeWidth - @"align") != 0) Z(1) else 0; |
| 150 | bSignificand = (bSignificand >> @truncate(S, @"align")) | sticky; |
| 131 | 151 | } else { |
| 132 | 152 | bSignificand = 1; // sticky; b is known to be non-zero. |
| 133 | 153 | } |
| ... | ... | @@ -141,7 +161,7 @@ inline fn addXf3(comptime T: type, a: T, b: T) T { |
| 141 | 161 | // and adjust the exponent: |
| 142 | 162 | if (aSignificand < implicitBit << 3) { |
| 143 | 163 | const shift = @intCast(i32, @clz(aSignificand)) - @intCast(i32, @clz(implicitBit << 3)); |
| 144 | | aSignificand <<= @intCast(u7, shift); |
| 164 | aSignificand <<= @intCast(S, shift); |
| 145 | 165 | aExponent -= shift; |
| 146 | 166 | } |
| 147 | 167 | } else { // addition |
| ... | ... | @@ -163,8 +183,8 @@ inline fn addXf3(comptime T: type, a: T, b: T) T { |
| 163 | 183 | // Result is denormal before rounding; the exponent is zero and we |
| 164 | 184 | // need to shift the significand. |
| 165 | 185 | const shift = @intCast(Z, 1 - aExponent); |
| 166 | | const sticky = if (aSignificand << @intCast(u7, typeWidth - shift) != 0) Z(1) else 0; |
| 167 | | aSignificand = aSignificand >> @intCast(u7, shift | sticky); |
| 186 | const sticky = if (aSignificand << @intCast(S, typeWidth - shift) != 0) Z(1) else 0; |
| 187 | aSignificand = aSignificand >> @intCast(S, shift | sticky); |
| 168 | 188 | aExponent = 0; |
| 169 | 189 | } |
| 170 | 190 | |