From 166db1a3ed7eca9b04b0626eaea8de0634ab9667 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 10 Feb 2022 17:36:31 -0700 Subject: stage1: fix f80 size and alignment on x86 and arm * F80Repr extern struct needs no explicit padding; let's match the target padding. * stage2: fix lowering of f80 constants. * stage1: decide ABI size and alignment of f80 based on alignment of u64. x86 has alignof u64 equal to 4 but arm has it as 8. * stage2: fix Value.floatReadFromMemory to use F80Repr --- src/value.zig | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'src/value.zig') diff --git a/src/value.zig b/src/value.zig index 33a75e08bb..aefb0a3e20 100644 --- a/src/value.zig +++ b/src/value.zig @@ -1122,10 +1122,32 @@ pub const Value = extern union { fn floatReadFromMemory(comptime F: type, target: Target, buffer: []const u8) F { if (F == f80) { - // TODO: use std.math.F80Repr? - const int = std.mem.readInt(u128, buffer[0..16], target.cpu.arch.endian()); - // TODO shouldn't this be a bitcast from u80 to f80 instead of u128 to f80? - return @bitCast(F, int); + switch (target.cpu.arch.endian()) { + .Little => { + const TargetF80Repr = extern struct { + fraction: u64, + exp: u16, + }; + const target_repr = @ptrCast(*align(1) const TargetF80Repr, buffer.ptr); + const real_repr: std.math.F80Repr = .{ + .fraction = target_repr.fraction, + .exp = target_repr.exp, + }; + return @ptrCast(*const f80, &real_repr).*; + }, + .Big => { + const TargetF80Repr = extern struct { + exp: u16, + fraction: u64, + }; + const target_repr = @ptrCast(*align(1) const TargetF80Repr, buffer.ptr); + const real_repr: std.math.F80Repr = .{ + .fraction = target_repr.fraction, + .exp = target_repr.exp, + }; + return @ptrCast(*const f80, &real_repr).*; + }, + } } const Int = @Type(.{ .Int = .{ .signedness = .unsigned, -- cgit v1.2.3