Commit be71195bba

Andrew Kelley <andrew@ziglang.org>
2021-09-22 02:02:15
stage2: enable f16 math
There was panic that said TODO add __trunctfhf2 to compiler-rt, but I checked and that function has been in compiler-rt since April.
1 parent 01f20c7
Changed files (4)
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);
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;
-}
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;
+}
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");
     }