From c8ded2f9c940be2d59f5e9dc7d66374b67afba63 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 20 Oct 2021 16:41:08 -0700 Subject: stage2: implement big int to float conversion --- src/value.zig | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'src/value.zig') diff --git a/src/value.zig b/src/value.zig index fce5e8afb1..7c24cdab81 100644 --- a/src/value.zig +++ b/src/value.zig @@ -1853,17 +1853,26 @@ pub const Value = extern union { }; } - pub fn intToFloat(val: Value, allocator: *Allocator, dest_ty: Type, target: Target) !Value { + pub fn intToFloat(val: Value, arena: *Allocator, dest_ty: Type, target: Target) !Value { switch (val.tag()) { .undef, .zero, .one => return val, .the_only_possible_value => return Value.initTag(.zero), // for i0, u0 .int_u64 => { - return intToFloatInner(val.castTag(.int_u64).?.data, allocator, dest_ty, target); + return intToFloatInner(val.castTag(.int_u64).?.data, arena, dest_ty, target); }, .int_i64 => { - return intToFloatInner(val.castTag(.int_i64).?.data, allocator, dest_ty, target); + return intToFloatInner(val.castTag(.int_i64).?.data, arena, dest_ty, target); + }, + .int_big_positive => { + const limbs = val.castTag(.int_big_positive).?.data; + const float = bigIntToFloat(limbs, true); + return floatToValue(float, arena, dest_ty, target); + }, + .int_big_negative => { + const limbs = val.castTag(.int_big_negative).?.data; + const float = bigIntToFloat(limbs, false); + return floatToValue(float, arena, dest_ty, target); }, - .int_big_positive, .int_big_negative => @panic("big int to float"), else => unreachable, } } @@ -1878,6 +1887,16 @@ pub const Value = extern union { } } + fn floatToValue(float: f128, arena: *Allocator, dest_ty: Type, target: Target) !Value { + switch (dest_ty.floatBits(target)) { + 16 => return Value.Tag.float_16.create(arena, @floatCast(f16, float)), + 32 => return Value.Tag.float_32.create(arena, @floatCast(f32, float)), + 64 => return Value.Tag.float_64.create(arena, @floatCast(f64, float)), + 128 => return Value.Tag.float_128.create(arena, float), + else => unreachable, + } + } + /// Supports both floats and ints; handles undefined. pub fn numberAddWrap( lhs: Value, -- cgit v1.2.3