make f80 less hacky; lower as u80 on non-x86
Get rid of `std.math.F80Repr`. Instead of trying to match the memory layout of f80, we treat it as a value, same as the other floating point types. The functions `make_f80` and `break_f80` are introduced to compose an f80 value out of its parts, and the inverse operation. stage2 LLVM backend: fix pointer to zero length array tripping LLVM assertion. It now checks for when the element type is a zero-bit type and lowers such thing the same way that pointers to other zero-bit types are lowered. Both stage1 and stage2 LLVM backends are adjusted so that f80 is lowered as x86_fp80 on x86_64 and i386 architectures, and identical to a u80 on others. LLVM constants are lowered in a less hacky way now that #10860 is fixed, by using the expression `(exp << 64) | fraction` using llvm constants. Sema is improved to handle c_longdouble by recursively handling it correctly for whatever the float bit width is. In both stage1 and stage2.
This commit is contained in:
committed by
Jakub Konka
parent
1c23321d03
commit
a024aff932
@@ -42,19 +42,11 @@ pub const f128_max = @bitCast(f128, @as(u128, 0x7FFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
pub const f128_epsilon = @bitCast(f128, @as(u128, 0x3F8F0000000000000000000000000000));
|
||||
pub const f128_toint = 1.0 / f128_epsilon;
|
||||
|
||||
pub const F80Repr = if (@import("builtin").cpu.arch.endian() == .Little) extern struct {
|
||||
fraction: u64 align(@alignOf(f80)),
|
||||
exp: u16,
|
||||
} else extern struct {
|
||||
exp: u16 align(@alignOf(f80)),
|
||||
fraction: u64,
|
||||
};
|
||||
|
||||
// float.h details
|
||||
pub const f80_true_min = @ptrCast(*const f80, &F80Repr{ .fraction = 1, .exp = 0 }).*;
|
||||
pub const f80_min = @ptrCast(*const f80, &F80Repr{ .fraction = 0x8000000000000000, .exp = 1 }).*;
|
||||
pub const f80_max = @ptrCast(*const f80, &F80Repr{ .fraction = 0xFFFFFFFFFFFFFFFF, .exp = 0x7FFE }).*;
|
||||
pub const f80_epsilon = @ptrCast(*const f80, &F80Repr{ .fraction = 0x8000000000000000, .exp = 0x3FC0 }).*;
|
||||
pub const f80_true_min = make_f80(.{ .fraction = 1, .exp = 0 });
|
||||
pub const f80_min = make_f80(.{ .fraction = 0x8000000000000000, .exp = 1 });
|
||||
pub const f80_max = make_f80(.{ .fraction = 0xFFFFFFFFFFFFFFFF, .exp = 0x7FFE });
|
||||
pub const f80_epsilon = make_f80(.{ .fraction = 0x8000000000000000, .exp = 0x3FC0 });
|
||||
pub const f80_toint = 1.0 / f80_epsilon;
|
||||
|
||||
pub const f64_true_min = 4.94065645841246544177e-324;
|
||||
@@ -104,9 +96,9 @@ pub const qnan_f64 = @bitCast(f64, qnan_u64);
|
||||
pub const inf_u64 = @as(u64, 0x7FF << 52);
|
||||
pub const inf_f64 = @bitCast(f64, inf_u64);
|
||||
|
||||
pub const inf_f80 = @ptrCast(*const f80, &F80Repr{ .fraction = 0x8000000000000000, .exp = 0x7fff }).*;
|
||||
pub const nan_f80 = @ptrCast(*const f80, &F80Repr{ .fraction = 0xA000000000000000, .exp = 0x7fff }).*;
|
||||
pub const qnan_f80 = @ptrCast(*const f80, &F80Repr{ .fraction = 0xC000000000000000, .exp = 0x7fff }).*;
|
||||
pub const inf_f80 = make_f80(F80{ .fraction = 0x8000000000000000, .exp = 0x7fff });
|
||||
pub const nan_f80 = make_f80(F80{ .fraction = 0xA000000000000000, .exp = 0x7fff });
|
||||
pub const qnan_f80 = make_f80(F80{ .fraction = 0xC000000000000000, .exp = 0x7fff });
|
||||
|
||||
pub const nan_u128 = @as(u128, 0x7fff0000000000000000000000000001);
|
||||
pub const nan_f128 = @bitCast(f128, nan_u128);
|
||||
@@ -1501,3 +1493,21 @@ test "boolMask" {
|
||||
pub fn comptimeMod(num: anytype, denom: comptime_int) IntFittingRange(0, denom - 1) {
|
||||
return @intCast(IntFittingRange(0, denom - 1), @mod(num, denom));
|
||||
}
|
||||
|
||||
pub const F80 = struct {
|
||||
fraction: u64,
|
||||
exp: u16,
|
||||
};
|
||||
|
||||
pub fn make_f80(repr: F80) f80 {
|
||||
const int = (@as(u80, repr.exp) << 64) | repr.fraction;
|
||||
return @bitCast(f80, int);
|
||||
}
|
||||
|
||||
pub fn break_f80(x: f80) F80 {
|
||||
const int = @bitCast(u80, x);
|
||||
return .{
|
||||
.fraction = @truncate(u64, int),
|
||||
.exp = @truncate(u16, int >> 64),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user