diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-02-10 22:06:43 -0700 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-02-12 11:18:23 +0100 |
| commit | a024aff9324e827d6595e44f922d87f8ed2dbd0d (patch) | |
| tree | 2c0557a4e57acd198ca57deb7cc387109d96c26d /src/type.zig | |
| parent | 1c23321d03a48558b02c2faf818b82811b8ab11d (diff) | |
| download | zig-a024aff9324e827d6595e44f922d87f8ed2dbd0d.tar.gz zig-a024aff9324e827d6595e44f922d87f8ed2dbd0d.zip | |
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.
Diffstat (limited to 'src/type.zig')
| -rw-r--r-- | src/type.zig | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/src/type.zig b/src/type.zig index 0827b2e2d7..27fdb0abc8 100644 --- a/src/type.zig +++ b/src/type.zig @@ -1877,9 +1877,28 @@ pub const Type = extern union { .f16 => return 2, .f32 => return 4, .f64 => return 8, - .f80 => return 16, .f128 => return 16, - .c_longdouble => return 16, + + .f80 => switch (target.cpu.arch) { + .i386 => return 4, + .x86_64 => return 16, + else => { + var payload: Payload.Bits = .{ + .base = .{ .tag = .int_unsigned }, + .data = 80, + }; + const u80_ty = initPayload(&payload.base); + return abiAlignment(u80_ty, target); + }, + }, + .c_longdouble => switch (CType.longdouble.sizeInBits(target)) { + 16 => return abiAlignment(Type.f16, target), + 32 => return abiAlignment(Type.f32, target), + 64 => return abiAlignment(Type.f64, target), + 80 => return abiAlignment(Type.f80, target), + 128 => return abiAlignment(Type.f128, target), + else => unreachable, + }, .error_set, .error_set_single, @@ -2158,9 +2177,28 @@ pub const Type = extern union { .f16 => return 2, .f32 => return 4, .f64 => return 8, - .f80 => return 16, .f128 => return 16, - .c_longdouble => return 16, + + .f80 => switch (target.cpu.arch) { + .i386 => return 12, + .x86_64 => return 16, + else => { + var payload: Payload.Bits = .{ + .base = .{ .tag = .int_unsigned }, + .data = 80, + }; + const u80_ty = initPayload(&payload.base); + return abiSize(u80_ty, target); + }, + }, + .c_longdouble => switch (CType.longdouble.sizeInBits(target)) { + 16 => return abiSize(Type.f16, target), + 32 => return abiSize(Type.f32, target), + 64 => return abiSize(Type.f64, target), + 80 => return abiSize(Type.f80, target), + 128 => return abiSize(Type.f128, target), + else => unreachable, + }, .error_set, .error_set_single, @@ -2349,7 +2387,7 @@ pub const Type = extern union { .c_ulong => return CType.ulong.sizeInBits(target), .c_longlong => return CType.longlong.sizeInBits(target), .c_ulonglong => return CType.ulonglong.sizeInBits(target), - .c_longdouble => 128, + .c_longdouble => return CType.longdouble.sizeInBits(target), .error_set, .error_set_single, @@ -4772,6 +4810,13 @@ pub const Type = extern union { pub const @"u8" = initTag(.u8); pub const @"u32" = initTag(.u32); pub const @"u64" = initTag(.u64); + + pub const @"f16" = initTag(.f16); + pub const @"f32" = initTag(.f32); + pub const @"f64" = initTag(.f64); + pub const @"f80" = initTag(.f80); + pub const @"f128" = initTag(.f128); + pub const @"bool" = initTag(.bool); pub const @"usize" = initTag(.usize); pub const @"isize" = initTag(.isize); |
