| author | |
| committer | |
| log | 96d86e346517b1917165b6f817b2147524a9a0b5 |
| tree | 8567ee8f6fb90d402d19762dffbb9503d5064237 |
| parent | f5540778b56636cffd89f794c6b1a9266d7d36f8 |
5 files changed, 37 insertions(+), 25 deletions(-)
lib/std/special/compiler_rt/README.md+17-17| ... | @@ -152,53 +152,53 @@ Bugs should be solved by trying to duplicate the bug upstream, if possible. | ... | @@ -152,53 +152,53 @@ Bugs should be solved by trying to duplicate the bug upstream, if possible. |
| 152 | - todo todo __fixsfsi // convert a to i32, rounding towards zero | 152 | - todo todo __fixsfsi // convert a to i32, rounding towards zero |
| 153 | - todo todo __fixdfsi // | 153 | - todo todo __fixdfsi // |
| 154 | - todo todo __fixtfsi // | 154 | - todo todo __fixtfsi // |
| 155 | - none none __fixxfsi // missing | 155 | - todo todo __fixxfsi // |
| 156 | - todo todo __fixsfdi // convert a to i64, rounding towards zero | 156 | - todo todo __fixsfdi // convert a to i64, rounding towards zero |
| 157 | - todo todo __fixdfdi // | 157 | - todo todo __fixdfdi // |
| 158 | - todo todo __fixtfdi // | 158 | - todo todo __fixtfdi // |
| 159 | - none none __fixxfdi // missing | 159 | - todo todo __fixxfdi // |
| 160 | - todo todo __fixsfti // convert a to i128, rounding towards zero | 160 | - todo todo __fixsfti // convert a to i128, rounding towards zero |
| 161 | - todo todo __fixdfti // | 161 | - todo todo __fixdfti // |
| 162 | - todo todo __fixtfdi // | 162 | - todo todo __fixtfdi // |
| 163 | - none none __fixxfti // missing | 163 | - todo todo __fixxfti // |
| 164 | 164 | ||
| 165 | - __fixunssfsi // convert to u32, rounding towards zero. negative values become 0. | 165 | - __fixunssfsi // convert to u32, rounding towards zero. negative values become 0. |
| 166 | - __fixunsdfsi // | 166 | - __fixunsdfsi // |
| 167 | - __fixunstfsi // | 167 | - __fixunstfsi // |
| 168 | - __fixunsxfsi // missing | 168 | - __fixunsxfsi // |
| 169 | - __fixunssfdi // convert to u64, rounding towards zero. negative values become 0. | 169 | - __fixunssfdi // convert to u64, rounding towards zero. negative values become 0. |
| 170 | - __fixunsdfdi // | 170 | - __fixunsdfdi // |
| 171 | - __fixunstfdi // | 171 | - __fixunstfdi // |
| 172 | - __fixunsxfdi // missing | 172 | - __fixunsxfdi // |
| 173 | - __fixunssfti // convert to u128, rounding towards zero. negative values become 0. | 173 | - __fixunssfti // convert to u128, rounding towards zero. negative values become 0. |
| 174 | - __fixunsdfti // | 174 | - __fixunsdfti // |
| 175 | - __fixunstfdi // | 175 | - __fixunstfdi // |
| 176 | - __fixunsxfti // missing | 176 | - __fixunsxfti // |
| 177 | 177 | ||
| 178 | - __floatsisf // convert i32 to floating point | 178 | - __floatsisf // convert i32 to floating point |
| 179 | - __floatsidf // | 179 | - __floatsidf // |
| 180 | - __floatsitf // | 180 | - __floatsitf // |
| 181 | - __floatsixf // missing | 181 | - __floatsixf // |
| 182 | - __floatdisf // convert i64 to floating point | 182 | - __floatdisf // convert i64 to floating point |
| 183 | - __floatdidf // | 183 | - __floatdidf // |
| 184 | - __floatditf // | 184 | - __floatditf // |
| 185 | - __floatdixf // missing | 185 | - __floatdixf // |
| 186 | - __floattisf // convert i128 to floating point | 186 | - __floattisf // convert i128 to floating point |
| 187 | - __floattidf // | 187 | - __floattidf // |
| 188 | - __floattixf // missing | 188 | - __floattixf // |
| 189 | 189 | ||
| 190 | - __floatunsisf // convert i32 to floating point | 190 | - __floatunsisf // convert u32 to floating point |
| 191 | - __floatunsidf // | 191 | - __floatunsidf // |
| 192 | - __floatunsitf // | 192 | - __floatunsitf // |
| 193 | - __floatunsixf // missing | 193 | - __floatunsixf // |
| 194 | - __floatundisf // convert i64 to floating point | 194 | - __floatundisf // convert u64 to floating point |
| 195 | - __floatundidf // | 195 | - __floatundidf // |
| 196 | - __floatunditf // | 196 | - __floatunditf // |
| 197 | - __floatundixf // missing | 197 | - __floatundixf // |
| 198 | - __floatuntisf // convert i128 to floating point | 198 | - __floatuntisf // convert u128 to floating point |
| 199 | - __floatuntidf // | 199 | - __floatuntidf // |
| 200 | - __floatuntitf // | 200 | - __floatuntitf // |
| 201 | - __floatuntixf // missing | 201 | - __floatuntixf // |
| 202 | 202 | ||
| 203 | #### Float Comparison | 203 | #### Float Comparison |
| 204 | - __cmpsf2 // return (a<b)=>-1,(a==b)=>0,(a>b)=>1,Nan=>1 dont rely on this | 204 | - __cmpsf2 // return (a<b)=>-1,(a==b)=>0,(a>b)=>1,Nan=>1 dont rely on this |
| ... | @@ -242,11 +242,11 @@ Bugs should be solved by trying to duplicate the bug upstream, if possible. | ... | @@ -242,11 +242,11 @@ Bugs should be solved by trying to duplicate the bug upstream, if possible. |
| 242 | - __mulsf3 // a * b | 242 | - __mulsf3 // a * b |
| 243 | - __muldf3 // a * b | 243 | - __muldf3 // a * b |
| 244 | - __multf3 // a * b | 244 | - __multf3 // a * b |
| 245 | - __mulxf3 // a * b missing | 245 | - __mulxf3 // a * b |
| 246 | - __divsf3 // a / b | 246 | - __divsf3 // a / b |
| 247 | - __divdf3 // a / b | 247 | - __divdf3 // a / b |
| 248 | - __divtf3 // a / b | 248 | - __divtf3 // a / b |
| 249 | - __divxf3 // a / b missing | 249 | - __divxf3 // a / b |
| 250 | - __negsf2 // -a symbol-level compatibility: libgcc uses this for the rl78 | 250 | - __negsf2 // -a symbol-level compatibility: libgcc uses this for the rl78 |
| 251 | - __negdf2 // -a unnecessary: can be lowered directly to a xor | 251 | - __negdf2 // -a unnecessary: can be lowered directly to a xor |
| 252 | - __negtf2 // -a | 252 | - __negtf2 // -a |
lib/std/special/compiler_rt/addXf3.zig+5-7| ... | @@ -74,7 +74,7 @@ fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeInfo(T | ... | @@ -74,7 +74,7 @@ fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeInfo(T |
| 74 | 74 | ||
| 75 | const shift = @clz(std.meta.Int(.unsigned, bits), significand.*) - @clz(Z, integerBit); | 75 | const shift = @clz(std.meta.Int(.unsigned, bits), significand.*) - @clz(Z, integerBit); |
| 76 | significand.* <<= @intCast(S, shift); | 76 | significand.* <<= @intCast(S, shift); |
| 77 | return 1 - shift; | 77 | return @as(i32, 1) - shift; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | // TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154 | 80 | // TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154 |
| ... | @@ -210,12 +210,10 @@ fn addXf3(comptime T: type, a: T, b: T) T { | ... | @@ -210,12 +210,10 @@ fn addXf3(comptime T: type, a: T, b: T) T { |
| 210 | if (aExponent >= maxExponent) return @bitCast(T, infRep | resultSign); | 210 | if (aExponent >= maxExponent) return @bitCast(T, infRep | resultSign); |
| 211 | 211 | ||
| 212 | if (aExponent <= 0) { | 212 | if (aExponent <= 0) { |
| 213 | // Result is denormal before rounding; the exponent is zero and we | 213 | // Result is denormal; the exponent and round/sticky bits are zero. |
| 214 | // need to shift the significand. | 214 | // All we need to do is shift the significand and apply the correct sign. |
| 215 | const shift = @intCast(Z, 1 - aExponent); | 215 | aSignificand >>= @intCast(S, 4 - aExponent); |
| 216 | const sticky = if (aSignificand << @intCast(S, typeWidth - shift) != 0) @as(Z, 1) else 0; | 216 | return @bitCast(T, resultSign | aSignificand); |
| 217 | aSignificand = aSignificand >> @intCast(S, shift | sticky); | ||
| 218 | aExponent = 0; | ||
| 219 | } | 217 | } |
| 220 | 218 | ||
| 221 | // Low three bits are round, guard, and sticky. | 219 | // Low three bits are round, guard, and sticky. |
lib/std/special/compiler_rt/addXf3_test.zig+2| ... | @@ -152,4 +152,6 @@ test "addxf3" { | ... | @@ -152,4 +152,6 @@ test "addxf3" { |
| 152 | try test__addxf3(0x1.0fff_ffff_ffff_fffep+0, 0x1.8p-63, 0x3FFF_8800000000000000); // round down to even | 152 | try test__addxf3(0x1.0fff_ffff_ffff_fffep+0, 0x1.8p-63, 0x3FFF_8800000000000000); // round down to even |
| 153 | try test__addxf3(0x1.0fff_ffff_ffff_fffep+0, 0x1.9p-63, 0x3FFF_8800000000000001); // round up | 153 | try test__addxf3(0x1.0fff_ffff_ffff_fffep+0, 0x1.9p-63, 0x3FFF_8800000000000001); // round up |
| 154 | try test__addxf3(0x1.0fff_ffff_ffff_fffep+0, 0x2.0p-63, 0x3FFF_8800000000000001); // exact | 154 | try test__addxf3(0x1.0fff_ffff_ffff_fffep+0, 0x2.0p-63, 0x3FFF_8800000000000001); // exact |
| 155 | try test__addxf3(0x0.ffff_ffff_ffff_fffcp-16382, 0x0.0000_0000_0000_0002p-16382, 0x0000_7FFFFFFFFFFFFFFF); // exact | ||
| 156 | try test__addxf3(0x0.1fff_ffff_ffff_fffcp-16382, 0x0.0000_0000_0000_0002p-16382, 0x0000_0FFFFFFFFFFFFFFF); // exact | ||
| 155 | } | 157 | } |
lib/std/special/compiler_rt/mulXf3.zig+9-1| ... | @@ -152,6 +152,10 @@ fn mulXf3(comptime T: type, a: T, b: T) T { | ... | @@ -152,6 +152,10 @@ fn mulXf3(comptime T: type, a: T, b: T) T { |
| 152 | const sticky = wideShrWithTruncation(ZSignificand, &productHi, &productLo, shift); | 152 | const sticky = wideShrWithTruncation(ZSignificand, &productHi, &productLo, shift); |
| 153 | productLo |= @boolToInt(sticky); | 153 | productLo |= @boolToInt(sticky); |
| 154 | result = productHi; | 154 | result = productHi; |
| 155 | |||
| 156 | // We include the integer bit so that rounding will carry to the exponent, | ||
| 157 | // but it will be removed later if the result is still denormal | ||
| 158 | if (significandBits != fractionalBits) result |= integerBit; | ||
| 155 | } else { | 159 | } else { |
| 156 | // Result is normal before rounding; insert the exponent. | 160 | // Result is normal before rounding; insert the exponent. |
| 157 | result = productHi & significandMask; | 161 | result = productHi & significandMask; |
| ... | @@ -166,7 +170,11 @@ fn mulXf3(comptime T: type, a: T, b: T) T { | ... | @@ -166,7 +170,11 @@ fn mulXf3(comptime T: type, a: T, b: T) T { |
| 166 | 170 | ||
| 167 | // Restore any explicit integer bit, if it was rounded off | 171 | // Restore any explicit integer bit, if it was rounded off |
| 168 | if (significandBits != fractionalBits) { | 172 | if (significandBits != fractionalBits) { |
| 169 | if ((result >> significandBits) != 0) result |= integerBit; | 173 | if ((result >> significandBits) != 0) { |
| 174 | result |= integerBit; | ||
| 175 | } else { | ||
| 176 | result &= ~integerBit; | ||
| 177 | } | ||
| 170 | } | 178 | } |
| 171 | 179 | ||
| 172 | // Insert the sign of the result: | 180 | // Insert the sign of the result: |
lib/std/special/compiler_rt/mulXf3_test.zig+4| ... | @@ -105,6 +105,7 @@ test "multf3" { | ... | @@ -105,6 +105,7 @@ test "multf3" { |
| 105 | 105 | ||
| 106 | try test__multf3(0x1.0000_0000_0000_0000_0000_0000_0001p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0002); | 106 | try test__multf3(0x1.0000_0000_0000_0000_0000_0000_0001p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0002); |
| 107 | try test__multf3(0x1.0000_0000_0000_0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0003); | 107 | try test__multf3(0x1.0000_0000_0000_0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0003); |
| 108 | try test__multf3(2.0, math.floatTrueMin(f128), 0x0000_0000_0000_0000, 0x0000_0000_0000_0002); | ||
| 108 | } | 109 | } |
| 109 | 110 | ||
| 110 | const qnan80 = @bitCast(f80, @bitCast(u80, math.nan(f80)) | (1 << (math.floatFractionalBits(f80) - 1))); | 111 | const qnan80 = @bitCast(f80, @bitCast(u80, math.nan(f80)) | (1 << (math.floatFractionalBits(f80) - 1))); |
| ... | @@ -164,4 +165,7 @@ test "mulxf3" { | ... | @@ -164,4 +165,7 @@ test "mulxf3" { |
| 164 | 165 | ||
| 165 | try test__mulxf3(0x1.0000_0001p+0, 0x1.0000_0001p+0, 0x3FFF_8000_0001_0000_0000); // round down to even | 166 | try test__mulxf3(0x1.0000_0001p+0, 0x1.0000_0001p+0, 0x3FFF_8000_0001_0000_0000); // round down to even |
| 166 | try test__mulxf3(0x1.0000_0001p+0, 0x1.0000_0001_0002p+0, 0x3FFF_8000_0001_0001_0001); // round up | 167 | try test__mulxf3(0x1.0000_0001p+0, 0x1.0000_0001_0002p+0, 0x3FFF_8000_0001_0001_0001); // round up |
| 168 | try test__mulxf3(0x0.8000_0000_0000_0000p-16382, 2.0, 0x0001_8000_0000_0000_0000); // denormal -> normal | ||
| 169 | try test__mulxf3(0x0.7fff_ffff_ffff_fffep-16382, 0x2.0000_0000_0000_0008p0, 0x0001_8000_0000_0000_0000); // denormal -> normal | ||
| 170 | try test__mulxf3(0x0.7fff_ffff_ffff_fffep-16382, 0x1.0000_0000_0000_0000p0, 0x0000_3FFF_FFFF_FFFF_FFFF); // denormal -> denormal | ||
| 167 | } | 171 | } |