Commit 1157ee1307

antlilja <liljaanton2001@gmail.com>
2020-06-17 17:35:45
Improve builtin op support for f128/comptime_float * Add support for fabs, floor, ceil, trunc and round * Add behavior tests
1 parent f595545
Changed files (5)
src/ir.cpp
@@ -13,6 +13,7 @@
 #include "os.hpp"
 #include "range_set.hpp"
 #include "softfloat.hpp"
+#include "softfloat_ext.hpp"
 #include "util.hpp"
 #include "mem_list.hpp"
 #include "all_types.hpp"
@@ -30303,6 +30304,21 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinF
         case BuiltinFnIdSqrt:
             f128M_sqrt(in, out);
             break;
+        case BuiltinFnIdFabs:
+            f128M_abs(in, out);
+            break;
+        case BuiltinFnIdFloor:
+            f128M_roundToInt(in, softfloat_round_min, false, out);
+            break;
+        case BuiltinFnIdCeil:
+            f128M_roundToInt(in, softfloat_round_max, false, out);
+        break;
+        case BuiltinFnIdTrunc:
+            f128M_trunc(in, out);
+            break;
+        case BuiltinFnIdRound: 
+            f128M_roundToInt(in, softfloat_round_near_maxMag, false, out);
+            break;
         case BuiltinFnIdNearbyInt:
         case BuiltinFnIdSin:
         case BuiltinFnIdCos:
@@ -30311,11 +30327,6 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinF
         case BuiltinFnIdLog:
         case BuiltinFnIdLog10:
         case BuiltinFnIdLog2:
-        case BuiltinFnIdFabs:
-        case BuiltinFnIdFloor:
-        case BuiltinFnIdCeil:
-        case BuiltinFnIdTrunc:
-        case BuiltinFnIdRound:
             return ir_add_error(ira, source_instr,
                 buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026",
                     float_op_to_name(fop), buf_ptr(&float_type->name)));
src/softfloat_ext.cpp
@@ -0,0 +1,25 @@
+#include "softfloat_ext.hpp"
+
+extern "C" {
+    #include "softfloat.h"
+}
+
+void f128M_abs(const float128_t *aPtr, float128_t *zPtr) {
+    float128_t zero_float;
+    ui32_to_f128M(0, &zero_float);
+    if (f128M_lt(aPtr, &zero_float)) {
+        f128M_sub(&zero_float, aPtr, zPtr);
+    } else {
+        *zPtr = *aPtr;
+    } 
+}
+
+void f128M_trunc(const float128_t *aPtr, float128_t *zPtr) {
+    float128_t zero_float;
+    ui32_to_f128M(0, &zero_float);
+    if (f128M_lt(aPtr, &zero_float)) {
+        f128M_roundToInt(aPtr, softfloat_round_max, false, zPtr);
+    } else {
+        f128M_roundToInt(aPtr, softfloat_round_min, false, zPtr);
+    } 
+}
\ No newline at end of file
src/softfloat_ext.hpp
@@ -0,0 +1,9 @@
+#ifndef ZIG_SOFTFLOAT_EXT_HPP
+#define ZIG_SOFTFLOAT_EXT_HPP
+
+#include "softfloat_types.h"
+
+void f128M_abs(const float128_t *aPtr, float128_t *zPtr);
+void f128M_trunc(const float128_t *aPtr, float128_t *zPtr);
+
+#endif
\ No newline at end of file
test/stage1/behavior/math.zig
@@ -634,6 +634,128 @@ fn testSqrt(comptime T: type, x: T) void {
     expect(@sqrt(x * x) == x);
 }
 
+test "@fabs" {
+    testFabs(f128, 12.0);
+    comptime testFabs(f128, 12.0);
+    testFabs(f64, 12.0);
+    comptime testFabs(f64, 12.0);
+    testFabs(f32, 12.0);
+    comptime testFabs(f32, 12.0);
+    testFabs(f16, 12.0);
+    comptime testFabs(f16, 12.0);
+
+    const x = 14.0;
+    const y = -x;
+    const z = @fabs(y);
+    comptime expectEqual(x, z);
+}
+
+fn testFabs(comptime T: type, x: T) void {
+    const y = -x;
+    const z = @fabs(y);
+    expectEqual(x, z);
+}
+
+test "@floor" {
+    // FIXME: Generates a floorl function call
+    // testFloor(f128, 12.0);
+    comptime testFloor(f128, 12.0);
+    testFloor(f64, 12.0);
+    comptime testFloor(f64, 12.0);
+    testFloor(f32, 12.0);
+    comptime testFloor(f32, 12.0);
+    testFloor(f16, 12.0);
+    comptime testFloor(f16, 12.0);
+
+    const x = 14.0;
+    const y = x + 0.7;
+    const z = @floor(y);
+    comptime expectEqual(x, z);
+}
+
+fn testFloor(comptime T: type, x: T) void {
+    const y = x + 0.6;
+    const z = @floor(y);
+    expectEqual(x, z);
+}
+
+test "@ceil" {
+    // FIXME: Generates a ceill function call
+    //testCeil(f128, 12.0);
+    comptime testCeil(f128, 12.0);
+    testCeil(f64, 12.0);
+    comptime testCeil(f64, 12.0);
+    testCeil(f32, 12.0);
+    comptime testCeil(f32, 12.0);
+    testCeil(f16, 12.0);
+    comptime testCeil(f16, 12.0);
+
+    const x = 14.0;
+    const y = x - 0.7;
+    const z = @ceil(y);
+    comptime expectEqual(x, z);
+}
+
+fn testCeil(comptime T: type, x: T) void {
+    const y = x - 0.8;
+    const z = @ceil(y);
+    expectEqual(x, z);
+}
+
+test "@trunc" {
+    // FIXME: Generates a truncl function call
+    //testTrunc(f128, 12.0);
+    comptime testTrunc(f128, 12.0);
+    testTrunc(f64, 12.0);
+    comptime testTrunc(f64, 12.0);
+    testTrunc(f32, 12.0);
+    comptime testTrunc(f32, 12.0);
+    testTrunc(f16, 12.0);
+    comptime testTrunc(f16, 12.0);
+
+    const x = 14.0;
+    const y = x + 0.7;
+    const z = @trunc(y);
+    comptime expectEqual(x, z);
+}
+
+fn testTrunc(comptime T: type, x: T) void {
+    {
+        const y = x + 0.8;
+        const z = @trunc(y);
+        expectEqual(x, z);
+    }
+
+    {
+        const y = -x - 0.8;
+        const z = @trunc(y);
+        expectEqual(-x, z);
+    }
+}
+
+test "@round" {
+    // FIXME: Generates a roundl function call
+    //testRound(f128, 12.0);
+    comptime testRound(f128, 12.0);
+    testRound(f64, 12.0);
+    comptime testRound(f64, 12.0);
+    testRound(f32, 12.0);
+    comptime testRound(f32, 12.0);
+    testRound(f16, 12.0);
+    comptime testRound(f16, 12.0);
+
+    const x = 14.0;
+    const y = x + 0.4;
+    const z = @round(y);
+    comptime expectEqual(x, z);
+}
+
+fn testRound(comptime T: type, x: T) void {
+    const y = x - 0.5;
+    const z = @round(y);
+    expectEqual(x, z);
+}
+
 test "comptime_int param and return" {
     const a = comptimeAdd(35361831660712422535336160538497375248, 101752735581729509668353361206450473702);
     expect(a == 137114567242441932203689521744947848950);
CMakeLists.txt
@@ -288,6 +288,7 @@ set(ZIG_SOURCES
     "${CMAKE_SOURCE_DIR}/src/target.cpp"
     "${CMAKE_SOURCE_DIR}/src/tokenizer.cpp"
     "${CMAKE_SOURCE_DIR}/src/util.cpp"
+    "${CMAKE_SOURCE_DIR}/src/softfloat_ext.cpp"
     "${ZIG_SOURCES_MEM_PROFILE}"
 )
 set(OPTIMIZED_C_SOURCES