diff --git a/src/value.zig b/src/value.zig index 1075d2bb26..bdf5b9c37c 100644 --- a/src/value.zig +++ b/src/value.zig @@ -937,7 +937,7 @@ pub const Value = extern union { /// Asserts that the value is a float or an integer. pub fn toFloat(self: Value, comptime T: type) T { return switch (self.tag()) { - .float_16 => @panic("TODO soft float"), + .float_16 => @floatCast(T, self.castTag(.float_16).?.data), .float_32 => @floatCast(T, self.castTag(.float_32).?.data), .float_64 => @floatCast(T, self.castTag(.float_64).?.data), .float_128 => @floatCast(T, self.castTag(.float_128).?.data), @@ -1046,11 +1046,10 @@ pub const Value = extern union { pub fn floatCast(self: Value, allocator: *Allocator, dest_ty: Type) !Value { switch (dest_ty.tag()) { .f16 => { - @panic("TODO add __trunctfhf2 to compiler-rt"); - //const res = try Value.Tag.float_16.create(allocator, self.toFloat(f16)); - //if (!self.eql(res)) - // return error.Overflow; - //return res; + const res = try Value.Tag.float_16.create(allocator, self.toFloat(f16)); + if (!self.eql(res, dest_ty)) + return error.Overflow; + return res; }, .f32 => { const res = try Value.Tag.float_32.create(allocator, self.toFloat(f32)); @@ -1901,10 +1900,9 @@ pub const Value = extern union { ) !Value { switch (float_type.tag()) { .f16 => { - @panic("TODO add __trunctfhf2 to compiler-rt"); - //const lhs_val = lhs.toFloat(f16); - //const rhs_val = rhs.toFloat(f16); - //return Value.Tag.float_16.create(arena, lhs_val + rhs_val); + const lhs_val = lhs.toFloat(f16); + const rhs_val = rhs.toFloat(f16); + return Value.Tag.float_16.create(arena, lhs_val + rhs_val); }, .f32 => { const lhs_val = lhs.toFloat(f32); @@ -1933,10 +1931,9 @@ pub const Value = extern union { ) !Value { switch (float_type.tag()) { .f16 => { - @panic("TODO add __trunctfhf2 to compiler-rt"); - //const lhs_val = lhs.toFloat(f16); - //const rhs_val = rhs.toFloat(f16); - //return Value.Tag.float_16.create(arena, lhs_val - rhs_val); + const lhs_val = lhs.toFloat(f16); + const rhs_val = rhs.toFloat(f16); + return Value.Tag.float_16.create(arena, lhs_val - rhs_val); }, .f32 => { const lhs_val = lhs.toFloat(f32); @@ -1965,10 +1962,9 @@ pub const Value = extern union { ) !Value { switch (float_type.tag()) { .f16 => { - @panic("TODO add __trunctfhf2 to compiler-rt"); - //const lhs_val = lhs.toFloat(f16); - //const rhs_val = rhs.toFloat(f16); - //return Value.Tag.float_16.create(arena, lhs_val / rhs_val); + const lhs_val = lhs.toFloat(f16); + const rhs_val = rhs.toFloat(f16); + return Value.Tag.float_16.create(arena, lhs_val / rhs_val); }, .f32 => { const lhs_val = lhs.toFloat(f32); @@ -1997,10 +1993,9 @@ pub const Value = extern union { ) !Value { switch (float_type.tag()) { .f16 => { - @panic("TODO add __trunctfhf2 to compiler-rt"); - //const lhs_val = lhs.toFloat(f16); - //const rhs_val = rhs.toFloat(f16); - //return Value.Tag.float_16.create(arena, lhs_val * rhs_val); + const lhs_val = lhs.toFloat(f16); + const rhs_val = rhs.toFloat(f16); + return Value.Tag.float_16.create(arena, lhs_val * rhs_val); }, .f32 => { const lhs_val = lhs.toFloat(f32); diff --git a/test/behavior.zig b/test/behavior.zig index ee3a789c39..f328db968e 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -13,6 +13,7 @@ test { _ = @import("behavior/atomics.zig"); _ = @import("behavior/sizeof_and_typeof.zig"); _ = @import("behavior/translate_c_macros.zig"); + _ = @import("behavior/widening.zig"); if (builtin.zig_is_stage2) { // When all comptime_memory.zig tests pass, #9646 can be closed. @@ -157,7 +158,7 @@ test { _ = @import("behavior/wasm.zig"); } _ = @import("behavior/while.zig"); - _ = @import("behavior/widening.zig"); + _ = @import("behavior/widening_stage1.zig"); _ = @import("behavior/src.zig"); _ = @import("behavior/translate_c_macros_stage1.zig"); } diff --git a/test/behavior/widening.zig b/test/behavior/widening.zig index 19abf767b8..daa592e64c 100644 --- a/test/behavior/widening.zig +++ b/test/behavior/widening.zig @@ -11,40 +11,3 @@ test "integer widening" { var f: u128 = e; try expect(f == a); } - -test "implicit unsigned integer to signed integer" { - var a: u8 = 250; - var b: i16 = a; - try expect(b == 250); -} - -test "float widening" { - var a: f16 = 12.34; - var b: f32 = a; - var c: f64 = b; - var d: f128 = c; - try expect(a == b); - try expect(b == c); - try expect(c == d); -} - -test "float widening f16 to f128" { - // TODO https://github.com/ziglang/zig/issues/3282 - if (@import("builtin").target.cpu.arch == .aarch64) return error.SkipZigTest; - if (@import("builtin").target.cpu.arch == .powerpc64le) return error.SkipZigTest; - - var x: f16 = 12.34; - var y: f128 = x; - try expect(x == y); -} - -test "cast small unsigned to larger signed" { - try expect(castSmallUnsignedToLargerSigned1(200) == @as(i16, 200)); - try expect(castSmallUnsignedToLargerSigned2(9999) == @as(i64, 9999)); -} -fn castSmallUnsignedToLargerSigned1(x: u8) i16 { - return x; -} -fn castSmallUnsignedToLargerSigned2(x: u16) i64 { - return x; -} diff --git a/test/behavior/widening_stage1.zig b/test/behavior/widening_stage1.zig new file mode 100644 index 0000000000..5b5bc67e45 --- /dev/null +++ b/test/behavior/widening_stage1.zig @@ -0,0 +1,40 @@ +const std = @import("std"); +const expect = std.testing.expect; +const mem = std.mem; + +test "implicit unsigned integer to signed integer" { + var a: u8 = 250; + var b: i16 = a; + try expect(b == 250); +} + +test "float widening" { + var a: f16 = 12.34; + var b: f32 = a; + var c: f64 = b; + var d: f128 = c; + try expect(a == b); + try expect(b == c); + try expect(c == d); +} + +test "float widening f16 to f128" { + // TODO https://github.com/ziglang/zig/issues/3282 + if (@import("builtin").stage2_arch == .aarch64) return error.SkipZigTest; + if (@import("builtin").stage2_arch == .powerpc64le) return error.SkipZigTest; + + var x: f16 = 12.34; + var y: f128 = x; + try expect(x == y); +} + +test "cast small unsigned to larger signed" { + try expect(castSmallUnsignedToLargerSigned1(200) == @as(i16, 200)); + try expect(castSmallUnsignedToLargerSigned2(9999) == @as(i64, 9999)); +} +fn castSmallUnsignedToLargerSigned1(x: u8) i16 { + return x; +} +fn castSmallUnsignedToLargerSigned2(x: u16) i64 { + return x; +}