authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-17 19:07:23-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-17 19:10:15-04:00
loge63d864c1ee343dff13b1e165079e092ee93e273
treefcd642630d288f71025ced2a87b0e73ce7129ac8
parent0d117bb0a993b2a0a290f99255c5bf1bf05f187f

add compiler_rt functions for f128

* __letf2 * __cmptf2 * __getf2 * __unordtf2 * __eqtf2 * __lttf2 * __netf2 * __gttf2

5 files changed, 149 insertions(+), 10 deletions(-)

CMakeLists.txt+1
......@@ -311,6 +311,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG
311311install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_file_template.zig" DESTINATION "${ZIG_STD_DEST}/special")
312312install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")
313313install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special")
314install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/comparetf2.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt")
314315install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixuint.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt")
315316install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixunsdfdi.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt")
316317install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixunsdfsi.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt")
std/special/compiler_rt/comparetf2.zig created+120
......@@ -0,0 +1,120 @@
1// TODO https://github.com/zig-lang/zig/issues/305
2// and then make the return types of some of these functions the enum instead of c_int
3const LE_LESS = c_int(-1);
4const LE_EQUAL = c_int(0);
5const LE_GREATER = c_int(1);
6const LE_UNORDERED = c_int(1);
7
8const rep_t = u128;
9const srep_t = i128;
10
11const typeWidth = rep_t.bit_count;
12const significandBits = 112;
13const exponentBits = (typeWidth - significandBits - 1);
14const signBit = (rep_t(1) << (significandBits + exponentBits));
15const absMask = signBit - 1;
16const implicitBit = rep_t(1) << significandBits;
17const significandMask = implicitBit - 1;
18const exponentMask = absMask ^ significandMask;
19const infRep = exponentMask;
20
21export fn __letf2(a: f128, b: f128) -> c_int {
22 const aInt = @bitCast(rep_t, a);
23 const bInt = @bitCast(rep_t, b);
24
25 const aAbs: rep_t = aInt & absMask;
26 const bAbs: rep_t = bInt & absMask;
27
28 // If either a or b is NaN, they are unordered.
29 if (aAbs > infRep or bAbs > infRep) return LE_UNORDERED;
30
31 // If a and b are both zeros, they are equal.
32 if ((aAbs | bAbs) == 0) return LE_EQUAL;
33
34 // If at least one of a and b is positive, we get the same result comparing
35 // a and b as signed integers as we would with a floating-point compare.
36 return if ((aInt & bInt) >= 0) {
37 if (aInt < bInt) {
38 LE_LESS
39 } else if (aInt == bInt) {
40 LE_EQUAL
41 } else {
42 LE_GREATER
43 }
44 } else {
45 // Otherwise, both are negative, so we need to flip the sense of the
46 // comparison to get the correct result. (This assumes a twos- or ones-
47 // complement integer representation; if integers are represented in a
48 // sign-magnitude representation, then this flip is incorrect).
49 if (aInt > bInt) {
50 LE_LESS
51 } else if (aInt == bInt) {
52 LE_EQUAL
53 } else {
54 LE_GREATER
55 }
56 };
57}
58
59// Alias for libgcc compatibility
60// TODO https://github.com/zig-lang/zig/issues/420
61export fn __cmptf2(a: f128, b: f128) -> c_int { __letf2(a, b) }
62
63// TODO https://github.com/zig-lang/zig/issues/305
64// and then make the return types of some of these functions the enum instead of c_int
65const GE_LESS = c_int(-1);
66const GE_EQUAL = c_int(0);
67const GE_GREATER = c_int(1);
68const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED
69
70export fn __getf2(a: f128, b: f128) -> c_int {
71
72 const aInt = @bitCast(srep_t, a);
73 const bInt = @bitCast(srep_t, b);
74 const aAbs = @bitCast(rep_t, aInt) & absMask;
75 const bAbs = @bitCast(rep_t, bInt) & absMask;
76
77 if (aAbs > infRep or bAbs > infRep) return GE_UNORDERED;
78 if ((aAbs | bAbs) == 0) return GE_EQUAL;
79 return if ((aInt & bInt) >= 0) {
80 if (aInt < bInt) {
81 GE_LESS
82 } else if (aInt == bInt) {
83 GE_EQUAL
84 } else {
85 GE_GREATER
86 }
87 } else {
88 if (aInt > bInt) {
89 GE_LESS
90 } else if (aInt == bInt) {
91 GE_EQUAL
92 } else {
93 GE_GREATER
94 }
95 };
96}
97
98export fn __unordtf2(a: f128, b: f128) -> c_int {
99 const aAbs = @bitCast(rep_t, a) & absMask;
100 const bAbs = @bitCast(rep_t, b) & absMask;
101 return c_int(aAbs > infRep or bAbs > infRep);
102}
103
104// The following are alternative names for the preceding routines.
105
106export fn __eqtf2(a: f128, b: f128) -> c_int {
107 return __letf2(a, b);
108}
109
110export fn __lttf2(a: f128, b: f128) -> c_int {
111 return __letf2(a, b);
112}
113
114export fn __netf2(a: f128, b: f128) -> c_int {
115 return __letf2(a, b);
116}
117
118export fn __gttf2(a: f128, b: f128) -> c_int {
119 return __getf2(a, b);
120}
std/special/compiler_rt/fixunstfdi_test.zig+11-10
......@@ -36,14 +36,15 @@ test "fixunstfdi" {
3636 test__fixunstfdi(-0x1.FFFFFFFFFFFFFp+62, 0);
3737 test__fixunstfdi(-0x1.FFFFFFFFFFFFEp+62, 0);
3838
39 test__fixunstfdi(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF);
40 test__fixunstfdi(0x1.0000000000000002p+63, 0x8000000000000001);
41 test__fixunstfdi(0x1.0000000000000000p+63, 0x8000000000000000);
42 test__fixunstfdi(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF);
43 test__fixunstfdi(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE);
44 test__fixunstfdi(0x1.p+64, 0xFFFFFFFFFFFFFFFF);
45
46 test__fixunstfdi(-0x1.0000000000000000p+63, 0);
47 test__fixunstfdi(-0x1.FFFFFFFFFFFFFFFCp+62, 0);
48 test__fixunstfdi(-0x1.FFFFFFFFFFFFFFF8p+62, 0);
39 // TODO enable these tests when we can parse f128 float literals
40 //test__fixunstfdi(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF);
41 //test__fixunstfdi(0x1.0000000000000002p+63, 0x8000000000000001);
42 //test__fixunstfdi(0x1.0000000000000000p+63, 0x8000000000000000);
43 //test__fixunstfdi(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF);
44 //test__fixunstfdi(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE);
45 //test__fixunstfdi(0x1.p+64, 0xFFFFFFFFFFFFFFFF);
46
47 //test__fixunstfdi(-0x1.0000000000000000p+63, 0);
48 //test__fixunstfdi(-0x1.FFFFFFFFFFFFFFFCp+62, 0);
49 //test__fixunstfdi(-0x1.FFFFFFFFFFFFFFF8p+62, 0);
4950}
std/special/compiler_rt/index.zig+1
......@@ -1,5 +1,6 @@
11// Find all the exported functions.
22comptime {
3 _ = @import("comparetf2.zig");
34 _ = @import("fixunsdfdi.zig");
45 _ = @import("fixunsdfsi.zig");
56 _ = @import("fixunsdfti.zig");
test/cases/math.zig+16
......@@ -312,3 +312,19 @@ test "big number multiplication" {
312312 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016);
313313 }
314314}
315
316test "f128" {
317 test_f128();
318 comptime test_f128();
319}
320
321fn make_f128(x: f128) -> f128 { x }
322
323fn test_f128() {
324 assert(@sizeOf(f128) == 16);
325 assert(make_f128(1.0) == 1.0);
326 assert(make_f128(1.0) != 1.1);
327 assert(make_f128(1.0) > 0.9);
328 assert(make_f128(1.0) >= 0.9);
329 assert(make_f128(1.0) >= 1.0);
330}