authorgravatar for liljaanton2001@gmail.comantlilja <liljaanton2001@gmail.com> 2020-06-17 17:35:45+02:00
committergravatar for liljaanton2001@gmail.comantlilja <liljaanton2001@gmail.com> 2020-06-17 17:35:45+02:00
log1157ee130732449811294d70021aaafa588d3048
tree442f27ca03ff3e1240b1cf9a572343d8c0a6f11e
parentf595545c10a35b85879edfa3c002ce308ffeb6c2

Improve builtin op support for f128/comptime_float

* Add support for fabs, floor, ceil, trunc and round * Add behavior tests

5 files changed, 173 insertions(+), 5 deletions(-)

CMakeLists.txt+1
...@@ -288,6 +288,7 @@ set(ZIG_SOURCES...@@ -288,6 +288,7 @@ set(ZIG_SOURCES
288 "${CMAKE_SOURCE_DIR}/src/target.cpp"288 "${CMAKE_SOURCE_DIR}/src/target.cpp"
289 "${CMAKE_SOURCE_DIR}/src/tokenizer.cpp"289 "${CMAKE_SOURCE_DIR}/src/tokenizer.cpp"
290 "${CMAKE_SOURCE_DIR}/src/util.cpp"290 "${CMAKE_SOURCE_DIR}/src/util.cpp"
291 "${CMAKE_SOURCE_DIR}/src/softfloat_ext.cpp"
291 "${ZIG_SOURCES_MEM_PROFILE}"292 "${ZIG_SOURCES_MEM_PROFILE}"
292)293)
293set(OPTIMIZED_C_SOURCES294set(OPTIMIZED_C_SOURCES
src/ir.cpp+16-5
...@@ -13,6 +13,7 @@...@@ -13,6 +13,7 @@
13#include "os.hpp"13#include "os.hpp"
14#include "range_set.hpp"14#include "range_set.hpp"
15#include "softfloat.hpp"15#include "softfloat.hpp"
16#include "softfloat_ext.hpp"
16#include "util.hpp"17#include "util.hpp"
17#include "mem_list.hpp"18#include "mem_list.hpp"
18#include "all_types.hpp"19#include "all_types.hpp"
...@@ -30303,6 +30304,21 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinF...@@ -30303,6 +30304,21 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinF
30303 case BuiltinFnIdSqrt:30304 case BuiltinFnIdSqrt:
30304 f128M_sqrt(in, out);30305 f128M_sqrt(in, out);
30305 break;30306 break;
30307 case BuiltinFnIdFabs:
30308 f128M_abs(in, out);
30309 break;
30310 case BuiltinFnIdFloor:
30311 f128M_roundToInt(in, softfloat_round_min, false, out);
30312 break;
30313 case BuiltinFnIdCeil:
30314 f128M_roundToInt(in, softfloat_round_max, false, out);
30315 break;
30316 case BuiltinFnIdTrunc:
30317 f128M_trunc(in, out);
30318 break;
30319 case BuiltinFnIdRound:
30320 f128M_roundToInt(in, softfloat_round_near_maxMag, false, out);
30321 break;
30306 case BuiltinFnIdNearbyInt:30322 case BuiltinFnIdNearbyInt:
30307 case BuiltinFnIdSin:30323 case BuiltinFnIdSin:
30308 case BuiltinFnIdCos:30324 case BuiltinFnIdCos:
...@@ -30311,11 +30327,6 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinF...@@ -30311,11 +30327,6 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinF
30311 case BuiltinFnIdLog:30327 case BuiltinFnIdLog:
30312 case BuiltinFnIdLog10:30328 case BuiltinFnIdLog10:
30313 case BuiltinFnIdLog2:30329 case BuiltinFnIdLog2:
30314 case BuiltinFnIdFabs:
30315 case BuiltinFnIdFloor:
30316 case BuiltinFnIdCeil:
30317 case BuiltinFnIdTrunc:
30318 case BuiltinFnIdRound:
30319 return ir_add_error(ira, source_instr,30330 return ir_add_error(ira, source_instr,
30320 buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026",30331 buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026",
30321 float_op_to_name(fop), buf_ptr(&float_type->name)));30332 float_op_to_name(fop), buf_ptr(&float_type->name)));
src/softfloat_ext.cpp created+25
...@@ -0,0 +1,25 @@
1#include "softfloat_ext.hpp"
2
3extern "C" {
4 #include "softfloat.h"
5}
6
7void f128M_abs(const float128_t *aPtr, float128_t *zPtr) {
8 float128_t zero_float;
9 ui32_to_f128M(0, &zero_float);
10 if (f128M_lt(aPtr, &zero_float)) {
11 f128M_sub(&zero_float, aPtr, zPtr);
12 } else {
13 *zPtr = *aPtr;
14 }
15}
16
17void f128M_trunc(const float128_t *aPtr, float128_t *zPtr) {
18 float128_t zero_float;
19 ui32_to_f128M(0, &zero_float);
20 if (f128M_lt(aPtr, &zero_float)) {
21 f128M_roundToInt(aPtr, softfloat_round_max, false, zPtr);
22 } else {
23 f128M_roundToInt(aPtr, softfloat_round_min, false, zPtr);
24 }
25}
\ No newline at end of file
src/softfloat_ext.hpp created+9
...@@ -0,0 +1,9 @@
1#ifndef ZIG_SOFTFLOAT_EXT_HPP
2#define ZIG_SOFTFLOAT_EXT_HPP
3
4#include "softfloat_types.h"
5
6void f128M_abs(const float128_t *aPtr, float128_t *zPtr);
7void f128M_trunc(const float128_t *aPtr, float128_t *zPtr);
8
9#endif
\ No newline at end of file
test/stage1/behavior/math.zig+122
...@@ -634,6 +634,128 @@ fn testSqrt(comptime T: type, x: T) void {...@@ -634,6 +634,128 @@ fn testSqrt(comptime T: type, x: T) void {
634 expect(@sqrt(x * x) == x);634 expect(@sqrt(x * x) == x);
635}635}
636636
637test "@fabs" {
638 testFabs(f128, 12.0);
639 comptime testFabs(f128, 12.0);
640 testFabs(f64, 12.0);
641 comptime testFabs(f64, 12.0);
642 testFabs(f32, 12.0);
643 comptime testFabs(f32, 12.0);
644 testFabs(f16, 12.0);
645 comptime testFabs(f16, 12.0);
646
647 const x = 14.0;
648 const y = -x;
649 const z = @fabs(y);
650 comptime expectEqual(x, z);
651}
652
653fn testFabs(comptime T: type, x: T) void {
654 const y = -x;
655 const z = @fabs(y);
656 expectEqual(x, z);
657}
658
659test "@floor" {
660 // FIXME: Generates a floorl function call
661 // testFloor(f128, 12.0);
662 comptime testFloor(f128, 12.0);
663 testFloor(f64, 12.0);
664 comptime testFloor(f64, 12.0);
665 testFloor(f32, 12.0);
666 comptime testFloor(f32, 12.0);
667 testFloor(f16, 12.0);
668 comptime testFloor(f16, 12.0);
669
670 const x = 14.0;
671 const y = x + 0.7;
672 const z = @floor(y);
673 comptime expectEqual(x, z);
674}
675
676fn testFloor(comptime T: type, x: T) void {
677 const y = x + 0.6;
678 const z = @floor(y);
679 expectEqual(x, z);
680}
681
682test "@ceil" {
683 // FIXME: Generates a ceill function call
684 //testCeil(f128, 12.0);
685 comptime testCeil(f128, 12.0);
686 testCeil(f64, 12.0);
687 comptime testCeil(f64, 12.0);
688 testCeil(f32, 12.0);
689 comptime testCeil(f32, 12.0);
690 testCeil(f16, 12.0);
691 comptime testCeil(f16, 12.0);
692
693 const x = 14.0;
694 const y = x - 0.7;
695 const z = @ceil(y);
696 comptime expectEqual(x, z);
697}
698
699fn testCeil(comptime T: type, x: T) void {
700 const y = x - 0.8;
701 const z = @ceil(y);
702 expectEqual(x, z);
703}
704
705test "@trunc" {
706 // FIXME: Generates a truncl function call
707 //testTrunc(f128, 12.0);
708 comptime testTrunc(f128, 12.0);
709 testTrunc(f64, 12.0);
710 comptime testTrunc(f64, 12.0);
711 testTrunc(f32, 12.0);
712 comptime testTrunc(f32, 12.0);
713 testTrunc(f16, 12.0);
714 comptime testTrunc(f16, 12.0);
715
716 const x = 14.0;
717 const y = x + 0.7;
718 const z = @trunc(y);
719 comptime expectEqual(x, z);
720}
721
722fn testTrunc(comptime T: type, x: T) void {
723 {
724 const y = x + 0.8;
725 const z = @trunc(y);
726 expectEqual(x, z);
727 }
728
729 {
730 const y = -x - 0.8;
731 const z = @trunc(y);
732 expectEqual(-x, z);
733 }
734}
735
736test "@round" {
737 // FIXME: Generates a roundl function call
738 //testRound(f128, 12.0);
739 comptime testRound(f128, 12.0);
740 testRound(f64, 12.0);
741 comptime testRound(f64, 12.0);
742 testRound(f32, 12.0);
743 comptime testRound(f32, 12.0);
744 testRound(f16, 12.0);
745 comptime testRound(f16, 12.0);
746
747 const x = 14.0;
748 const y = x + 0.4;
749 const z = @round(y);
750 comptime expectEqual(x, z);
751}
752
753fn testRound(comptime T: type, x: T) void {
754 const y = x - 0.5;
755 const z = @round(y);
756 expectEqual(x, z);
757}
758
637test "comptime_int param and return" {759test "comptime_int param and return" {
638 const a = comptimeAdd(35361831660712422535336160538497375248, 101752735581729509668353361206450473702);760 const a = comptimeAdd(35361831660712422535336160538497375248, 101752735581729509668353361206450473702);
639 expect(a == 137114567242441932203689521744947848950);761 expect(a == 137114567242441932203689521744947848950);