| author | |
| committer | |
| log | e63d864c1ee343dff13b1e165079e092ee93e273 |
| tree | fcd642630d288f71025ced2a87b0e73ce7129ac8 |
| parent | 0d117bb0a993b2a0a290f99255c5bf1bf05f187f |
* __letf2
* __cmptf2
* __getf2
* __unordtf2
* __eqtf2
* __lttf2
* __netf2
* __gttf25 files changed, 149 insertions(+), 10 deletions(-)
CMakeLists.txt+1| ... | @@ -311,6 +311,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG | ... | @@ -311,6 +311,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG |
| 311 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_file_template.zig" DESTINATION "${ZIG_STD_DEST}/special") | 311 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_file_template.zig" DESTINATION "${ZIG_STD_DEST}/special") |
| 312 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_runner.zig" DESTINATION "${ZIG_STD_DEST}/special") | 312 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_runner.zig" DESTINATION "${ZIG_STD_DEST}/special") |
| 313 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special") | 313 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special") |
| 314 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/comparetf2.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | ||
| 314 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixuint.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | 315 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixuint.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") |
| 315 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixunsdfdi.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | 316 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixunsdfdi.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") |
| 316 | install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt/fixunsdfsi.zig" DESTINATION "${ZIG_STD_DEST}/special/compiler_rt") | 317 | install(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 | ||
| 3 | const LE_LESS = c_int(-1); | ||
| 4 | const LE_EQUAL = c_int(0); | ||
| 5 | const LE_GREATER = c_int(1); | ||
| 6 | const LE_UNORDERED = c_int(1); | ||
| 7 | |||
| 8 | const rep_t = u128; | ||
| 9 | const srep_t = i128; | ||
| 10 | |||
| 11 | const typeWidth = rep_t.bit_count; | ||
| 12 | const significandBits = 112; | ||
| 13 | const exponentBits = (typeWidth - significandBits - 1); | ||
| 14 | const signBit = (rep_t(1) << (significandBits + exponentBits)); | ||
| 15 | const absMask = signBit - 1; | ||
| 16 | const implicitBit = rep_t(1) << significandBits; | ||
| 17 | const significandMask = implicitBit - 1; | ||
| 18 | const exponentMask = absMask ^ significandMask; | ||
| 19 | const infRep = exponentMask; | ||
| 20 | |||
| 21 | export 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 | ||
| 61 | export 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 | ||
| 65 | const GE_LESS = c_int(-1); | ||
| 66 | const GE_EQUAL = c_int(0); | ||
| 67 | const GE_GREATER = c_int(1); | ||
| 68 | const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED | ||
| 69 | |||
| 70 | export 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 | |||
| 98 | export 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 | |||
| 106 | export fn __eqtf2(a: f128, b: f128) -> c_int { | ||
| 107 | return __letf2(a, b); | ||
| 108 | } | ||
| 109 | |||
| 110 | export fn __lttf2(a: f128, b: f128) -> c_int { | ||
| 111 | return __letf2(a, b); | ||
| 112 | } | ||
| 113 | |||
| 114 | export fn __netf2(a: f128, b: f128) -> c_int { | ||
| 115 | return __letf2(a, b); | ||
| 116 | } | ||
| 117 | |||
| 118 | export 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" { | ... | @@ -36,14 +36,15 @@ test "fixunstfdi" { |
| 36 | test__fixunstfdi(-0x1.FFFFFFFFFFFFFp+62, 0); | 36 | test__fixunstfdi(-0x1.FFFFFFFFFFFFFp+62, 0); |
| 37 | test__fixunstfdi(-0x1.FFFFFFFFFFFFEp+62, 0); | 37 | test__fixunstfdi(-0x1.FFFFFFFFFFFFEp+62, 0); |
| 38 | 38 | ||
| 39 | test__fixunstfdi(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF); | 39 | // TODO enable these tests when we can parse f128 float literals |
| 40 | test__fixunstfdi(0x1.0000000000000002p+63, 0x8000000000000001); | 40 | //test__fixunstfdi(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF); |
| 41 | test__fixunstfdi(0x1.0000000000000000p+63, 0x8000000000000000); | 41 | //test__fixunstfdi(0x1.0000000000000002p+63, 0x8000000000000001); |
| 42 | test__fixunstfdi(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF); | 42 | //test__fixunstfdi(0x1.0000000000000000p+63, 0x8000000000000000); |
| 43 | test__fixunstfdi(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE); | 43 | //test__fixunstfdi(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF); |
| 44 | test__fixunstfdi(0x1.p+64, 0xFFFFFFFFFFFFFFFF); | 44 | //test__fixunstfdi(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE); |
| 45 | 45 | //test__fixunstfdi(0x1.p+64, 0xFFFFFFFFFFFFFFFF); | |
| 46 | test__fixunstfdi(-0x1.0000000000000000p+63, 0); | 46 | |
| 47 | test__fixunstfdi(-0x1.FFFFFFFFFFFFFFFCp+62, 0); | 47 | //test__fixunstfdi(-0x1.0000000000000000p+63, 0); |
| 48 | test__fixunstfdi(-0x1.FFFFFFFFFFFFFFF8p+62, 0); | 48 | //test__fixunstfdi(-0x1.FFFFFFFFFFFFFFFCp+62, 0); |
| 49 | //test__fixunstfdi(-0x1.FFFFFFFFFFFFFFF8p+62, 0); | ||
| 49 | } | 50 | } |
std/special/compiler_rt/index.zig+1| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | // Find all the exported functions. | 1 | // Find all the exported functions. |
| 2 | comptime { | 2 | comptime { |
| 3 | _ = @import("comparetf2.zig"); | ||
| 3 | _ = @import("fixunsdfdi.zig"); | 4 | _ = @import("fixunsdfdi.zig"); |
| 4 | _ = @import("fixunsdfsi.zig"); | 5 | _ = @import("fixunsdfsi.zig"); |
| 5 | _ = @import("fixunsdfti.zig"); | 6 | _ = @import("fixunsdfti.zig"); |
test/cases/math.zig+16| ... | @@ -312,3 +312,19 @@ test "big number multiplication" { | ... | @@ -312,3 +312,19 @@ test "big number multiplication" { |
| 312 | 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016); | 312 | 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016); |
| 313 | } | 313 | } |
| 314 | } | 314 | } |
| 315 | |||
| 316 | test "f128" { | ||
| 317 | test_f128(); | ||
| 318 | comptime test_f128(); | ||
| 319 | } | ||
| 320 | |||
| 321 | fn make_f128(x: f128) -> f128 { x } | ||
| 322 | |||
| 323 | fn 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 | } |