| author | |
| committer | |
| log | a242b0be888fbcffd4eaa2e3af9cb30bc3c71584 |
| tree | 206800945aea793494fc490cd2343a77d391d244 |
| parent | 0c0be6da880fd1a6bdd3266125d6c5bcaac2803f |
213 files changed, 6404 insertions(+), 7023 deletions(-)
lib/compiler/resinator/parse.zig+1-1| ... | ... | @@ -1277,7 +1277,7 @@ pub const Parser = struct { |
| 1277 | 1277 | }, |
| 1278 | 1278 | else => unreachable, |
| 1279 | 1279 | } |
| 1280 | @compileError("unreachable"); | |
| 1280 | comptime unreachable; | |
| 1281 | 1281 | } |
| 1282 | 1282 | |
| 1283 | 1283 | pub const OptionalParamParser = struct { |
lib/compiler_rt.zig+120-168| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | const builtin = @import("builtin"); |
| 2 | const compiler_rt = @This(); | |
| 2 | 3 | const ofmt_c = builtin.object_format == .c; |
| 3 | 4 | const native_endian = builtin.cpu.arch.endian(); |
| 4 | 5 | |
| ... | ... | @@ -84,144 +85,17 @@ comptime { |
| 84 | 85 | // Float routines |
| 85 | 86 | // conversion |
| 86 | 87 | _ = @import("compiler_rt/extendf.zig"); |
| 87 | _ = @import("compiler_rt/extendhfsf2.zig"); | |
| 88 | _ = @import("compiler_rt/extendhfdf2.zig"); | |
| 89 | _ = @import("compiler_rt/extendhftf2.zig"); | |
| 90 | _ = @import("compiler_rt/extendhfxf2.zig"); | |
| 91 | _ = @import("compiler_rt/extendsfdf2.zig"); | |
| 92 | _ = @import("compiler_rt/extendsftf2.zig"); | |
| 93 | _ = @import("compiler_rt/extendsfxf2.zig"); | |
| 94 | _ = @import("compiler_rt/extenddftf2.zig"); | |
| 95 | _ = @import("compiler_rt/extenddfxf2.zig"); | |
| 96 | _ = @import("compiler_rt/extendxftf2.zig"); | |
| 97 | ||
| 98 | 88 | _ = @import("compiler_rt/truncf.zig"); |
| 99 | _ = @import("compiler_rt/truncsfhf2.zig"); | |
| 100 | _ = @import("compiler_rt/truncdfhf2.zig"); | |
| 101 | _ = @import("compiler_rt/truncdfsf2.zig"); | |
| 102 | _ = @import("compiler_rt/truncxfhf2.zig"); | |
| 103 | _ = @import("compiler_rt/truncxfsf2.zig"); | |
| 104 | _ = @import("compiler_rt/truncxfdf2.zig"); | |
| 105 | _ = @import("compiler_rt/trunctfhf2.zig"); | |
| 106 | _ = @import("compiler_rt/trunctfsf2.zig"); | |
| 107 | _ = @import("compiler_rt/trunctfdf2.zig"); | |
| 108 | _ = @import("compiler_rt/trunctfxf2.zig"); | |
| 109 | ||
| 110 | 89 | _ = @import("compiler_rt/int_from_float.zig"); |
| 111 | _ = @import("compiler_rt/fixhfei.zig"); | |
| 112 | _ = @import("compiler_rt/fixsfsi.zig"); | |
| 113 | _ = @import("compiler_rt/fixsfdi.zig"); | |
| 114 | _ = @import("compiler_rt/fixsfti.zig"); | |
| 115 | _ = @import("compiler_rt/fixsfei.zig"); | |
| 116 | _ = @import("compiler_rt/fixdfsi.zig"); | |
| 117 | _ = @import("compiler_rt/fixdfdi.zig"); | |
| 118 | _ = @import("compiler_rt/fixdfti.zig"); | |
| 119 | _ = @import("compiler_rt/fixdfei.zig"); | |
| 120 | _ = @import("compiler_rt/fixtfsi.zig"); | |
| 121 | _ = @import("compiler_rt/fixtfdi.zig"); | |
| 122 | _ = @import("compiler_rt/fixtfti.zig"); | |
| 123 | _ = @import("compiler_rt/fixtfei.zig"); | |
| 124 | _ = @import("compiler_rt/fixxfsi.zig"); | |
| 125 | _ = @import("compiler_rt/fixxfdi.zig"); | |
| 126 | _ = @import("compiler_rt/fixxfei.zig"); | |
| 127 | ||
| 128 | _ = @import("compiler_rt/fixunshfsi.zig"); | |
| 129 | _ = @import("compiler_rt/fixunshfdi.zig"); | |
| 130 | _ = @import("compiler_rt/fixunshfti.zig"); | |
| 131 | _ = @import("compiler_rt/fixunshfei.zig"); | |
| 132 | _ = @import("compiler_rt/fixunssfsi.zig"); | |
| 133 | _ = @import("compiler_rt/fixunssfdi.zig"); | |
| 134 | _ = @import("compiler_rt/fixunssfti.zig"); | |
| 135 | _ = @import("compiler_rt/fixunssfei.zig"); | |
| 136 | _ = @import("compiler_rt/fixunsdfsi.zig"); | |
| 137 | _ = @import("compiler_rt/fixunsdfdi.zig"); | |
| 138 | _ = @import("compiler_rt/fixunsdfti.zig"); | |
| 139 | _ = @import("compiler_rt/fixunsdfei.zig"); | |
| 140 | _ = @import("compiler_rt/fixunstfsi.zig"); | |
| 141 | _ = @import("compiler_rt/fixunstfdi.zig"); | |
| 142 | _ = @import("compiler_rt/fixunstfti.zig"); | |
| 143 | _ = @import("compiler_rt/fixunstfei.zig"); | |
| 144 | _ = @import("compiler_rt/fixunsxfsi.zig"); | |
| 145 | _ = @import("compiler_rt/fixunsxfdi.zig"); | |
| 146 | _ = @import("compiler_rt/fixunsxfti.zig"); | |
| 147 | _ = @import("compiler_rt/fixunsxfei.zig"); | |
| 148 | ||
| 149 | 90 | _ = @import("compiler_rt/float_from_int.zig"); |
| 150 | _ = @import("compiler_rt/floatsihf.zig"); | |
| 151 | _ = @import("compiler_rt/floatsisf.zig"); | |
| 152 | _ = @import("compiler_rt/floatsidf.zig"); | |
| 153 | _ = @import("compiler_rt/floatsitf.zig"); | |
| 154 | _ = @import("compiler_rt/floatsixf.zig"); | |
| 155 | _ = @import("compiler_rt/floatdihf.zig"); | |
| 156 | _ = @import("compiler_rt/floatdisf.zig"); | |
| 157 | _ = @import("compiler_rt/floatdidf.zig"); | |
| 158 | _ = @import("compiler_rt/floatditf.zig"); | |
| 159 | _ = @import("compiler_rt/floatdixf.zig"); | |
| 160 | _ = @import("compiler_rt/floattihf.zig"); | |
| 161 | _ = @import("compiler_rt/floattisf.zig"); | |
| 162 | _ = @import("compiler_rt/floattidf.zig"); | |
| 163 | _ = @import("compiler_rt/floattitf.zig"); | |
| 164 | _ = @import("compiler_rt/floattixf.zig"); | |
| 165 | _ = @import("compiler_rt/floateihf.zig"); | |
| 166 | _ = @import("compiler_rt/floateisf.zig"); | |
| 167 | _ = @import("compiler_rt/floateidf.zig"); | |
| 168 | _ = @import("compiler_rt/floateitf.zig"); | |
| 169 | _ = @import("compiler_rt/floateixf.zig"); | |
| 170 | _ = @import("compiler_rt/floatunsihf.zig"); | |
| 171 | _ = @import("compiler_rt/floatunsisf.zig"); | |
| 172 | _ = @import("compiler_rt/floatunsidf.zig"); | |
| 173 | _ = @import("compiler_rt/floatunsitf.zig"); | |
| 174 | _ = @import("compiler_rt/floatunsixf.zig"); | |
| 175 | _ = @import("compiler_rt/floatundihf.zig"); | |
| 176 | _ = @import("compiler_rt/floatundisf.zig"); | |
| 177 | _ = @import("compiler_rt/floatundidf.zig"); | |
| 178 | _ = @import("compiler_rt/floatunditf.zig"); | |
| 179 | _ = @import("compiler_rt/floatundixf.zig"); | |
| 180 | _ = @import("compiler_rt/floatuntihf.zig"); | |
| 181 | _ = @import("compiler_rt/floatuntisf.zig"); | |
| 182 | _ = @import("compiler_rt/floatuntidf.zig"); | |
| 183 | _ = @import("compiler_rt/floatuntitf.zig"); | |
| 184 | _ = @import("compiler_rt/floatuntixf.zig"); | |
| 185 | _ = @import("compiler_rt/floatuneihf.zig"); | |
| 186 | _ = @import("compiler_rt/floatuneisf.zig"); | |
| 187 | _ = @import("compiler_rt/floatuneidf.zig"); | |
| 188 | _ = @import("compiler_rt/floatuneitf.zig"); | |
| 189 | _ = @import("compiler_rt/floatuneixf.zig"); | |
| 190 | 91 | |
| 191 | 92 | // comparison |
| 192 | 93 | _ = @import("compiler_rt/comparef.zig"); |
| 193 | _ = @import("compiler_rt/cmpdf2.zig"); | |
| 194 | _ = @import("compiler_rt/cmptf2.zig"); | |
| 195 | _ = @import("compiler_rt/cmpxf2.zig"); | |
| 196 | _ = @import("compiler_rt/unorddf2.zig"); | |
| 197 | _ = @import("compiler_rt/gehf2.zig"); | |
| 198 | _ = @import("compiler_rt/gesf2.zig"); | |
| 199 | _ = @import("compiler_rt/gedf2.zig"); | |
| 200 | _ = @import("compiler_rt/gexf2.zig"); | |
| 201 | _ = @import("compiler_rt/getf2.zig"); | |
| 202 | 94 | |
| 203 | 95 | // arithmetic |
| 204 | 96 | _ = @import("compiler_rt/addf3.zig"); |
| 205 | _ = @import("compiler_rt/addhf3.zig"); | |
| 206 | _ = @import("compiler_rt/addsf3.zig"); | |
| 207 | _ = @import("compiler_rt/adddf3.zig"); | |
| 208 | _ = @import("compiler_rt/addtf3.zig"); | |
| 209 | _ = @import("compiler_rt/addxf3.zig"); | |
| 210 | ||
| 211 | _ = @import("compiler_rt/subhf3.zig"); | |
| 212 | _ = @import("compiler_rt/subsf3.zig"); | |
| 213 | _ = @import("compiler_rt/subdf3.zig"); | |
| 214 | _ = @import("compiler_rt/subtf3.zig"); | |
| 215 | _ = @import("compiler_rt/subxf3.zig"); | |
| 216 | ||
| 217 | 97 | _ = @import("compiler_rt/mulf3.zig"); |
| 218 | _ = @import("compiler_rt/mulhf3.zig"); | |
| 219 | _ = @import("compiler_rt/mulsf3.zig"); | |
| 220 | _ = @import("compiler_rt/muldf3.zig"); | |
| 221 | _ = @import("compiler_rt/multf3.zig"); | |
| 222 | _ = @import("compiler_rt/mulxf3.zig"); | |
| 223 | 98 | |
| 224 | _ = @import("compiler_rt/divhf3.zig"); | |
| 225 | 99 | _ = @import("compiler_rt/divsf3.zig"); |
| 226 | 100 | _ = @import("compiler_rt/divdf3.zig"); |
| 227 | 101 | _ = @import("compiler_rt/divxf3.zig"); |
| ... | ... | @@ -235,25 +109,17 @@ comptime { |
| 235 | 109 | symbol(&__negsf2, "__negsf2"); |
| 236 | 110 | symbol(&__negdf2, "__negdf2"); |
| 237 | 111 | } |
| 238 | if (want_ppc_abi) symbol(&__negtf2, "__negkf2"); | |
| 239 | symbol(&__negtf2, "__negtf2"); | |
| 112 | if (want_ppc_abi) { | |
| 113 | symbol(&__negtf2, "__negkf2"); | |
| 114 | } else { | |
| 115 | symbol(&__negtf2, "__negtf2"); | |
| 116 | } | |
| 240 | 117 | symbol(&__negxf2, "__negxf2"); |
| 241 | 118 | |
| 242 | 119 | // other |
| 243 | 120 | _ = @import("compiler_rt/powiXf2.zig"); |
| 244 | 121 | _ = @import("compiler_rt/mulc3.zig"); |
| 245 | _ = @import("compiler_rt/mulhc3.zig"); | |
| 246 | _ = @import("compiler_rt/mulsc3.zig"); | |
| 247 | _ = @import("compiler_rt/muldc3.zig"); | |
| 248 | _ = @import("compiler_rt/mulxc3.zig"); | |
| 249 | _ = @import("compiler_rt/multc3.zig"); | |
| 250 | ||
| 251 | 122 | _ = @import("compiler_rt/divc3.zig"); |
| 252 | _ = @import("compiler_rt/divhc3.zig"); | |
| 253 | _ = @import("compiler_rt/divsc3.zig"); | |
| 254 | _ = @import("compiler_rt/divdc3.zig"); | |
| 255 | _ = @import("compiler_rt/divxc3.zig"); | |
| 256 | _ = @import("compiler_rt/divtc3.zig"); | |
| 257 | 123 | |
| 258 | 124 | // Math routines. Alphabetically sorted. |
| 259 | 125 | _ = @import("compiler_rt/cos.zig"); |
| ... | ... | @@ -279,7 +145,7 @@ comptime { |
| 279 | 145 | _ = @import("compiler_rt/divmodei4.zig"); |
| 280 | 146 | _ = @import("compiler_rt/udivmodei4.zig"); |
| 281 | 147 | |
| 282 | _ = @import("compiler_rt/limb64.zig"); | |
| 148 | if (builtin.cpu.arch.isWasm()) _ = @import("compiler_rt/limb64.zig"); | |
| 283 | 149 | |
| 284 | 150 | // extra |
| 285 | 151 | _ = @import("compiler_rt/os_version_check.zig"); |
| ... | ... | @@ -290,7 +156,7 @@ comptime { |
| 290 | 156 | _ = @import("compiler_rt/clear_cache.zig"); |
| 291 | 157 | _ = @import("compiler_rt/hexagon.zig"); |
| 292 | 158 | |
| 293 | if (@import("builtin").object_format != .c) { | |
| 159 | if (builtin.object_format != .c) { | |
| 294 | 160 | if (builtin.zig_backend != .stage2_aarch64) _ = @import("compiler_rt/atomics.zig"); |
| 295 | 161 | _ = @import("compiler_rt/stack_probe.zig"); |
| 296 | 162 | |
| ... | ... | @@ -366,10 +232,7 @@ pub const want_aeabi = switch (builtin.abi) { |
| 366 | 232 | .gnueabihf, |
| 367 | 233 | .android, |
| 368 | 234 | .androideabi, |
| 369 | => switch (builtin.cpu.arch) { | |
| 370 | .arm, .armeb, .thumb, .thumbeb => true, | |
| 371 | else => false, | |
| 372 | }, | |
| 235 | => builtin.cpu.arch.isArm(), | |
| 373 | 236 | else => false, |
| 374 | 237 | }; |
| 375 | 238 | |
| ... | ... | @@ -443,19 +306,108 @@ pub const gnu_f16_abi = switch (builtin.cpu.arch) { |
| 443 | 306 | pub const want_sparc64_abi = builtin.cpu.arch == .sparc64; |
| 444 | 307 | pub const want_sparc32_abi = builtin.cpu.arch == .sparc; |
| 445 | 308 | |
| 446 | pub fn F16T(comptime OtherType: type) type { | |
| 447 | return switch (builtin.cpu.arch) { | |
| 448 | .x86, .x86_64 => if (builtin.target.os.tag.isDarwin()) switch (OtherType) { | |
| 449 | // Starting with LLVM 16, Darwin uses different abi for f16 | |
| 450 | // depending on the type of the other return/argument..??? | |
| 451 | f32, f64 => u16, | |
| 452 | f80, f128 => f16, | |
| 453 | else => unreachable, | |
| 454 | } else f16, | |
| 455 | else => f16, | |
| 309 | /// For operations converting between `f16` and another floating point type. | |
| 310 | pub fn f16Conv(comptime OtherType: type) type { | |
| 311 | switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 16)) { | |
| 312 | .hard => {}, | |
| 313 | .soft => return softFloatAbi(f16), | |
| 314 | } | |
| 315 | if (builtin.cpu.arch.isX86() and builtin.os.tag.isDarwin()) switch (OtherType) { | |
| 316 | else => unreachable, | |
| 317 | // Starting with LLVM 16, Darwin uses different abi for f16 | |
| 318 | // depending on the type of the other return/argument..??? | |
| 319 | f32, f64 => return softFloatAbi(f16), | |
| 320 | f80, f128 => {}, | |
| 321 | }; | |
| 322 | return hardFloatAbi(f16); | |
| 323 | } | |
| 324 | pub const @"f16" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 16)) { | |
| 325 | .hard => hardFloatAbi(f16), | |
| 326 | .soft => softFloatAbi(f16), | |
| 327 | }; | |
| 328 | pub const @"f32" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 32)) { | |
| 329 | .hard => hardFloatAbi(f32), | |
| 330 | .soft => softFloatAbi(f32), | |
| 331 | }; | |
| 332 | pub const @"f64" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 64)) { | |
| 333 | .hard => hardFloatAbi(f64), | |
| 334 | .soft => softFloatAbi(f64), | |
| 335 | }; | |
| 336 | pub const @"f80" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 80)) { | |
| 337 | .hard => hardFloatAbi(f80), | |
| 338 | .soft => struct { | |
| 339 | pub const Abi = extern struct { mantissa: u64, exponent: u16 }; | |
| 340 | const Repr = packed struct { mantissa: u64, exponent: u16 }; | |
| 341 | pub inline fn toAbi(raw: f80) Abi { | |
| 342 | const repr: Repr = @bitCast(raw); | |
| 343 | return .{ .mantissa = repr.mantissa, .exponent = repr.exponent }; | |
| 344 | } | |
| 345 | pub inline fn fromAbi(abi: Abi) f80 { | |
| 346 | const repr: Repr = .{ .mantissa = abi.mantissa, .exponent = abi.exponent }; | |
| 347 | return @bitCast(repr); | |
| 348 | } | |
| 349 | pub const complex = complexAbi(f80, @This()); | |
| 350 | }, | |
| 351 | }; | |
| 352 | pub const @"f128" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 128)) { | |
| 353 | .hard => hardFloatAbi(f128), | |
| 354 | .soft => struct { | |
| 355 | pub const Abi = switch (builtin.cpu.arch.endian()) { | |
| 356 | .big => extern struct { hi: u64, lo: u64 }, | |
| 357 | .little => extern struct { lo: u64, hi: u64 }, | |
| 358 | }; | |
| 359 | const Repr = packed struct { lo: u64, hi: u64 }; | |
| 360 | pub inline fn toAbi(raw: f128) Abi { | |
| 361 | const repr: Repr = @bitCast(raw); | |
| 362 | return .{ .lo = repr.lo, .hi = repr.hi }; | |
| 363 | } | |
| 364 | pub inline fn fromAbi(abi: Abi) f128 { | |
| 365 | const repr: Repr = .{ .lo = abi.lo, .hi = abi.hi }; | |
| 366 | return @bitCast(repr); | |
| 367 | } | |
| 368 | pub const complex = complexAbi(f128, @This()); | |
| 369 | }, | |
| 370 | }; | |
| 371 | fn hardFloatAbi(comptime Float: type) type { | |
| 372 | return struct { | |
| 373 | pub const Abi = Float; | |
| 374 | pub inline fn toAbi(raw: Float) Abi { | |
| 375 | return raw; | |
| 376 | } | |
| 377 | pub inline fn fromAbi(abi: Abi) Float { | |
| 378 | return abi; | |
| 379 | } | |
| 380 | pub const complex = complexAbi(Float, @This()); | |
| 381 | }; | |
| 382 | } | |
| 383 | fn softFloatAbi(comptime Float: type) type { | |
| 384 | return struct { | |
| 385 | pub const Abi = @Int(.unsigned, @bitSizeOf(Float)); | |
| 386 | pub inline fn toAbi(raw: Float) Abi { | |
| 387 | return @bitCast(raw); | |
| 388 | } | |
| 389 | pub inline fn fromAbi(abi: Abi) Float { | |
| 390 | return @bitCast(abi); | |
| 391 | } | |
| 392 | pub const complex = complexAbi(Float, @This()); | |
| 393 | }; | |
| 394 | } | |
| 395 | fn complexAbi(comptime Float: type, comptime float: type) type { | |
| 396 | return struct { | |
| 397 | pub const Abi = extern struct { real: float.Abi, imag: float.Abi }; | |
| 398 | pub inline fn toAbi(raw: Complex(Float)) Abi { | |
| 399 | return .{ .real = float.toAbi(raw.real), .imag = float.toAbi(raw.imag) }; | |
| 400 | } | |
| 401 | pub inline fn fromAbi(abi: Abi) Complex(Float) { | |
| 402 | return .{ .real = float.fromAbi(abi.real), .imag = float.fromAbi(abi.imag) }; | |
| 403 | } | |
| 456 | 404 | }; |
| 457 | 405 | } |
| 458 | 406 | |
| 407 | pub fn Complex(comptime Float: type) type { | |
| 408 | return struct { real: Float, imag: Float }; | |
| 409 | } | |
| 410 | ||
| 459 | 411 | pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void { |
| 460 | 412 | switch (Z) { |
| 461 | 413 | u16 => { |
| ... | ... | @@ -588,31 +540,31 @@ pub inline fn fneg(a: anytype) @TypeOf(a) { |
| 588 | 540 | return @bitCast(negated); |
| 589 | 541 | } |
| 590 | 542 | |
| 591 | fn __negxf2(a: f80) callconv(.c) f80 { | |
| 592 | return fneg(a); | |
| 543 | fn __neghf2(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 544 | return compiler_rt.f16.toAbi(fneg(compiler_rt.f16.fromAbi(a))); | |
| 593 | 545 | } |
| 594 | 546 | |
| 595 | fn __neghf2(a: f16) callconv(.c) f16 { | |
| 596 | return fneg(a); | |
| 547 | fn __negsf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 548 | return compiler_rt.f32.toAbi(fneg(compiler_rt.f32.fromAbi(a))); | |
| 597 | 549 | } |
| 598 | 550 | |
| 599 | fn __negdf2(a: f64) callconv(.c) f64 { | |
| 600 | return fneg(a); | |
| 551 | fn __negdf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 552 | return compiler_rt.f64.toAbi(fneg(compiler_rt.f64.fromAbi(a))); | |
| 601 | 553 | } |
| 602 | 554 | |
| 603 | fn __aeabi_dneg(a: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 604 | return fneg(a); | |
| 555 | fn __negxf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 556 | return compiler_rt.f80.toAbi(fneg(compiler_rt.f80.fromAbi(a))); | |
| 605 | 557 | } |
| 606 | 558 | |
| 607 | fn __negtf2(a: f128) callconv(.c) f128 { | |
| 608 | return fneg(a); | |
| 559 | fn __negtf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 560 | return compiler_rt.f128.toAbi(fneg(compiler_rt.f128.fromAbi(a))); | |
| 609 | 561 | } |
| 610 | 562 | |
| 611 | fn __negsf2(a: f32) callconv(.c) f32 { | |
| 563 | fn __aeabi_fneg(a: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 612 | 564 | return fneg(a); |
| 613 | 565 | } |
| 614 | 566 | |
| 615 | fn __aeabi_fneg(a: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 567 | fn __aeabi_dneg(a: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 616 | 568 | return fneg(a); |
| 617 | 569 | } |
| 618 | 570 |
lib/compiler_rt/absv.zig+1-2| ... | ... | @@ -14,8 +14,7 @@ pub inline fn absv(comptime ST: type, a: ST) ST { |
| 14 | 14 | const sign: ST = a >> N - 1; |
| 15 | 15 | x +%= sign; |
| 16 | 16 | x ^= sign; |
| 17 | if (x < 0) | |
| 18 | @panic("compiler_rt absv: overflow"); | |
| 17 | if (x < 0) @panic("integer overflow"); | |
| 19 | 18 | return x; |
| 20 | 19 | } |
| 21 | 20 |
lib/compiler_rt/absvdi2.zig+3-2| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 2 | const absv = @import("./absv.zig").absv; | |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const absv = @import("absv.zig").absv; | |
| 3 | 4 | |
| 4 | 5 | comptime { |
| 5 | 6 | symbol(&__absvdi2, "__absvdi2"); |
lib/compiler_rt/absvsi2.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const compiler_rt = @import("../compiler_rt.zig"); |
| 2 | 2 | const symbol = compiler_rt.symbol; |
| 3 | const absv = @import("./absv.zig").absv; | |
| 3 | const absv = @import("absv.zig").absv; | |
| 4 | 4 | |
| 5 | 5 | comptime { |
| 6 | 6 | symbol(&__absvsi2, "__absvsi2"); |
lib/compiler_rt/absvti2.zig+3-2| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 2 | const absv = @import("./absv.zig").absv; | |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const absv = @import("absv.zig").absv; | |
| 3 | 4 | |
| 4 | 5 | comptime { |
| 5 | 6 | symbol(&__absvti2, "__absvti2"); |
lib/compiler_rt/adddf3.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const addf3 = @import("./addf3.zig").addf3; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_dadd, "__aeabi_dadd"); | |
| 8 | } else { | |
| 9 | symbol(&__adddf3, "__adddf3"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | fn __adddf3(a: f64, b: f64) callconv(.c) f64 { | |
| 14 | return addf3(f64, a, b); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_dadd(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 18 | return addf3(f64, a, b); | |
| 19 | } |
lib/compiler_rt/addf3.zig+132-1| ... | ... | @@ -1,12 +1,143 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const math = std.math; |
| 3 | 3 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | const symbol = compiler_rt.symbol; | |
| 4 | 5 | const normalize = compiler_rt.normalize; |
| 5 | 6 | |
| 7 | comptime { | |
| 8 | symbol(&__addhf3, "__addhf3"); | |
| 9 | if (compiler_rt.want_aeabi) { | |
| 10 | symbol(&__aeabi_fadd, "__aeabi_fadd"); | |
| 11 | symbol(&__aeabi_dadd, "__aeabi_dadd"); | |
| 12 | } else { | |
| 13 | symbol(&__addsf3, "__addsf3"); | |
| 14 | symbol(&__adddf3, "__adddf3"); | |
| 15 | } | |
| 16 | symbol(&__addxf3, "__addxf3"); | |
| 17 | if (compiler_rt.want_ppc_abi) { | |
| 18 | symbol(&__addtf3, "__addkf3"); | |
| 19 | } else if (compiler_rt.want_sparc64_abi) { | |
| 20 | symbol(&_Qp_add, "_Qp_add"); | |
| 21 | } else if (compiler_rt.want_sparc32_abi) { | |
| 22 | symbol(&__addtf3, "_Q_add"); | |
| 23 | } else { | |
| 24 | symbol(&__addtf3, "__addtf3"); | |
| 25 | } | |
| 26 | } | |
| 27 | ||
| 28 | fn __addhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 29 | return compiler_rt.f16.toAbi(add_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); | |
| 30 | } | |
| 31 | pub fn add_f16(a: f16, b: f16) f16 { | |
| 32 | return addf3(f16, a, b); | |
| 33 | } | |
| 34 | ||
| 35 | fn __addsf3(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 36 | return compiler_rt.f32.toAbi(add_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); | |
| 37 | } | |
| 38 | fn __aeabi_fadd(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 39 | return add_f32(a, b); | |
| 40 | } | |
| 41 | pub fn add_f32(a: f32, b: f32) f32 { | |
| 42 | return addf3(f32, a, b); | |
| 43 | } | |
| 44 | ||
| 45 | fn __adddf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 46 | return compiler_rt.f64.toAbi(add_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); | |
| 47 | } | |
| 48 | fn __aeabi_dadd(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 49 | return add_f64(a, b); | |
| 50 | } | |
| 51 | pub fn add_f64(a: f64, b: f64) f64 { | |
| 52 | return addf3(f64, a, b); | |
| 53 | } | |
| 54 | ||
| 55 | fn __addxf3(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 56 | return compiler_rt.f80.toAbi(add_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); | |
| 57 | } | |
| 58 | pub fn add_f80(a: f80, b: f80) f80 { | |
| 59 | return addf3(f80, a, b); | |
| 60 | } | |
| 61 | ||
| 62 | fn __addtf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 63 | return compiler_rt.f128.toAbi(add_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); | |
| 64 | } | |
| 65 | fn _Qp_add(c: *f128, a: *f128, b: *f128) callconv(.c) void { | |
| 66 | c.* = add_f128(a.*, b.*); | |
| 67 | } | |
| 68 | pub fn add_f128(a: f128, b: f128) f128 { | |
| 69 | return addf3(f128, a, b); | |
| 70 | } | |
| 71 | ||
| 72 | comptime { | |
| 73 | symbol(&__subhf3, "__subhf3"); | |
| 74 | if (compiler_rt.want_aeabi) { | |
| 75 | symbol(&__aeabi_fsub, "__aeabi_fsub"); | |
| 76 | symbol(&__aeabi_dsub, "__aeabi_dsub"); | |
| 77 | } else { | |
| 78 | symbol(&__subsf3, "__subsf3"); | |
| 79 | symbol(&__subdf3, "__subdf3"); | |
| 80 | } | |
| 81 | symbol(&__subxf3, "__subxf3"); | |
| 82 | if (compiler_rt.want_ppc_abi) { | |
| 83 | symbol(&__subtf3, "__subkf3"); | |
| 84 | } else if (compiler_rt.want_sparc64_abi) { | |
| 85 | symbol(&_Qp_sub, "_Qp_sub"); | |
| 86 | } else if (compiler_rt.want_sparc32_abi) { | |
| 87 | symbol(&__subtf3, "_Q_sub"); | |
| 88 | } else { | |
| 89 | symbol(&__subtf3, "__subtf3"); | |
| 90 | } | |
| 91 | } | |
| 92 | ||
| 93 | fn __subhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 94 | return compiler_rt.f16.toAbi(sub_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); | |
| 95 | } | |
| 96 | pub fn sub_f16(a: f16, b: f16) f16 { | |
| 97 | return add_f16(a, compiler_rt.fneg(b)); | |
| 98 | } | |
| 99 | ||
| 100 | fn __subsf3(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 101 | return compiler_rt.f32.toAbi(sub_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); | |
| 102 | } | |
| 103 | fn __aeabi_fsub(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 104 | return sub_f32(a, b); | |
| 105 | } | |
| 106 | pub fn sub_f32(a: f32, b: f32) f32 { | |
| 107 | return add_f32(a, compiler_rt.fneg(b)); | |
| 108 | } | |
| 109 | ||
| 110 | fn __subdf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 111 | return compiler_rt.f64.toAbi(sub_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); | |
| 112 | } | |
| 113 | fn __aeabi_dsub(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 114 | return sub_f64(a, b); | |
| 115 | } | |
| 116 | pub fn sub_f64(a: f64, b: f64) f64 { | |
| 117 | return add_f64(a, compiler_rt.fneg(b)); | |
| 118 | } | |
| 119 | ||
| 120 | fn __subxf3(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 121 | return compiler_rt.f80.toAbi(sub_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); | |
| 122 | } | |
| 123 | pub fn sub_f80(a: f80, b: f80) f80 { | |
| 124 | return add_f80(a, compiler_rt.fneg(b)); | |
| 125 | } | |
| 126 | ||
| 127 | fn __subtf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 128 | return compiler_rt.f128.toAbi(sub_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); | |
| 129 | } | |
| 130 | fn _Qp_sub(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { | |
| 131 | c.* = sub_f128(a.*, b.*); | |
| 132 | } | |
| 133 | pub fn sub_f128(a: f128, b: f128) f128 { | |
| 134 | return add_f128(a, compiler_rt.fneg(b)); | |
| 135 | } | |
| 136 | ||
| 6 | 137 | /// Ported from: |
| 7 | 138 | /// |
| 8 | 139 | /// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/lib/builtins/fp_add_impl.inc |
| 9 | pub inline fn addf3(comptime T: type, a: T, b: T) T { | |
| 140 | inline fn addf3(comptime T: type, a: T, b: T) T { | |
| 10 | 141 | const bits = @typeInfo(T).float.bits; |
| 11 | 142 | const Z = @Int(.unsigned, bits); |
| 12 | 143 |
lib/compiler_rt/addf3_test.zig+7-6| ... | ... | @@ -8,12 +8,13 @@ const builtin = @import("builtin"); |
| 8 | 8 | const math = std.math; |
| 9 | 9 | const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64); |
| 10 | 10 | |
| 11 | const __addtf3 = @import("addtf3.zig").__addtf3; | |
| 12 | const __addxf3 = @import("addxf3.zig").__addxf3; | |
| 13 | const __subtf3 = @import("subtf3.zig").__subtf3; | |
| 11 | const impl = @import("addf3.zig"); | |
| 12 | const add_f128 = impl.add_f128; | |
| 13 | const add_f80 = impl.add_f80; | |
| 14 | const sub_f128 = impl.sub_f128; | |
| 14 | 15 | |
| 15 | 16 | fn test__addtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { |
| 16 | const x = __addtf3(a, b); | |
| 17 | const x = add_f128(a, b); | |
| 17 | 18 | |
| 18 | 19 | const rep: u128 = @bitCast(x); |
| 19 | 20 | const hi: u64 = @intCast(rep >> 64); |
| ... | ... | @@ -52,7 +53,7 @@ test "addtf3" { |
| 52 | 53 | } |
| 53 | 54 | |
| 54 | 55 | fn test__subtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { |
| 55 | const x = __subtf3(a, b); | |
| 56 | const x = sub_f128(a, b); | |
| 56 | 57 | |
| 57 | 58 | const rep: u128 = @bitCast(x); |
| 58 | 59 | const hi: u64 = @intCast(rep >> 64); |
| ... | ... | @@ -91,7 +92,7 @@ test "subtf3" { |
| 91 | 92 | const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1))); |
| 92 | 93 | |
| 93 | 94 | fn test__addxf3(a: f80, b: f80, expected: u80) !void { |
| 94 | const x = __addxf3(a, b); | |
| 95 | const x = add_f80(a, b); | |
| 95 | 96 | const rep: u80 = @bitCast(x); |
| 96 | 97 | |
| 97 | 98 | if (rep == expected) |
lib/compiler_rt/addhf3.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const addf3 = @import("./addf3.zig").addf3; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__addhf3, "__addhf3"); | |
| 7 | } | |
| 8 | ||
| 9 | fn __addhf3(a: f16, b: f16) callconv(.c) f16 { | |
| 10 | return addf3(f16, a, b); | |
| 11 | } |
lib/compiler_rt/addsf3.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const addf3 = @import("./addf3.zig").addf3; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_fadd, "__aeabi_fadd"); | |
| 8 | } else { | |
| 9 | symbol(&__addsf3, "__addsf3"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | fn __addsf3(a: f32, b: f32) callconv(.c) f32 { | |
| 14 | return addf3(f32, a, b); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_fadd(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 18 | return addf3(f32, a, b); | |
| 19 | } |
lib/compiler_rt/addtf3.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const addf3 = @import("./addf3.zig").addf3; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) { | |
| 7 | symbol(&__addtf3, "__addkf3"); | |
| 8 | } else if (compiler_rt.want_sparc64_abi) { | |
| 9 | symbol(&_Qp_add, "_Qp_add"); | |
| 10 | } else if (compiler_rt.want_sparc32_abi) { | |
| 11 | symbol(&__addtf3, "_Q_add"); | |
| 12 | } | |
| 13 | symbol(&__addtf3, "__addtf3"); | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __addtf3(a: f128, b: f128) callconv(.c) f128 { | |
| 17 | return addf3(f128, a, b); | |
| 18 | } | |
| 19 | ||
| 20 | fn _Qp_add(c: *f128, a: *f128, b: *f128) callconv(.c) void { | |
| 21 | c.* = addf3(f128, a.*, b.*); | |
| 22 | } |
lib/compiler_rt/addvdi3.zig+3-2| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 2 | 3 | const testing = @import("std").testing; |
| 3 | 4 | |
| 4 | 5 | comptime { |
| ... | ... | @@ -9,7 +10,7 @@ pub fn __addvdi3(a: i64, b: i64) callconv(.c) i64 { |
| 9 | 10 | const sum = a +% b; |
| 10 | 11 | // Overflow occurred iff both operands have the same sign, and the sign of the sum does |
| 11 | 12 | // not match it. In other words, iff the sum sign is not the sign of either operand. |
| 12 | if (((sum ^ a) & (sum ^ b)) < 0) @panic("compiler-rt: integer overflow"); | |
| 13 | if (((sum ^ a) & (sum ^ b)) < 0) @panic("integer overflow"); | |
| 13 | 14 | return sum; |
| 14 | 15 | } |
| 15 | 16 |
lib/compiler_rt/addvsi3.zig+1-1| ... | ... | @@ -10,7 +10,7 @@ pub fn __addvsi3(a: i32, b: i32) callconv(.c) i32 { |
| 10 | 10 | const sum = a +% b; |
| 11 | 11 | // Overflow occurred iff both operands have the same sign, and the sign of the sum does |
| 12 | 12 | // not match it. In other words, iff the sum sign is not the sign of either operand. |
| 13 | if (((sum ^ a) & (sum ^ b)) < 0) @panic("compiler-rt: integer overflow"); | |
| 13 | if (((sum ^ a) & (sum ^ b)) < 0) @panic("integer overflow"); | |
| 14 | 14 | return sum; |
| 15 | 15 | } |
| 16 | 16 |
lib/compiler_rt/addxf3.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const addf3 = @import("./addf3.zig").addf3; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__addxf3, "__addxf3"); | |
| 7 | } | |
| 8 | ||
| 9 | pub fn __addxf3(a: f80, b: f80) callconv(.c) f80 { | |
| 10 | return addf3(f80, a, b); | |
| 11 | } |
lib/compiler_rt/atomics.zig+1-1| ... | ... | @@ -5,7 +5,7 @@ const arch = cpu.arch; |
| 5 | 5 | const std = @import("std"); |
| 6 | 6 | |
| 7 | 7 | const compiler_rt = @import("../compiler_rt.zig"); |
| 8 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 8 | const symbol = compiler_rt.symbol; | |
| 9 | 9 | |
| 10 | 10 | // This parameter is true iff the target architecture supports the bare minimum |
| 11 | 11 | // to implement the atomic load/store intrinsics. |
lib/compiler_rt/aulldiv.zig+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | const builtin = @import("builtin"); |
| 2 | 2 | |
| 3 | 3 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | 5 | |
| 6 | 6 | comptime { |
| 7 | 7 | if (compiler_rt.want_windows_x86_msvc_abi) { |
lib/compiler_rt/cmpdf2.zig deleted-67| ... | ... | @@ -1,67 +0,0 @@ |
| 1 | ///! The quoted behavior definitions are from | |
| 2 | ///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const comparef = @import("./comparef.zig"); | |
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 6 | ||
| 7 | comptime { | |
| 8 | if (compiler_rt.want_aeabi) { | |
| 9 | symbol(&__aeabi_dcmpeq, "__aeabi_dcmpeq"); | |
| 10 | symbol(&__aeabi_dcmplt, "__aeabi_dcmplt"); | |
| 11 | symbol(&__aeabi_dcmple, "__aeabi_dcmple"); | |
| 12 | } else { | |
| 13 | symbol(&__eqdf2, "__eqdf2"); | |
| 14 | symbol(&__nedf2, "__nedf2"); | |
| 15 | symbol(&__ledf2, "__ledf2"); | |
| 16 | symbol(&__cmpdf2, "__cmpdf2"); | |
| 17 | symbol(&__ltdf2, "__ltdf2"); | |
| 18 | } | |
| 19 | } | |
| 20 | ||
| 21 | /// "These functions calculate a <=> b. That is, if a is less than b, they return -1; | |
| 22 | /// if a is greater than b, they return 1; and if a and b are equal they return 0. | |
| 23 | /// If either argument is NaN they return 1..." | |
| 24 | /// | |
| 25 | /// Note that this matches the definition of `__ledf2`, `__eqdf2`, `__nedf2`, `__cmpdf2`, | |
| 26 | /// and `__ltdf2`. | |
| 27 | fn __cmpdf2(a: f64, b: f64) callconv(.c) i32 { | |
| 28 | return @backingInt(comparef.cmpf2(f64, comparef.LE, a, b)); | |
| 29 | } | |
| 30 | ||
| 31 | /// "These functions return a value less than or equal to zero if neither argument is NaN, | |
| 32 | /// and a is less than or equal to b." | |
| 33 | pub fn __ledf2(a: f64, b: f64) callconv(.c) i32 { | |
| 34 | return __cmpdf2(a, b); | |
| 35 | } | |
| 36 | ||
| 37 | /// "These functions return zero if neither argument is NaN, and a and b are equal." | |
| 38 | /// Note that due to some kind of historical accident, __eqdf2 and __nedf2 are defined | |
| 39 | /// to have the same return value. | |
| 40 | pub fn __eqdf2(a: f64, b: f64) callconv(.c) i32 { | |
| 41 | return __cmpdf2(a, b); | |
| 42 | } | |
| 43 | ||
| 44 | /// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." | |
| 45 | /// Note that due to some kind of historical accident, __eqdf2 and __nedf2 are defined | |
| 46 | /// to have the same return value. | |
| 47 | pub fn __nedf2(a: f64, b: f64) callconv(.c) i32 { | |
| 48 | return __cmpdf2(a, b); | |
| 49 | } | |
| 50 | ||
| 51 | /// "These functions return a value less than zero if neither argument is NaN, and a | |
| 52 | /// is strictly less than b." | |
| 53 | pub fn __ltdf2(a: f64, b: f64) callconv(.c) i32 { | |
| 54 | return __cmpdf2(a, b); | |
| 55 | } | |
| 56 | ||
| 57 | fn __aeabi_dcmpeq(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 58 | return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) == .Equal); | |
| 59 | } | |
| 60 | ||
| 61 | fn __aeabi_dcmplt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 62 | return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) == .Less); | |
| 63 | } | |
| 64 | ||
| 65 | fn __aeabi_dcmple(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 66 | return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) != .Greater); | |
| 67 | } |
lib/compiler_rt/cmptf2.zig deleted-146| ... | ... | @@ -1,146 +0,0 @@ |
| 1 | ///! The quoted behavior definitions are from | |
| 2 | ///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const comparef = @import("./comparef.zig"); | |
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 6 | ||
| 7 | comptime { | |
| 8 | if (compiler_rt.want_ppc_abi) { | |
| 9 | symbol(&__eqtf2, "__eqkf2"); | |
| 10 | symbol(&__netf2, "__nekf2"); | |
| 11 | symbol(&__lttf2, "__ltkf2"); | |
| 12 | symbol(&__letf2, "__lekf2"); | |
| 13 | } else if (compiler_rt.want_sparc64_abi) { | |
| 14 | symbol(&_Qp_cmp, "_Qp_cmp"); | |
| 15 | symbol(&_Qp_feq, "_Qp_feq"); | |
| 16 | symbol(&_Qp_fne, "_Qp_fne"); | |
| 17 | symbol(&_Qp_flt, "_Qp_flt"); | |
| 18 | symbol(&_Qp_fle, "_Qp_fle"); | |
| 19 | symbol(&_Qp_fgt, "_Qp_fgt"); | |
| 20 | symbol(&_Qp_fge, "_Qp_fge"); | |
| 21 | } else if (compiler_rt.want_sparc32_abi) { | |
| 22 | symbol(&_Q_cmp, "_Q_cmp"); | |
| 23 | symbol(&_Q_feq, "_Q_feq"); | |
| 24 | symbol(&_Q_fne, "_Q_fne"); | |
| 25 | symbol(&_Q_flt, "_Q_flt"); | |
| 26 | symbol(&_Q_fle, "_Q_fle"); | |
| 27 | symbol(&_Q_fgt, "_Q_fgt"); | |
| 28 | symbol(&_Q_fge, "_Q_fge"); | |
| 29 | } | |
| 30 | symbol(&__eqtf2, "__eqtf2"); | |
| 31 | symbol(&__netf2, "__netf2"); | |
| 32 | symbol(&__letf2, "__letf2"); | |
| 33 | symbol(&__cmptf2, "__cmptf2"); | |
| 34 | symbol(&__lttf2, "__lttf2"); | |
| 35 | } | |
| 36 | ||
| 37 | /// "These functions calculate a <=> b. That is, if a is less than b, they return -1; | |
| 38 | /// if a is greater than b, they return 1; and if a and b are equal they return 0. | |
| 39 | /// If either argument is NaN they return 1..." | |
| 40 | /// | |
| 41 | /// Note that this matches the definition of `__letf2`, `__eqtf2`, `__netf2`, `__cmptf2`, | |
| 42 | /// and `__lttf2`. | |
| 43 | fn __cmptf2(a: f128, b: f128) callconv(.c) i32 { | |
| 44 | return @backingInt(comparef.cmpf2(f128, comparef.LE, a, b)); | |
| 45 | } | |
| 46 | ||
| 47 | /// "These functions return a value less than or equal to zero if neither argument is NaN, | |
| 48 | /// and a is less than or equal to b." | |
| 49 | fn __letf2(a: f128, b: f128) callconv(.c) i32 { | |
| 50 | return __cmptf2(a, b); | |
| 51 | } | |
| 52 | ||
| 53 | /// "These functions return zero if neither argument is NaN, and a and b are equal." | |
| 54 | /// Note that due to some kind of historical accident, __eqtf2 and __netf2 are defined | |
| 55 | /// to have the same return value. | |
| 56 | fn __eqtf2(a: f128, b: f128) callconv(.c) i32 { | |
| 57 | return __cmptf2(a, b); | |
| 58 | } | |
| 59 | ||
| 60 | /// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." | |
| 61 | /// Note that due to some kind of historical accident, __eqtf2 and __netf2 are defined | |
| 62 | /// to have the same return value. | |
| 63 | fn __netf2(a: f128, b: f128) callconv(.c) i32 { | |
| 64 | return __cmptf2(a, b); | |
| 65 | } | |
| 66 | ||
| 67 | /// "These functions return a value less than zero if neither argument is NaN, and a | |
| 68 | /// is strictly less than b." | |
| 69 | fn __lttf2(a: f128, b: f128) callconv(.c) i32 { | |
| 70 | return __cmptf2(a, b); | |
| 71 | } | |
| 72 | ||
| 73 | const SparcFCMP = enum(i32) { | |
| 74 | Equal = 0, | |
| 75 | Less = 1, | |
| 76 | Greater = 2, | |
| 77 | Unordered = 3, | |
| 78 | }; | |
| 79 | ||
| 80 | fn _Qp_cmp(a: *const f128, b: *const f128) callconv(.c) i32 { | |
| 81 | return @backingInt(comparef.cmpf2(f128, SparcFCMP, a.*, b.*)); | |
| 82 | } | |
| 83 | ||
| 84 | fn _Qp_feq(a: *const f128, b: *const f128) callconv(.c) bool { | |
| 85 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Equal; | |
| 86 | } | |
| 87 | ||
| 88 | fn _Qp_fne(a: *const f128, b: *const f128) callconv(.c) bool { | |
| 89 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) != .Equal; | |
| 90 | } | |
| 91 | ||
| 92 | fn _Qp_flt(a: *const f128, b: *const f128) callconv(.c) bool { | |
| 93 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Less; | |
| 94 | } | |
| 95 | ||
| 96 | fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.c) bool { | |
| 97 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Greater; | |
| 98 | } | |
| 99 | ||
| 100 | fn _Qp_fge(a: *const f128, b: *const f128) callconv(.c) bool { | |
| 101 | return switch (@as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b))))) { | |
| 102 | .Equal, .Greater => true, | |
| 103 | .Less, .Unordered => false, | |
| 104 | }; | |
| 105 | } | |
| 106 | ||
| 107 | fn _Qp_fle(a: *const f128, b: *const f128) callconv(.c) bool { | |
| 108 | return switch (@as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b))))) { | |
| 109 | .Equal, .Less => true, | |
| 110 | .Greater, .Unordered => false, | |
| 111 | }; | |
| 112 | } | |
| 113 | ||
| 114 | fn _Q_cmp(a: f128, b: f128) callconv(.c) i32 { | |
| 115 | return @backingInt(comparef.cmpf2(f128, SparcFCMP, a, b)); | |
| 116 | } | |
| 117 | ||
| 118 | fn _Q_feq(a: f128, b: f128) callconv(.c) bool { | |
| 119 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Equal; | |
| 120 | } | |
| 121 | ||
| 122 | fn _Q_fne(a: f128, b: f128) callconv(.c) bool { | |
| 123 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) != .Equal; | |
| 124 | } | |
| 125 | ||
| 126 | fn _Q_flt(a: f128, b: f128) callconv(.c) bool { | |
| 127 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Less; | |
| 128 | } | |
| 129 | ||
| 130 | fn _Q_fgt(a: f128, b: f128) callconv(.c) bool { | |
| 131 | return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Greater; | |
| 132 | } | |
| 133 | ||
| 134 | fn _Q_fge(a: f128, b: f128) callconv(.c) bool { | |
| 135 | return switch (@as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b))))) { | |
| 136 | .Equal, .Greater => true, | |
| 137 | .Less, .Unordered => false, | |
| 138 | }; | |
| 139 | } | |
| 140 | ||
| 141 | fn _Q_fle(a: f128, b: f128) callconv(.c) bool { | |
| 142 | return switch (@as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b))))) { | |
| 143 | .Equal, .Less => true, | |
| 144 | .Greater, .Unordered => false, | |
| 145 | }; | |
| 146 | } |
lib/compiler_rt/cmpxf2.zig deleted-49| ... | ... | @@ -1,49 +0,0 @@ |
| 1 | ///! The quoted behavior definitions are from | |
| 2 | ///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | const comparef = @import("./comparef.zig"); | |
| 6 | ||
| 7 | comptime { | |
| 8 | symbol(&__eqxf2, "__eqxf2"); | |
| 9 | symbol(&__nexf2, "__nexf2"); | |
| 10 | symbol(&__lexf2, "__lexf2"); | |
| 11 | symbol(&__cmpxf2, "__cmpxf2"); | |
| 12 | symbol(&__ltxf2, "__ltxf2"); | |
| 13 | } | |
| 14 | ||
| 15 | /// "These functions calculate a <=> b. That is, if a is less than b, they return -1; | |
| 16 | /// if a is greater than b, they return 1; and if a and b are equal they return 0. | |
| 17 | /// If either argument is NaN they return 1..." | |
| 18 | /// | |
| 19 | /// Note that this matches the definition of `__lexf2`, `__eqxf2`, `__nexf2`, `__cmpxf2`, | |
| 20 | /// and `__ltxf2`. | |
| 21 | fn __cmpxf2(a: f80, b: f80) callconv(.c) i32 { | |
| 22 | return @backingInt(comparef.cmp_f80(comparef.LE, a, b)); | |
| 23 | } | |
| 24 | ||
| 25 | /// "These functions return a value less than or equal to zero if neither argument is NaN, | |
| 26 | /// and a is less than or equal to b." | |
| 27 | fn __lexf2(a: f80, b: f80) callconv(.c) i32 { | |
| 28 | return __cmpxf2(a, b); | |
| 29 | } | |
| 30 | ||
| 31 | /// "These functions return zero if neither argument is NaN, and a and b are equal." | |
| 32 | /// Note that due to some kind of historical accident, __eqxf2 and __nexf2 are defined | |
| 33 | /// to have the same return value. | |
| 34 | fn __eqxf2(a: f80, b: f80) callconv(.c) i32 { | |
| 35 | return __cmpxf2(a, b); | |
| 36 | } | |
| 37 | ||
| 38 | /// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." | |
| 39 | /// Note that due to some kind of historical accident, __eqxf2 and __nexf2 are defined | |
| 40 | /// to have the same return value. | |
| 41 | fn __nexf2(a: f80, b: f80) callconv(.c) i32 { | |
| 42 | return __cmpxf2(a, b); | |
| 43 | } | |
| 44 | ||
| 45 | /// "These functions return a value less than zero if neither argument is NaN, and a | |
| 46 | /// is strictly less than b." | |
| 47 | fn __ltxf2(a: f80, b: f80) callconv(.c) i32 { | |
| 48 | return __cmpxf2(a, b); | |
| 49 | } |
lib/compiler_rt/comparedf2_test.zig+17-73| ... | ... | @@ -5,52 +5,12 @@ |
| 5 | 5 | const std = @import("std"); |
| 6 | 6 | const builtin = @import("builtin"); |
| 7 | 7 | |
| 8 | const __eqdf2 = @import("./cmpdf2.zig").__eqdf2; | |
| 9 | const __ledf2 = @import("./cmpdf2.zig").__ledf2; | |
| 10 | const __ltdf2 = @import("./cmpdf2.zig").__ltdf2; | |
| 11 | const __nedf2 = @import("./cmpdf2.zig").__nedf2; | |
| 8 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 12 | 9 | |
| 13 | const __gedf2 = @import("./gedf2.zig").__gedf2; | |
| 14 | const __gtdf2 = @import("./gedf2.zig").__gtdf2; | |
| 15 | ||
| 16 | const __unorddf2 = @import("./unorddf2.zig").__unorddf2; | |
| 17 | ||
| 18 | const TestVector = struct { | |
| 19 | a: f64, | |
| 20 | b: f64, | |
| 21 | eqReference: c_int, | |
| 22 | geReference: c_int, | |
| 23 | gtReference: c_int, | |
| 24 | leReference: c_int, | |
| 25 | ltReference: c_int, | |
| 26 | neReference: c_int, | |
| 27 | unReference: c_int, | |
| 28 | }; | |
| 29 | ||
| 30 | fn test__cmpdf2(vector: TestVector) bool { | |
| 31 | if (__eqdf2(vector.a, vector.b) != vector.eqReference) { | |
| 32 | return false; | |
| 33 | } | |
| 34 | if (__gedf2(vector.a, vector.b) != vector.geReference) { | |
| 35 | return false; | |
| 36 | } | |
| 37 | if (__gtdf2(vector.a, vector.b) != vector.gtReference) { | |
| 38 | return false; | |
| 39 | } | |
| 40 | if (__ledf2(vector.a, vector.b) != vector.leReference) { | |
| 41 | return false; | |
| 42 | } | |
| 43 | if (__ltdf2(vector.a, vector.b) != vector.ltReference) { | |
| 44 | return false; | |
| 45 | } | |
| 46 | if (__nedf2(vector.a, vector.b) != vector.neReference) { | |
| 47 | return false; | |
| 48 | } | |
| 49 | if (__unorddf2(vector.a, vector.b) != vector.unReference) { | |
| 50 | return false; | |
| 51 | } | |
| 52 | return true; | |
| 53 | } | |
| 10 | const impl = @import("comparef.zig"); | |
| 11 | const Order = impl.Order; | |
| 12 | const cmp_f64 = impl.cmp_f64; | |
| 13 | const unord_f64 = impl.unord_f64; | |
| 54 | 14 | |
| 55 | 15 | const arguments = [_]f64{ |
| 56 | 16 | std.math.nan(f64), |
| ... | ... | @@ -73,36 +33,20 @@ const arguments = [_]f64{ |
| 73 | 33 | std.math.inf(f64), |
| 74 | 34 | }; |
| 75 | 35 | |
| 76 | fn generateVector(comptime a: f64, comptime b: f64) TestVector { | |
| 77 | const leResult = if (a < b) -1 else if (a == b) 0 else 1; | |
| 78 | const geResult = if (a > b) 1 else if (a == b) 0 else -1; | |
| 79 | const unResult = if (a != a or b != b) 1 else 0; | |
| 80 | return TestVector{ | |
| 81 | .a = a, | |
| 82 | .b = b, | |
| 83 | .eqReference = leResult, | |
| 84 | .geReference = geResult, | |
| 85 | .gtReference = geResult, | |
| 86 | .leReference = leResult, | |
| 87 | .ltReference = leResult, | |
| 88 | .neReference = leResult, | |
| 89 | .unReference = unResult, | |
| 90 | }; | |
| 91 | } | |
| 92 | ||
| 93 | const test_vectors = init: { | |
| 94 | @setEvalBranchQuota(10000); | |
| 95 | var vectors: [arguments.len * arguments.len]TestVector = undefined; | |
| 36 | test "compare f64" { | |
| 96 | 37 | for (arguments[0..], 0..) |arg_i, i| { |
| 97 | 38 | for (arguments[0..], 0..) |arg_j, j| { |
| 98 | vectors[(i * arguments.len) + j] = generateVector(arg_i, arg_j); | |
| 39 | const expected_unord = i == 0 or j == 0; | |
| 40 | const expected_order: ?Order = if (expected_unord) null else switch (std.math.order( | |
| 41 | if (i >= 9) i - 1 else i, | |
| 42 | if (j >= 9) j - 1 else j, | |
| 43 | )) { | |
| 44 | .lt => .lt, | |
| 45 | .eq => .eq, | |
| 46 | .gt => .gt, | |
| 47 | }; | |
| 48 | try std.testing.expect(expected_order == cmp_f64(arg_i, arg_j)); | |
| 49 | try std.testing.expect(expected_unord == unord_f64(arg_i, arg_j)); | |
| 99 | 50 | } |
| 100 | 51 | } |
| 101 | break :init vectors; | |
| 102 | }; | |
| 103 | ||
| 104 | test "compare f64" { | |
| 105 | for (test_vectors) |vector| { | |
| 106 | try std.testing.expect(test__cmpdf2(vector)); | |
| 107 | } | |
| 108 | 52 | } |
lib/compiler_rt/comparef.zig+274-167| ... | ... | @@ -1,163 +1,309 @@ |
| 1 | const builtin = @import("builtin"); | |
| 1 | 2 | const std = @import("std"); |
| 2 | 3 | |
| 3 | 4 | const compiler_rt = @import("../compiler_rt.zig"); |
| 4 | 5 | const symbol = compiler_rt.symbol; |
| 5 | 6 | |
| 6 | comptime { | |
| 7 | if (compiler_rt.want_aeabi) { | |
| 8 | symbol(&__aeabi_fcmpun, "__aeabi_fcmpun"); | |
| 9 | } else { | |
| 10 | symbol(&__unordsf2, "__unordsf2"); | |
| 11 | } | |
| 12 | ||
| 13 | symbol(&__unordxf2, "__unordxf2"); | |
| 7 | const Unordered = if (builtin.cpu.arch == .avr) | |
| 8 | i8 | |
| 9 | else if (builtin.cpu.arch.isAARCH64()) | |
| 10 | i32 | |
| 11 | else if (builtin.target.cTypeBitSize(.long) >= builtin.target.ptrBitWidth()) | |
| 12 | c_long | |
| 13 | else | |
| 14 | c_longlong; | |
| 15 | pub const Order = enum(Unordered) { lt = -1, eq = 0, gt = 1 }; | |
| 16 | const SparcOrder = enum(i32) { eq = 0, lt = 1, gt = 2, un = 3 }; | |
| 14 | 17 | |
| 15 | symbol(&__eqhf2, "__eqhf2"); | |
| 16 | symbol(&__nehf2, "__nehf2"); | |
| 17 | symbol(&__lehf2, "__lehf2"); | |
| 18 | comptime { | |
| 18 | 19 | symbol(&__cmphf2, "__cmphf2"); |
| 19 | symbol(&__lthf2, "__lthf2"); | |
| 20 | symbol(&__cmphf2, "__eqhf2"); | |
| 21 | symbol(&__cmphf2, "__nehf2"); | |
| 22 | symbol(&__cmphf2, "__lthf2"); | |
| 23 | symbol(&__cmphf2, "__lehf2"); | |
| 24 | symbol(&__gehf2, "__gthf2"); | |
| 25 | symbol(&__gehf2, "__gehf2"); | |
| 26 | symbol(&__unordhf2, "__unordhf2"); | |
| 20 | 27 | |
| 21 | 28 | if (compiler_rt.want_aeabi) { |
| 22 | 29 | symbol(&__aeabi_fcmpeq, "__aeabi_fcmpeq"); |
| 23 | 30 | symbol(&__aeabi_fcmplt, "__aeabi_fcmplt"); |
| 24 | 31 | symbol(&__aeabi_fcmple, "__aeabi_fcmple"); |
| 32 | symbol(&__aeabi_fcmpgt, "__aeabi_fcmpgt"); | |
| 33 | symbol(&__aeabi_fcmpge, "__aeabi_fcmpge"); | |
| 34 | symbol(&__aeabi_fcmpun, "__aeabi_fcmpun"); | |
| 35 | ||
| 36 | symbol(&__aeabi_dcmpeq, "__aeabi_dcmpeq"); | |
| 37 | symbol(&__aeabi_dcmplt, "__aeabi_dcmplt"); | |
| 38 | symbol(&__aeabi_dcmple, "__aeabi_dcmple"); | |
| 39 | symbol(&__aeabi_dcmpgt, "__aeabi_dcmpgt"); | |
| 40 | symbol(&__aeabi_dcmpge, "__aeabi_dcmpge"); | |
| 41 | symbol(&__aeabi_dcmpun, "__aeabi_dcmpun"); | |
| 25 | 42 | } else { |
| 26 | symbol(&__eqsf2, "__eqsf2"); | |
| 27 | symbol(&__nesf2, "__nesf2"); | |
| 28 | symbol(&__lesf2, "__lesf2"); | |
| 29 | 43 | symbol(&__cmpsf2, "__cmpsf2"); |
| 30 | symbol(&__ltsf2, "__ltsf2"); | |
| 44 | symbol(&__cmpsf2, "__eqsf2"); | |
| 45 | symbol(&__cmpsf2, "__nesf2"); | |
| 46 | symbol(&__cmpsf2, "__ltsf2"); | |
| 47 | symbol(&__cmpsf2, "__lesf2"); | |
| 48 | symbol(&__gesf2, "__gtsf2"); | |
| 49 | symbol(&__gesf2, "__gesf2"); | |
| 50 | symbol(&__unordsf2, "__unordsf2"); | |
| 51 | ||
| 52 | symbol(&__cmpdf2, "__cmpdf2"); | |
| 53 | symbol(&__cmpdf2, "__eqdf2"); | |
| 54 | symbol(&__cmpdf2, "__nedf2"); | |
| 55 | symbol(&__cmpdf2, "__ltdf2"); | |
| 56 | symbol(&__cmpdf2, "__ledf2"); | |
| 57 | symbol(&__gedf2, "__gtdf2"); | |
| 58 | symbol(&__gedf2, "__gedf2"); | |
| 59 | symbol(&__unorddf2, "__unorddf2"); | |
| 31 | 60 | } |
| 32 | 61 | |
| 62 | symbol(&__cmpxf2, "__cmpxf2"); | |
| 63 | symbol(&__cmpxf2, "__eqxf2"); | |
| 64 | symbol(&__cmpxf2, "__nexf2"); | |
| 65 | symbol(&__cmpxf2, "__ltxf2"); | |
| 66 | symbol(&__cmpxf2, "__lexf2"); | |
| 67 | symbol(&__gexf2, "__gtxf2"); | |
| 68 | symbol(&__gexf2, "__gexf2"); | |
| 69 | symbol(&__unordxf2, "__unordxf2"); | |
| 70 | ||
| 33 | 71 | if (compiler_rt.want_ppc_abi) { |
| 72 | symbol(&__cmptf2, "__eqkf2"); | |
| 73 | symbol(&__cmptf2, "__nekf2"); | |
| 74 | symbol(&__cmptf2, "__ltkf2"); | |
| 75 | symbol(&__cmptf2, "__lekf2"); | |
| 76 | symbol(&__getf2, "__gtkf2"); | |
| 77 | symbol(&__getf2, "__gekf2"); | |
| 34 | 78 | symbol(&__unordtf2, "__unordkf2"); |
| 79 | } else if (compiler_rt.want_sparc64_abi) { | |
| 80 | symbol(&_Qp_cmp, "_Qp_cmp"); | |
| 81 | symbol(&_Qp_feq, "_Qp_feq"); | |
| 82 | symbol(&_Qp_fne, "_Qp_fne"); | |
| 83 | symbol(&_Qp_flt, "_Qp_flt"); | |
| 84 | symbol(&_Qp_fle, "_Qp_fle"); | |
| 85 | symbol(&_Qp_fgt, "_Qp_fgt"); | |
| 86 | symbol(&_Qp_fge, "_Qp_fge"); | |
| 87 | } else if (compiler_rt.want_sparc32_abi) { | |
| 88 | symbol(&_Q_cmp, "_Q_cmp"); | |
| 89 | symbol(&_Q_feq, "_Q_feq"); | |
| 90 | symbol(&_Q_fne, "_Q_fne"); | |
| 91 | symbol(&_Q_flt, "_Q_flt"); | |
| 92 | symbol(&_Q_fle, "_Q_fle"); | |
| 93 | symbol(&_Q_fgt, "_Q_fgt"); | |
| 94 | symbol(&_Q_fge, "_Q_fge"); | |
| 95 | } else { | |
| 96 | symbol(&__cmptf2, "__cmptf2"); | |
| 97 | symbol(&__cmptf2, "__eqtf2"); | |
| 98 | symbol(&__cmptf2, "__netf2"); | |
| 99 | symbol(&__cmptf2, "__lttf2"); | |
| 100 | symbol(&__cmptf2, "__letf2"); | |
| 101 | symbol(&__getf2, "__gttf2"); | |
| 102 | symbol(&__getf2, "__getf2"); | |
| 103 | symbol(&__unordtf2, "__unordtf2"); | |
| 35 | 104 | } |
| 36 | symbol(&__unordtf2, "__unordtf2"); | |
| 37 | symbol(&__unordhf2, "__unordhf2"); | |
| 38 | } | |
| 39 | ||
| 40 | pub fn __unordhf2(a: f16, b: f16) callconv(.c) i32 { | |
| 41 | return unordcmp(f16, a, b); | |
| 42 | 105 | } |
| 43 | 106 | |
| 44 | pub fn __unordtf2(a: f128, b: f128) callconv(.c) i32 { | |
| 45 | return unordcmp(f128, a, b); | |
| 107 | fn __cmphf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Order { | |
| 108 | return cmp_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)) orelse .gt; | |
| 46 | 109 | } |
| 47 | ||
| 48 | /// "These functions calculate a <=> b. That is, if a is less than b, they return -1; | |
| 49 | /// if a is greater than b, they return 1; and if a and b are equal they return 0. | |
| 50 | /// If either argument is NaN they return 1..." | |
| 51 | /// | |
| 52 | /// Note that this matches the definition of `__lesf2`, `__eqsf2`, `__nesf2`, `__cmpsf2`, | |
| 53 | /// and `__ltsf2`. | |
| 54 | fn __cmpsf2(a: f32, b: f32) callconv(.c) i32 { | |
| 55 | return @backingInt(cmpf2(f32, LE, a, b)); | |
| 110 | fn __gehf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Order { | |
| 111 | return cmp_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)) orelse .lt; | |
| 56 | 112 | } |
| 57 | ||
| 58 | /// "These functions return a value less than or equal to zero if neither argument is NaN, | |
| 59 | /// and a is less than or equal to b." | |
| 60 | pub fn __lesf2(a: f32, b: f32) callconv(.c) i32 { | |
| 61 | return __cmpsf2(a, b); | |
| 113 | fn __unordhf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Unordered { | |
| 114 | return @intFromBool(unord_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); | |
| 62 | 115 | } |
| 63 | ||
| 64 | /// "These functions return zero if neither argument is NaN, and a and b are equal." | |
| 65 | /// Note that due to some kind of historical accident, __eqsf2 and __nesf2 are defined | |
| 66 | /// to have the same return value. | |
| 67 | pub fn __eqsf2(a: f32, b: f32) callconv(.c) i32 { | |
| 68 | return __cmpsf2(a, b); | |
| 116 | pub fn cmp_f16(a: f16, b: f16) ?Order { | |
| 117 | return cmpf2(f16, a, b); | |
| 69 | 118 | } |
| 70 | ||
| 71 | /// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." | |
| 72 | /// Note that due to some kind of historical accident, __eqsf2 and __nesf2 are defined | |
| 73 | /// to have the same return value. | |
| 74 | pub fn __nesf2(a: f32, b: f32) callconv(.c) i32 { | |
| 75 | return __cmpsf2(a, b); | |
| 119 | pub fn unord_f16(a: f16, b: f16) bool { | |
| 120 | return unord(f16, a, b); | |
| 76 | 121 | } |
| 77 | 122 | |
| 78 | /// "These functions return a value less than zero if neither argument is NaN, and a | |
| 79 | /// is strictly less than b." | |
| 80 | pub fn __ltsf2(a: f32, b: f32) callconv(.c) i32 { | |
| 81 | return __cmpsf2(a, b); | |
| 123 | fn __cmpsf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Order { | |
| 124 | return cmp_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)) orelse .gt; | |
| 82 | 125 | } |
| 83 | ||
| 84 | 126 | fn __aeabi_fcmpeq(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { |
| 85 | return @intFromBool(cmpf2(f32, LE, a, b) == .Equal); | |
| 127 | return @intFromBool(cmp_f32(a, b) == .eq); | |
| 86 | 128 | } |
| 87 | ||
| 88 | 129 | fn __aeabi_fcmplt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { |
| 89 | return @intFromBool(cmpf2(f32, LE, a, b) == .Less); | |
| 130 | return @intFromBool(cmp_f32(a, b) == .lt); | |
| 90 | 131 | } |
| 91 | ||
| 92 | 132 | fn __aeabi_fcmple(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { |
| 93 | return @intFromBool(cmpf2(f32, LE, a, b) != .Greater); | |
| 133 | return @intFromBool(cmp_f32(a, b) orelse .gt != .gt); | |
| 94 | 134 | } |
| 95 | ||
| 96 | /// "These functions calculate a <=> b. That is, if a is less than b, they return -1; | |
| 97 | /// if a is greater than b, they return 1; and if a and b are equal they return 0. | |
| 98 | /// If either argument is NaN they return 1..." | |
| 99 | /// | |
| 100 | /// Note that this matches the definition of `__lehf2`, `__eqhf2`, `__nehf2`, `__cmphf2`, | |
| 101 | /// and `__lthf2`. | |
| 102 | fn __cmphf2(a: f16, b: f16) callconv(.c) i32 { | |
| 103 | return @backingInt(cmpf2(f16, LE, a, b)); | |
| 135 | fn __gesf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Order { | |
| 136 | return cmp_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)) orelse .lt; | |
| 104 | 137 | } |
| 105 | ||
| 106 | /// "These functions return a value less than or equal to zero if neither argument is NaN, | |
| 107 | /// and a is less than or equal to b." | |
| 108 | fn __lehf2(a: f16, b: f16) callconv(.c) i32 { | |
| 109 | return __cmphf2(a, b); | |
| 138 | fn __aeabi_fcmpge(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 139 | return @intFromBool(cmp_f32(a, b) orelse .lt != .lt); | |
| 110 | 140 | } |
| 111 | ||
| 112 | /// "These functions return zero if neither argument is NaN, and a and b are equal." | |
| 113 | /// Note that due to some kind of historical accident, __eqhf2 and __nehf2 are defined | |
| 114 | /// to have the same return value. | |
| 115 | fn __eqhf2(a: f16, b: f16) callconv(.c) i32 { | |
| 116 | return __cmphf2(a, b); | |
| 141 | fn __aeabi_fcmpgt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 142 | return @intFromBool(cmp_f32(a, b) == .gt); | |
| 117 | 143 | } |
| 118 | ||
| 119 | /// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." | |
| 120 | /// Note that due to some kind of historical accident, __eqhf2 and __nehf2 are defined | |
| 121 | /// to have the same return value. | |
| 122 | fn __nehf2(a: f16, b: f16) callconv(.c) i32 { | |
| 123 | return __cmphf2(a, b); | |
| 144 | fn __unordsf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Unordered { | |
| 145 | return @intFromBool(unord_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); | |
| 124 | 146 | } |
| 125 | ||
| 126 | /// "These functions return a value less than zero if neither argument is NaN, and a | |
| 127 | /// is strictly less than b." | |
| 128 | fn __lthf2(a: f16, b: f16) callconv(.c) i32 { | |
| 129 | return __cmphf2(a, b); | |
| 147 | fn __aeabi_fcmpun(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 148 | return @intFromBool(unord_f32(a, b)); | |
| 130 | 149 | } |
| 131 | ||
| 132 | fn __unordxf2(a: f80, b: f80) callconv(.c) i32 { | |
| 133 | return unordcmp(f80, a, b); | |
| 150 | pub fn cmp_f32(a: f32, b: f32) ?Order { | |
| 151 | return cmpf2(f32, a, b); | |
| 152 | } | |
| 153 | pub fn unord_f32(a: f32, b: f32) bool { | |
| 154 | return unord(f32, a, b); | |
| 134 | 155 | } |
| 135 | 156 | |
| 136 | pub fn __unordsf2(a: f32, b: f32) callconv(.c) i32 { | |
| 137 | return unordcmp(f32, a, b); | |
| 157 | fn __cmpdf2(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) Order { | |
| 158 | return cmp_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)) orelse .gt; | |
| 159 | } | |
| 160 | fn __aeabi_dcmpeq(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 161 | return @intFromBool(cmp_f64(a, b) == .eq); | |
| 162 | } | |
| 163 | fn __aeabi_dcmplt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 164 | return @intFromBool(cmp_f64(a, b) == .lt); | |
| 165 | } | |
| 166 | fn __aeabi_dcmple(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 167 | return @intFromBool(cmp_f64(a, b) orelse .gt != .gt); | |
| 168 | } | |
| 169 | fn __gedf2(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) Order { | |
| 170 | return cmp_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)) orelse .lt; | |
| 171 | } | |
| 172 | fn __aeabi_dcmpge(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 173 | return @intFromBool(cmp_f64(a, b) orelse .lt != .lt); | |
| 174 | } | |
| 175 | fn __aeabi_dcmpgt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 176 | return @intFromBool(cmp_f64(a, b) == .gt); | |
| 177 | } | |
| 178 | fn __unorddf2(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) Unordered { | |
| 179 | return @intFromBool(unord_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); | |
| 180 | } | |
| 181 | fn __aeabi_dcmpun(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 182 | return @intFromBool(unord_f64(a, b)); | |
| 183 | } | |
| 184 | pub fn cmp_f64(a: f64, b: f64) ?Order { | |
| 185 | return cmpf2(f64, a, b); | |
| 186 | } | |
| 187 | pub fn unord_f64(a: f64, b: f64) bool { | |
| 188 | return unord(f64, a, b); | |
| 138 | 189 | } |
| 139 | 190 | |
| 140 | fn __aeabi_fcmpun(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 141 | return unordcmp(f32, a, b); | |
| 191 | fn __cmpxf2(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) Order { | |
| 192 | return cmp_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b)) orelse .gt; | |
| 193 | } | |
| 194 | fn __gexf2(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) Order { | |
| 195 | return cmp_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b)) orelse .lt; | |
| 142 | 196 | } |
| 197 | fn __unordxf2(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) Unordered { | |
| 198 | return @intFromBool(unord_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); | |
| 199 | } | |
| 200 | pub fn cmp_f80(a: f80, b: f80) ?Order { | |
| 201 | const a_rep = std.math.F80.fromFloat(a); | |
| 202 | const b_rep = std.math.F80.fromFloat(b); | |
| 203 | const sig_bits = std.math.floatMantissaBits(f80); | |
| 204 | const int_bit = 0x8000000000000000; | |
| 205 | const sign_bit = 0x8000; | |
| 206 | const special_exp = 0x7FFF; | |
| 143 | 207 | |
| 144 | pub const LE = enum(i32) { | |
| 145 | Less = -1, | |
| 146 | Equal = 0, | |
| 147 | Greater = 1, | |
| 208 | // If either a or b is NaN, they are unordered. | |
| 209 | if ((a_rep.exp & special_exp == special_exp and a_rep.fraction ^ int_bit != 0) or | |
| 210 | (b_rep.exp & special_exp == special_exp and b_rep.fraction ^ int_bit != 0)) | |
| 211 | return null; | |
| 148 | 212 | |
| 149 | const Unordered: LE = .Greater; | |
| 150 | }; | |
| 213 | // If a and b are both zeros, they are equal. | |
| 214 | if ((a_rep.fraction | b_rep.fraction) | ((a_rep.exp | b_rep.exp) & special_exp) == 0) | |
| 215 | return .eq; | |
| 151 | 216 | |
| 152 | pub const GE = enum(i32) { | |
| 153 | Less = -1, | |
| 154 | Equal = 0, | |
| 155 | Greater = 1, | |
| 217 | if (@intFromBool(a_rep.exp == b_rep.exp) & @intFromBool(a_rep.fraction == b_rep.fraction) != 0) { | |
| 218 | return .eq; | |
| 219 | } else if (a_rep.exp & sign_bit != b_rep.exp & sign_bit) { | |
| 220 | // signs are different | |
| 221 | if (@as(i16, @bitCast(a_rep.exp)) < @as(i16, @bitCast(b_rep.exp))) { | |
| 222 | return .lt; | |
| 223 | } else { | |
| 224 | return .gt; | |
| 225 | } | |
| 226 | } else { | |
| 227 | const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits); | |
| 228 | const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits); | |
| 229 | if ((a_fraction < b_fraction) == (a_rep.exp & sign_bit == 0)) { | |
| 230 | return .lt; | |
| 231 | } else { | |
| 232 | return .gt; | |
| 233 | } | |
| 234 | } | |
| 235 | } | |
| 236 | pub fn unord_f80(a: f80, b: f80) bool { | |
| 237 | return unord(f80, a, b); | |
| 238 | } | |
| 156 | 239 | |
| 157 | const Unordered: GE = .Less; | |
| 158 | }; | |
| 240 | fn __cmptf2(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) Order { | |
| 241 | return cmp_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)) orelse .gt; | |
| 242 | } | |
| 243 | fn __getf2(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) Order { | |
| 244 | return cmp_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)) orelse .lt; | |
| 245 | } | |
| 246 | fn __unordtf2(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) Unordered { | |
| 247 | return @intFromBool(unord_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); | |
| 248 | } | |
| 249 | fn _Qp_cmp(a: *const f128, b: *const f128) callconv(.c) SparcOrder { | |
| 250 | return switch (cmp_f128(a.*, b.*) orelse return .un) { | |
| 251 | .lt => .lt, | |
| 252 | .eq => .eq, | |
| 253 | .gt => .gt, | |
| 254 | }; | |
| 255 | } | |
| 256 | fn _Qp_feq(a: *const f128, b: *const f128) callconv(.c) i32 { | |
| 257 | return @intFromBool(cmp_f128(a.*, b.*) == .eq); | |
| 258 | } | |
| 259 | fn _Qp_fne(a: *const f128, b: *const f128) callconv(.c) i32 { | |
| 260 | return @intFromBool(cmp_f128(a.*, b.*) != .eq); | |
| 261 | } | |
| 262 | fn _Qp_flt(a: *const f128, b: *const f128) callconv(.c) i32 { | |
| 263 | return @intFromBool(cmp_f128(a.*, b.*) == .lt); | |
| 264 | } | |
| 265 | fn _Qp_fle(a: *const f128, b: *const f128) callconv(.c) i32 { | |
| 266 | return @intFromBool((cmp_f128(a.*, b.*) orelse .gt) != .gt); | |
| 267 | } | |
| 268 | fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.c) i32 { | |
| 269 | return @intFromBool(cmp_f128(a.*, b.*) == .gt); | |
| 270 | } | |
| 271 | fn _Qp_fge(a: *const f128, b: *const f128) callconv(.c) i32 { | |
| 272 | return @intFromBool((cmp_f128(a.*, b.*) orelse .lt) != .lt); | |
| 273 | } | |
| 274 | fn _Q_cmp(a: f128, b: f128) callconv(.c) SparcOrder { | |
| 275 | return switch (cmp_f128(a, b) orelse return .un) { | |
| 276 | .lt => .lt, | |
| 277 | .eq => .eq, | |
| 278 | .gt => .gt, | |
| 279 | }; | |
| 280 | } | |
| 281 | fn _Q_feq(a: f128, b: f128) callconv(.c) i32 { | |
| 282 | return @intFromBool(cmp_f128(a, b) == .eq); | |
| 283 | } | |
| 284 | fn _Q_fne(a: f128, b: f128) callconv(.c) i32 { | |
| 285 | return @intFromBool(cmp_f128(a, b) != .eq); | |
| 286 | } | |
| 287 | fn _Q_flt(a: f128, b: f128) callconv(.c) i32 { | |
| 288 | return @intFromBool(cmp_f128(a, b) == .lt); | |
| 289 | } | |
| 290 | fn _Q_fle(a: f128, b: f128) callconv(.c) i32 { | |
| 291 | return @intFromBool((cmp_f128(a, b) orelse .gt) != .gt); | |
| 292 | } | |
| 293 | fn _Q_fgt(a: f128, b: f128) callconv(.c) i32 { | |
| 294 | return @intFromBool(cmp_f128(a, b) == .gt); | |
| 295 | } | |
| 296 | fn _Q_fge(a: f128, b: f128) callconv(.c) i32 { | |
| 297 | return @intFromBool((cmp_f128(a, b) orelse .lt) != .lt); | |
| 298 | } | |
| 299 | pub fn cmp_f128(a: f128, b: f128) ?Order { | |
| 300 | return cmpf2(f128, a, b); | |
| 301 | } | |
| 302 | pub fn unord_f128(a: f128, b: f128) bool { | |
| 303 | return unord(f128, a, b); | |
| 304 | } | |
| 159 | 305 | |
| 160 | pub inline fn cmpf2(comptime T: type, comptime RT: type, a: T, b: T) RT { | |
| 306 | inline fn cmpf2(comptime T: type, a: T, b: T) ?Order { | |
| 161 | 307 | const bits = @typeInfo(T).float.bits; |
| 162 | 308 | const srep_t = @Int(.signed, bits); |
| 163 | 309 | const rep_t = @Int(.unsigned, bits); |
| ... | ... | @@ -175,81 +321,42 @@ pub inline fn cmpf2(comptime T: type, comptime RT: type, a: T, b: T) RT { |
| 175 | 321 | const bAbs = @as(rep_t, @bitCast(bInt)) & absMask; |
| 176 | 322 | |
| 177 | 323 | // If either a or b is NaN, they are unordered. |
| 178 | if (aAbs > infRep or bAbs > infRep) return RT.Unordered; | |
| 324 | if (aAbs > infRep or bAbs > infRep) return null; | |
| 179 | 325 | |
| 180 | 326 | // If a and b are both zeros, they are equal. |
| 181 | if ((aAbs | bAbs) == 0) return .Equal; | |
| 327 | if ((aAbs | bAbs) == 0) return .eq; | |
| 182 | 328 | |
| 183 | 329 | // If at least one of a and b is positive, we get the same result comparing |
| 184 | 330 | // a and b as signed integers as we would with a floating-point compare. |
| 185 | 331 | if ((aInt & bInt) >= 0) { |
| 186 | 332 | if (aInt < bInt) { |
| 187 | return .Less; | |
| 333 | return .lt; | |
| 188 | 334 | } else if (aInt == bInt) { |
| 189 | return .Equal; | |
| 190 | } else return .Greater; | |
| 335 | return .eq; | |
| 336 | } else return .gt; | |
| 191 | 337 | } else { |
| 192 | 338 | // Otherwise, both are negative, so we need to flip the sense of the |
| 193 | 339 | // comparison to get the correct result. (This assumes a twos- or ones- |
| 194 | 340 | // complement integer representation; if integers are represented in a |
| 195 | 341 | // sign-magnitude representation, then this flip is incorrect). |
| 196 | 342 | if (aInt > bInt) { |
| 197 | return .Less; | |
| 343 | return .lt; | |
| 198 | 344 | } else if (aInt == bInt) { |
| 199 | return .Equal; | |
| 200 | } else return .Greater; | |
| 345 | return .eq; | |
| 346 | } else return .gt; | |
| 201 | 347 | } |
| 202 | 348 | } |
| 203 | 349 | |
| 204 | pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT { | |
| 205 | const a_rep = std.math.F80.fromFloat(a); | |
| 206 | const b_rep = std.math.F80.fromFloat(b); | |
| 207 | const sig_bits = std.math.floatMantissaBits(f80); | |
| 208 | const int_bit = 0x8000000000000000; | |
| 209 | const sign_bit = 0x8000; | |
| 210 | const special_exp = 0x7FFF; | |
| 211 | ||
| 212 | // If either a or b is NaN, they are unordered. | |
| 213 | if ((a_rep.exp & special_exp == special_exp and a_rep.fraction ^ int_bit != 0) or | |
| 214 | (b_rep.exp & special_exp == special_exp and b_rep.fraction ^ int_bit != 0)) | |
| 215 | return RT.Unordered; | |
| 216 | ||
| 217 | // If a and b are both zeros, they are equal. | |
| 218 | if ((a_rep.fraction | b_rep.fraction) | ((a_rep.exp | b_rep.exp) & special_exp) == 0) | |
| 219 | return .Equal; | |
| 220 | ||
| 221 | if (@intFromBool(a_rep.exp == b_rep.exp) & @intFromBool(a_rep.fraction == b_rep.fraction) != 0) { | |
| 222 | return .Equal; | |
| 223 | } else if (a_rep.exp & sign_bit != b_rep.exp & sign_bit) { | |
| 224 | // signs are different | |
| 225 | if (@as(i16, @bitCast(a_rep.exp)) < @as(i16, @bitCast(b_rep.exp))) { | |
| 226 | return .Less; | |
| 227 | } else { | |
| 228 | return .Greater; | |
| 229 | } | |
| 230 | } else { | |
| 231 | const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits); | |
| 232 | const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits); | |
| 233 | if ((a_fraction < b_fraction) == (a_rep.exp & sign_bit == 0)) { | |
| 234 | return .Less; | |
| 235 | } else { | |
| 236 | return .Greater; | |
| 237 | } | |
| 238 | } | |
| 239 | } | |
| 240 | ||
| 241 | test "cmp_f80" { | |
| 242 | inline for (.{ LE, GE }) |RT| { | |
| 243 | try std.testing.expect(cmp_f80(RT, 1.0, 1.0) == RT.Equal); | |
| 244 | try std.testing.expect(cmp_f80(RT, 0.0, -0.0) == RT.Equal); | |
| 245 | try std.testing.expect(cmp_f80(RT, 2.0, 4.0) == RT.Less); | |
| 246 | try std.testing.expect(cmp_f80(RT, 2.0, -4.0) == RT.Greater); | |
| 247 | try std.testing.expect(cmp_f80(RT, -2.0, -4.0) == RT.Greater); | |
| 248 | try std.testing.expect(cmp_f80(RT, -2.0, 4.0) == RT.Less); | |
| 249 | } | |
| 350 | test cmp_f80 { | |
| 351 | try std.testing.expect(cmp_f80(1.0, 1.0) == .eq); | |
| 352 | try std.testing.expect(cmp_f80(0.0, -0.0) == .eq); | |
| 353 | try std.testing.expect(cmp_f80(2.0, 4.0) == .lt); | |
| 354 | try std.testing.expect(cmp_f80(2.0, -4.0) == .gt); | |
| 355 | try std.testing.expect(cmp_f80(-2.0, -4.0) == .gt); | |
| 356 | try std.testing.expect(cmp_f80(-2.0, 4.0) == .lt); | |
| 250 | 357 | } |
| 251 | 358 | |
| 252 | pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 { | |
| 359 | inline fn unord(comptime T: type, a: T, b: T) bool { | |
| 253 | 360 | const rep_t = @Int(.unsigned, @typeInfo(T).float.bits); |
| 254 | 361 | |
| 255 | 362 | const significandBits = std.math.floatMantissaBits(T); |
| ... | ... | @@ -261,7 +368,7 @@ pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 { |
| 261 | 368 | const aAbs: rep_t = @as(rep_t, @bitCast(a)) & absMask; |
| 262 | 369 | const bAbs: rep_t = @as(rep_t, @bitCast(b)) & absMask; |
| 263 | 370 | |
| 264 | return @intFromBool(aAbs > infRep or bAbs > infRep); | |
| 371 | return aAbs > infRep or bAbs > infRep; | |
| 265 | 372 | } |
| 266 | 373 | |
| 267 | 374 | test { |
lib/compiler_rt/comparesf2_test.zig+17-73| ... | ... | @@ -5,52 +5,12 @@ |
| 5 | 5 | const std = @import("std"); |
| 6 | 6 | const builtin = @import("builtin"); |
| 7 | 7 | |
| 8 | const __eqsf2 = @import("./comparef.zig").__eqsf2; | |
| 9 | const __lesf2 = @import("./comparef.zig").__lesf2; | |
| 10 | const __ltsf2 = @import("./comparef.zig").__ltsf2; | |
| 11 | const __nesf2 = @import("./comparef.zig").__nesf2; | |
| 8 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 12 | 9 | |
| 13 | const __gesf2 = @import("./gesf2.zig").__gesf2; | |
| 14 | const __gtsf2 = @import("./gesf2.zig").__gtsf2; | |
| 15 | ||
| 16 | const __unordsf2 = @import("./comparef.zig").__unordsf2; | |
| 17 | ||
| 18 | const TestVector = struct { | |
| 19 | a: f32, | |
| 20 | b: f32, | |
| 21 | eqReference: c_int, | |
| 22 | geReference: c_int, | |
| 23 | gtReference: c_int, | |
| 24 | leReference: c_int, | |
| 25 | ltReference: c_int, | |
| 26 | neReference: c_int, | |
| 27 | unReference: c_int, | |
| 28 | }; | |
| 29 | ||
| 30 | fn test__cmpsf2(vector: TestVector) bool { | |
| 31 | if (__eqsf2(vector.a, vector.b) != vector.eqReference) { | |
| 32 | return false; | |
| 33 | } | |
| 34 | if (__gesf2(vector.a, vector.b) != vector.geReference) { | |
| 35 | return false; | |
| 36 | } | |
| 37 | if (__gtsf2(vector.a, vector.b) != vector.gtReference) { | |
| 38 | return false; | |
| 39 | } | |
| 40 | if (__lesf2(vector.a, vector.b) != vector.leReference) { | |
| 41 | return false; | |
| 42 | } | |
| 43 | if (__ltsf2(vector.a, vector.b) != vector.ltReference) { | |
| 44 | return false; | |
| 45 | } | |
| 46 | if (__nesf2(vector.a, vector.b) != vector.neReference) { | |
| 47 | return false; | |
| 48 | } | |
| 49 | if (__unordsf2(vector.a, vector.b) != vector.unReference) { | |
| 50 | return false; | |
| 51 | } | |
| 52 | return true; | |
| 53 | } | |
| 10 | const impl = @import("comparef.zig"); | |
| 11 | const Order = impl.Order; | |
| 12 | const cmp_f32 = impl.cmp_f32; | |
| 13 | const unord_f32 = impl.unord_f32; | |
| 54 | 14 | |
| 55 | 15 | const arguments = [_]f32{ |
| 56 | 16 | std.math.nan(f32), |
| ... | ... | @@ -73,36 +33,20 @@ const arguments = [_]f32{ |
| 73 | 33 | std.math.inf(f32), |
| 74 | 34 | }; |
| 75 | 35 | |
| 76 | fn generateVector(comptime a: f32, comptime b: f32) TestVector { | |
| 77 | const leResult = if (a < b) -1 else if (a == b) 0 else 1; | |
| 78 | const geResult = if (a > b) 1 else if (a == b) 0 else -1; | |
| 79 | const unResult = if (a != a or b != b) 1 else 0; | |
| 80 | return TestVector{ | |
| 81 | .a = a, | |
| 82 | .b = b, | |
| 83 | .eqReference = leResult, | |
| 84 | .geReference = geResult, | |
| 85 | .gtReference = geResult, | |
| 86 | .leReference = leResult, | |
| 87 | .ltReference = leResult, | |
| 88 | .neReference = leResult, | |
| 89 | .unReference = unResult, | |
| 90 | }; | |
| 91 | } | |
| 92 | ||
| 93 | const test_vectors = init: { | |
| 94 | @setEvalBranchQuota(10000); | |
| 95 | var vectors: [arguments.len * arguments.len]TestVector = undefined; | |
| 36 | test "compare f32" { | |
| 96 | 37 | for (arguments[0..], 0..) |arg_i, i| { |
| 97 | 38 | for (arguments[0..], 0..) |arg_j, j| { |
| 98 | vectors[(i * arguments.len) + j] = generateVector(arg_i, arg_j); | |
| 39 | const expected_unord = i == 0 or j == 0; | |
| 40 | const expected_order: ?Order = if (expected_unord) null else switch (std.math.order( | |
| 41 | i - @intFromBool(i >= 9), | |
| 42 | j - @intFromBool(j >= 9), | |
| 43 | )) { | |
| 44 | .lt => .lt, | |
| 45 | .eq => .eq, | |
| 46 | .gt => .gt, | |
| 47 | }; | |
| 48 | try std.testing.expect(expected_order == cmp_f32(arg_i, arg_j)); | |
| 49 | try std.testing.expect(expected_unord == unord_f32(arg_i, arg_j)); | |
| 99 | 50 | } |
| 100 | 51 | } |
| 101 | break :init vectors; | |
| 102 | }; | |
| 103 | ||
| 104 | test "compare f32" { | |
| 105 | for (test_vectors) |vector| { | |
| 106 | try std.testing.expect(test__cmpsf2(vector)); | |
| 107 | } | |
| 108 | 52 | } |
lib/compiler_rt/cos.zig+64-50| ... | ... | @@ -13,31 +13,35 @@ const expect = std.testing.expect; |
| 13 | 13 | const expectApproxEqAbs = std.testing.expectApproxEqAbs; |
| 14 | 14 | |
| 15 | 15 | const compiler_rt = @import("../compiler_rt.zig"); |
| 16 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 16 | const symbol = compiler_rt.symbol; | |
| 17 | 17 | const trig = @import("trig.zig"); |
| 18 | 18 | const rem_pio2 = @import("rem_pio2.zig").rem_pio2; |
| 19 | 19 | const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; |
| 20 | 20 | const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; |
| 21 | 21 | |
| 22 | 22 | comptime { |
| 23 | symbol(&cosh, "__cosh"); | |
| 24 | symbol(&cosl, "__cosl"); | |
| 23 | symbol(&__cosh, "__cosh"); | |
| 25 | 24 | symbol(&cosf, "cosf"); |
| 26 | 25 | symbol(&cos, "cos"); |
| 27 | symbol(&cosx, "__cosx"); | |
| 28 | if (compiler_rt.want_ppc_abi) { | |
| 29 | symbol(&cosq, "cosf128"); | |
| 30 | } | |
| 26 | symbol(&__cosx, "__cosx"); | |
| 27 | if (compiler_rt.want_ppc_abi) symbol(&cosq, "cosf128"); | |
| 31 | 28 | symbol(&cosq, "cosq"); |
| 32 | 29 | symbol(&cosl, "cosl"); |
| 30 | symbol(&cosl, "__cosl"); // required by musl | |
| 33 | 31 | } |
| 34 | 32 | |
| 35 | pub fn cosh(a: f16) callconv(.c) f16 { | |
| 33 | fn __cosh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 34 | return compiler_rt.f16.toAbi(cos_f16(compiler_rt.f16.fromAbi(x))); | |
| 35 | } | |
| 36 | pub fn cos_f16(x: f16) f16 { | |
| 36 | 37 | // TODO: more efficient implementation |
| 37 | return @floatCast(cosf(a)); | |
| 38 | return @floatCast(cos_f32(x)); | |
| 38 | 39 | } |
| 39 | 40 | |
| 40 | pub fn cosf(x: f32) callconv(.c) f32 { | |
| 41 | fn cosf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 42 | return compiler_rt.f32.toAbi(cos_f32(compiler_rt.f32.fromAbi(x))); | |
| 43 | } | |
| 44 | pub fn cos_f32(x: f32) f32 { | |
| 41 | 45 | // Small multiples of pi/2 rounded to double precision. |
| 42 | 46 | const c1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 |
| 43 | 47 | const c2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 |
| ... | ... | @@ -94,7 +98,10 @@ pub fn cosf(x: f32) callconv(.c) f32 { |
| 94 | 98 | }; |
| 95 | 99 | } |
| 96 | 100 | |
| 97 | pub fn cos(x: f64) callconv(.c) f64 { | |
| 101 | fn cos(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 102 | return compiler_rt.f64.toAbi(cos_f64(compiler_rt.f64.fromAbi(x))); | |
| 103 | } | |
| 104 | pub fn cos_f64(x: f64) f64 { | |
| 98 | 105 | var ix = @as(u64, @bitCast(x)) >> 32; |
| 99 | 106 | ix &= 0x7fffffff; |
| 100 | 107 | |
| ... | ... | @@ -123,7 +130,10 @@ pub fn cos(x: f64) callconv(.c) f64 { |
| 123 | 130 | }; |
| 124 | 131 | } |
| 125 | 132 | |
| 126 | pub fn cosx(x: f80) callconv(.c) f80 { | |
| 133 | fn __cosx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 134 | return compiler_rt.f80.toAbi(cos_f80(compiler_rt.f80.fromAbi(x))); | |
| 135 | } | |
| 136 | pub fn cos_f80(x: f80) f80 { | |
| 127 | 137 | const se = ld.signExponent(x) & 0x7fff; |
| 128 | 138 | if (se == 0x7fff) { |
| 129 | 139 | return x - x; |
| ... | ... | @@ -147,7 +157,10 @@ pub fn cosx(x: f80) callconv(.c) f80 { |
| 147 | 157 | }; |
| 148 | 158 | } |
| 149 | 159 | |
| 150 | pub fn cosq(x: f128) callconv(.c) f128 { | |
| 160 | fn cosq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 161 | return compiler_rt.f128.toAbi(cos_f128(compiler_rt.f128.fromAbi(x))); | |
| 162 | } | |
| 163 | pub fn cos_f128(x: f128) f128 { | |
| 151 | 164 | const se = ld.signExponent(x) & 0x7fff; |
| 152 | 165 | if (se == 0x7fff) { |
| 153 | 166 | return x - x; |
| ... | ... | @@ -173,20 +186,21 @@ pub fn cosq(x: f128) callconv(.c) f128 { |
| 173 | 186 | |
| 174 | 187 | pub fn cosl(x: c_longdouble) callconv(.c) c_longdouble { |
| 175 | 188 | switch (@typeInfo(c_longdouble).float.bits) { |
| 176 | 64 => return cos(x), | |
| 177 | 80 => return cosx(x), | |
| 178 | 128 => return cosq(x), | |
| 179 | else => @compileError("unreachable"), | |
| 189 | 64 => return cos_f64(x), | |
| 190 | 80 => return cos_f80(x), | |
| 191 | 128 => return cos_f128(x), | |
| 192 | else => comptime unreachable, | |
| 180 | 193 | } |
| 181 | 194 | } |
| 182 | 195 | |
| 183 | 196 | fn testCosSpecial(comptime T: type) !void { |
| 184 | 197 | const f = switch (T) { |
| 185 | f32 => cosf, | |
| 186 | f64 => cos, | |
| 187 | f80 => cosx, | |
| 188 | f128 => cosq, | |
| 189 | else => @compileError("unimplemented"), | |
| 198 | f16 => cos_f16, | |
| 199 | f32 => cos_f32, | |
| 200 | f64 => cos_f64, | |
| 201 | f80 => cos_f80, | |
| 202 | f128 => cos_f128, | |
| 203 | else => comptime unreachable, | |
| 190 | 204 | }; |
| 191 | 205 | |
| 192 | 206 | try expect(f(0.0) == 1.0); |
| ... | ... | @@ -198,13 +212,13 @@ fn testCosSpecial(comptime T: type) !void { |
| 198 | 212 | |
| 199 | 213 | test "cos32.normal" { |
| 200 | 214 | const epsilon = math.floatEps(f32); |
| 201 | try expectApproxEqAbs(@as(f32, 1.0), cosf(0.0), epsilon); | |
| 202 | try expectApproxEqAbs(@as(f32, 0.9800666), cosf(0.2), epsilon); | |
| 203 | try expectApproxEqAbs(@as(f32, 0.6276231), cosf(0.8923), epsilon); | |
| 204 | try expectApproxEqAbs(@as(f32, 0.0707372), cosf(1.5), epsilon); | |
| 205 | try expectApproxEqAbs(@as(f32, 0.0707372), cosf(-1.5), epsilon); | |
| 206 | try expectApproxEqAbs(@as(f32, 0.96913195), cosf(37.45), epsilon); | |
| 207 | try expectApproxEqAbs(@as(f32, 0.40079966), cosf(89.123), epsilon); | |
| 215 | try expectApproxEqAbs(@as(f32, 1.0), cos_f32(0.0), epsilon); | |
| 216 | try expectApproxEqAbs(@as(f32, 0.9800666), cos_f32(0.2), epsilon); | |
| 217 | try expectApproxEqAbs(@as(f32, 0.6276231), cos_f32(0.8923), epsilon); | |
| 218 | try expectApproxEqAbs(@as(f32, 0.0707372), cos_f32(1.5), epsilon); | |
| 219 | try expectApproxEqAbs(@as(f32, 0.0707372), cos_f32(-1.5), epsilon); | |
| 220 | try expectApproxEqAbs(@as(f32, 0.96913195), cos_f32(37.45), epsilon); | |
| 221 | try expectApproxEqAbs(@as(f32, 0.40079966), cos_f32(89.123), epsilon); | |
| 208 | 222 | } |
| 209 | 223 | |
| 210 | 224 | test "cos32.special" { |
| ... | ... | @@ -213,13 +227,13 @@ test "cos32.special" { |
| 213 | 227 | |
| 214 | 228 | test "cos64.normal" { |
| 215 | 229 | const epsilon = math.floatEps(f64); |
| 216 | try expectApproxEqAbs(@as(f64, 1.0), cos(0.0), epsilon); | |
| 217 | try expectApproxEqAbs(@as(f64, 0.9800665778412416), cos(0.2), epsilon); | |
| 218 | try expectApproxEqAbs(@as(f64, 0.6276230983360804), cos(0.8923), epsilon); | |
| 219 | try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos(1.5), epsilon); | |
| 220 | try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos(-1.5), epsilon); | |
| 221 | try expectApproxEqAbs(@as(f64, 0.9691317730707778), cos(37.45), epsilon); | |
| 222 | try expectApproxEqAbs(@as(f64, 0.4008006809354791), cos(89.123), epsilon); | |
| 230 | try expectApproxEqAbs(@as(f64, 1.0), cos_f64(0.0), epsilon); | |
| 231 | try expectApproxEqAbs(@as(f64, 0.9800665778412416), cos_f64(0.2), epsilon); | |
| 232 | try expectApproxEqAbs(@as(f64, 0.6276230983360804), cos_f64(0.8923), epsilon); | |
| 233 | try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos_f64(1.5), epsilon); | |
| 234 | try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos_f64(-1.5), epsilon); | |
| 235 | try expectApproxEqAbs(@as(f64, 0.9691317730707778), cos_f64(37.45), epsilon); | |
| 236 | try expectApproxEqAbs(@as(f64, 0.4008006809354791), cos_f64(89.123), epsilon); | |
| 223 | 237 | } |
| 224 | 238 | |
| 225 | 239 | test "cos64.special" { |
| ... | ... | @@ -228,13 +242,13 @@ test "cos64.special" { |
| 228 | 242 | |
| 229 | 243 | test "cos80.normal" { |
| 230 | 244 | const epsilon = math.floatEps(f80); |
| 231 | try expectApproxEqAbs(@as(f80, 1.0), cosx(0.0), epsilon); | |
| 232 | try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), cosx(0.2), epsilon); | |
| 233 | try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), cosx(0.8923), epsilon); | |
| 234 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(1.5), epsilon); | |
| 235 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(-1.5), epsilon); | |
| 236 | try expectApproxEqAbs(@as(f80, 0.9691317730707771246), cosx(37.45), epsilon); | |
| 237 | try expectApproxEqAbs(@as(f80, 0.4008006809354834001), cosx(89.123), epsilon); | |
| 245 | try expectApproxEqAbs(@as(f80, 1.0), cos_f80(0.0), epsilon); | |
| 246 | try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), cos_f80(0.2), epsilon); | |
| 247 | try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), cos_f80(0.8923), epsilon); | |
| 248 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cos_f80(1.5), epsilon); | |
| 249 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cos_f80(-1.5), epsilon); | |
| 250 | try expectApproxEqAbs(@as(f80, 0.9691317730707771246), cos_f80(37.45), epsilon); | |
| 251 | try expectApproxEqAbs(@as(f80, 0.4008006809354834001), cos_f80(89.123), epsilon); | |
| 238 | 252 | } |
| 239 | 253 | |
| 240 | 254 | test "cos80.special" { |
| ... | ... | @@ -243,13 +257,13 @@ test "cos80.special" { |
| 243 | 257 | |
| 244 | 258 | test "cos128.normal" { |
| 245 | 259 | const epsilon = math.floatEps(f128); |
| 246 | try expectApproxEqAbs(@as(f128, 1.0), cosq(0.0), epsilon); | |
| 247 | try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), cosq(0.2), epsilon); | |
| 248 | try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), cosq(0.8923), epsilon); | |
| 249 | try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cosq(1.5), epsilon); | |
| 250 | try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cosq(-1.5), epsilon); | |
| 251 | try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), cosq(37.45), epsilon); | |
| 252 | try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), cosq(89.123), epsilon); | |
| 260 | try expectApproxEqAbs(@as(f128, 1.0), cos_f128(0.0), epsilon); | |
| 261 | try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), cos_f128(0.2), epsilon); | |
| 262 | try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), cos_f128(0.8923), epsilon); | |
| 263 | try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cos_f128(1.5), epsilon); | |
| 264 | try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cos_f128(-1.5), epsilon); | |
| 265 | try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), cos_f128(37.45), epsilon); | |
| 266 | try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), cos_f128(89.123), epsilon); | |
| 253 | 267 | } |
| 254 | 268 | |
| 255 | 269 | test "cos128.special" { |
lib/compiler_rt/count0bits.zig+2-1| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | const builtin = @import("builtin"); |
| 2 | 2 | const std = @import("std"); |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 4 | 5 | |
| 5 | 6 | comptime { |
| 6 | 7 | symbol(&__clzsi2, "__clzsi2"); |
lib/compiler_rt/divc3.zig+78-5| ... | ... | @@ -7,12 +7,81 @@ const maxInt = std.math.maxInt; |
| 7 | 7 | const minInt = std.math.minInt; |
| 8 | 8 | const isFinite = std.math.isFinite; |
| 9 | 9 | const copysign = std.math.copysign; |
| 10 | const Complex = @import("mulc3.zig").Complex; | |
| 10 | ||
| 11 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 12 | const symbol = compiler_rt.symbol; | |
| 13 | const Complex = compiler_rt.Complex; | |
| 14 | ||
| 15 | comptime { | |
| 16 | if (@import("builtin").zig_backend != .stage2_c) { | |
| 17 | symbol(&__divhc3, "__divhc3"); | |
| 18 | symbol(&__divsc3, "__divsc3"); | |
| 19 | symbol(&__divdc3, "__divdc3"); | |
| 20 | symbol(&__divxc3, "__divxc3"); | |
| 21 | if (compiler_rt.want_ppc_abi) { | |
| 22 | symbol(&__divtc3, "__divkc3"); | |
| 23 | } else { | |
| 24 | symbol(&__divtc3, "__divtc3"); | |
| 25 | } | |
| 26 | } | |
| 27 | } | |
| 28 | ||
| 29 | fn __divhc3(lhs_real: compiler_rt.f16.Abi, lhs_imag: compiler_rt.f16.Abi, rhs_real: compiler_rt.f16.Abi, rhs_imag: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.complex.Abi { | |
| 30 | return compiler_rt.f16.complex.toAbi(div_cf16( | |
| 31 | compiler_rt.f16.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | |
| 32 | compiler_rt.f16.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | |
| 33 | )); | |
| 34 | } | |
| 35 | pub fn div_cf16(a: Complex(f16), b: Complex(f16)) Complex(f16) { | |
| 36 | return divc3(f16, a, b); | |
| 37 | } | |
| 38 | ||
| 39 | fn __divsc3(lhs_real: compiler_rt.f32.Abi, lhs_imag: compiler_rt.f32.Abi, rhs_real: compiler_rt.f32.Abi, rhs_imag: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.complex.Abi { | |
| 40 | return compiler_rt.f32.complex.toAbi(div_cf32( | |
| 41 | compiler_rt.f32.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | |
| 42 | compiler_rt.f32.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | |
| 43 | )); | |
| 44 | } | |
| 45 | pub fn div_cf32(a: Complex(f32), b: Complex(f32)) Complex(f32) { | |
| 46 | return divc3(f32, a, b); | |
| 47 | } | |
| 48 | ||
| 49 | fn __divdc3(lhs_real: compiler_rt.f64.Abi, lhs_imag: compiler_rt.f64.Abi, rhs_real: compiler_rt.f64.Abi, rhs_imag: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.complex.Abi { | |
| 50 | return compiler_rt.f64.complex.toAbi(div_cf64( | |
| 51 | compiler_rt.f64.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | |
| 52 | compiler_rt.f64.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | |
| 53 | )); | |
| 54 | } | |
| 55 | pub fn div_cf64(a: Complex(f64), b: Complex(f64)) Complex(f64) { | |
| 56 | return divc3(f64, a, b); | |
| 57 | } | |
| 58 | ||
| 59 | fn __divxc3(lhs_real: compiler_rt.f80.Abi, lhs_imag: compiler_rt.f80.Abi, rhs_real: compiler_rt.f80.Abi, rhs_imag: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.complex.Abi { | |
| 60 | return compiler_rt.f80.complex.toAbi(div_cf80( | |
| 61 | compiler_rt.f80.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | |
| 62 | compiler_rt.f80.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | |
| 63 | )); | |
| 64 | } | |
| 65 | pub fn div_cf80(a: Complex(f80), b: Complex(f80)) Complex(f80) { | |
| 66 | return divc3(f80, a, b); | |
| 67 | } | |
| 68 | ||
| 69 | fn __divtc3(lhs_real: compiler_rt.f128.Abi, lhs_imag: compiler_rt.f128.Abi, rhs_real: compiler_rt.f128.Abi, rhs_imag: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.complex.Abi { | |
| 70 | return compiler_rt.f128.complex.toAbi(div_cf128( | |
| 71 | compiler_rt.f128.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | |
| 72 | compiler_rt.f128.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | |
| 73 | )); | |
| 74 | } | |
| 75 | pub fn div_cf128(a: Complex(f128), b: Complex(f128)) Complex(f128) { | |
| 76 | return divc3(f128, a, b); | |
| 77 | } | |
| 11 | 78 | |
| 12 | 79 | /// Implementation based on Annex G of C17 Standard (N2176) |
| 13 | pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) { | |
| 14 | var c = c_in; | |
| 15 | var d = d_in; | |
| 80 | inline fn divc3(comptime T: type, lhs: Complex(T), rhs: Complex(T)) Complex(T) { | |
| 81 | const a = lhs.real; | |
| 82 | const b = lhs.imag; | |
| 83 | var c = rhs.real; | |
| 84 | var d = rhs.imag; | |
| 16 | 85 | |
| 17 | 86 | // logbw used to prevent under/over-flow |
| 18 | 87 | const logbw = ilogb(@max(@abs(c), @abs(d))); |
| ... | ... | @@ -23,7 +92,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) { |
| 23 | 92 | break :b logbw; |
| 24 | 93 | } else 0; |
| 25 | 94 | const denom = c * c + d * d; |
| 26 | const result = Complex(T){ | |
| 95 | const result: Complex(T) = .{ | |
| 27 | 96 | .real = scalbn((a * c + b * d) / denom, -ilogbw), |
| 28 | 97 | .imag = scalbn((b * c - a * d) / denom, -ilogbw), |
| 29 | 98 | }; |
| ... | ... | @@ -58,3 +127,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) { |
| 58 | 127 | |
| 59 | 128 | return result; |
| 60 | 129 | } |
| 130 | ||
| 131 | test { | |
| 132 | _ = @import("divc3_test.zig"); | |
| 133 | } |
lib/compiler_rt/divc3_test.zig+28-51| ... | ... | @@ -2,76 +2,53 @@ const std = @import("std"); |
| 2 | 2 | const math = std.math; |
| 3 | 3 | const expect = std.testing.expect; |
| 4 | 4 | |
| 5 | const Complex = @import("./mulc3.zig").Complex; | |
| 6 | const __divhc3 = @import("./divhc3.zig").__divhc3; | |
| 7 | const __divsc3 = @import("./divsc3.zig").__divsc3; | |
| 8 | const __divdc3 = @import("./divdc3.zig").__divdc3; | |
| 9 | const __divxc3 = @import("./divxc3.zig").__divxc3; | |
| 10 | const __divtc3 = @import("./divtc3.zig").__divtc3; | |
| 5 | const Complex = @import("../compiler_rt.zig").Complex; | |
| 6 | ||
| 7 | const impl = @import("divc3.zig"); | |
| 8 | const div_cf16 = impl.div_cf16; | |
| 9 | const div_cf32 = impl.div_cf32; | |
| 10 | const div_cf64 = impl.div_cf64; | |
| 11 | const div_cf80 = impl.div_cf80; | |
| 12 | const div_cf128 = impl.div_cf128; | |
| 11 | 13 | |
| 12 | 14 | test "divc3" { |
| 13 | try testDiv(f16, __divhc3); | |
| 14 | try testDiv(f32, __divsc3); | |
| 15 | try testDiv(f64, __divdc3); | |
| 16 | try testDiv(f80, __divxc3); | |
| 17 | try testDiv(f128, __divtc3); | |
| 15 | try testDiv(f16, div_cf16); | |
| 16 | try testDiv(f32, div_cf32); | |
| 17 | try testDiv(f64, div_cf64); | |
| 18 | try testDiv(f80, div_cf80); | |
| 19 | try testDiv(f128, div_cf128); | |
| 18 | 20 | } |
| 19 | 21 | |
| 20 | fn testDiv(comptime T: type, comptime f: fn (T, T, T, T) callconv(.c) Complex(T)) !void { | |
| 22 | fn testDiv(comptime T: type, comptime f: fn (Complex(T), Complex(T)) Complex(T)) !void { | |
| 21 | 23 | { |
| 22 | const a: T = 1.0; | |
| 23 | const b: T = 0.0; | |
| 24 | const c: T = -1.0; | |
| 25 | const d: T = 0.0; | |
| 26 | ||
| 27 | const result = f(a, b, c, d); | |
| 24 | const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -1.0, .imag = 0.0 }); | |
| 28 | 25 | try expect(result.real == -1.0); |
| 29 | try expect(result.imag == 0.0); | |
| 26 | try expect(math.isNegativeZero(result.imag)); | |
| 30 | 27 | } |
| 31 | 28 | { |
| 32 | const a: T = 1.0; | |
| 33 | const b: T = 0.0; | |
| 34 | const c: T = -4.0; | |
| 35 | const d: T = 0.0; | |
| 36 | ||
| 37 | const result = f(a, b, c, d); | |
| 29 | const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -4.0, .imag = 0.0 }); | |
| 38 | 30 | try expect(result.real == -0.25); |
| 39 | try expect(result.imag == 0.0); | |
| 31 | try expect(math.isNegativeZero(result.imag)); | |
| 40 | 32 | } |
| 41 | 33 | { |
| 42 | 34 | // if the first operand is an infinity and the second operand is a finite number, then the |
| 43 | // result of the / operator is an infinity; | |
| 44 | const a: T = -math.inf(T); | |
| 45 | const b: T = 0.0; | |
| 46 | const c: T = -4.0; | |
| 47 | const d: T = 1.0; | |
| 48 | ||
| 49 | const result = f(a, b, c, d); | |
| 50 | try expect(result.real == math.inf(T)); | |
| 51 | try expect(result.imag == math.inf(T)); | |
| 35 | // resultult of the / operator is an infinity; | |
| 36 | const result = f(.{ .real = -math.inf(T), .imag = 0.0 }, .{ .real = -4.0, .imag = 1.0 }); | |
| 37 | try expect(math.isPositiveInf(result.real)); | |
| 38 | try expect(math.isPositiveInf(result.imag)); | |
| 52 | 39 | } |
| 53 | 40 | { |
| 54 | 41 | // if the first operand is a finite number and the second operand is an infinity, then the |
| 55 | 42 | // result of the / operator is a zero; |
| 56 | const a: T = 17.2; | |
| 57 | const b: T = 0.0; | |
| 58 | const c: T = -math.inf(T); | |
| 59 | const d: T = 0.0; | |
| 60 | ||
| 61 | const result = f(a, b, c, d); | |
| 62 | try expect(result.real == -0.0); | |
| 63 | try expect(result.imag == 0.0); | |
| 43 | const result = f(.{ .real = 17.2, .imag = 0.0 }, .{ .real = -math.inf(T), .imag = 0.0 }); | |
| 44 | try expect(math.isNegativeZero(result.real)); | |
| 45 | try expect(math.isNegativeZero(result.imag)); | |
| 64 | 46 | } |
| 65 | 47 | { |
| 66 | 48 | // if the first operand is a nonzero finite number or an infinity and the second operand is |
| 67 | 49 | // a zero, then the result of the / operator is an infinity |
| 68 | const a: T = 1.1; | |
| 69 | const b: T = 0.1; | |
| 70 | const c: T = 0.0; | |
| 71 | const d: T = 0.0; | |
| 72 | ||
| 73 | const result = f(a, b, c, d); | |
| 74 | try expect(result.real == math.inf(T)); | |
| 75 | try expect(result.imag == math.inf(T)); | |
| 50 | const result = f(.{ .real = 1.1, .imag = 0.1 }, .{ .real = 0.0, .imag = 0.0 }); | |
| 51 | try expect(math.isPositiveInf(result.real)); | |
| 52 | try expect(math.isPositiveInf(result.imag)); | |
| 76 | 53 | } |
| 77 | 54 | } |
lib/compiler_rt/divdc3.zig deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 2 | const divc3 = @import("./divc3.zig"); | |
| 3 | const Complex = @import("./mulc3.zig").Complex; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | |
| 7 | symbol(&__divdc3, "__divdc3"); | |
| 8 | } | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __divdc3(a: f64, b: f64, c: f64, d: f64) callconv(.c) Complex(f64) { | |
| 12 | return divc3.divc3(f64, a, b, c, d); | |
| 13 | } |
lib/compiler_rt/divdf3.zig+4-4| ... | ... | @@ -17,15 +17,15 @@ comptime { |
| 17 | 17 | } |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | pub fn __divdf3(a: f64, b: f64) callconv(.c) f64 { | |
| 21 | return div(a, b); | |
| 20 | fn __divdf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 21 | return compiler_rt.f64.toAbi(div_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); | |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | 24 | fn __aeabi_ddiv(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { |
| 25 | return div(a, b); | |
| 25 | return div_f64(a, b); | |
| 26 | 26 | } |
| 27 | 27 | |
| 28 | inline fn div(a: f64, b: f64) f64 { | |
| 28 | pub fn div_f64(a: f64, b: f64) f64 { | |
| 29 | 29 | const Z = @Int(.unsigned, 64); |
| 30 | 30 | const SignedZ = @Int(.signed, 64); |
| 31 | 31 |
lib/compiler_rt/divdf3_test.zig+2-2| ... | ... | @@ -6,7 +6,7 @@ const std = @import("std"); |
| 6 | 6 | const math = std.math; |
| 7 | 7 | const testing = std.testing; |
| 8 | 8 | |
| 9 | const __divdf3 = @import("divdf3.zig").__divdf3; | |
| 9 | const div_f64 = @import("divdf3.zig").div_f64; | |
| 10 | 10 | |
| 11 | 11 | const nanRep: u64 = @as(u64, @bitCast(math.nan(f64))); |
| 12 | 12 | const infRep: u64 = @as(u64, @bitCast(math.inf(f64))); |
| ... | ... | @@ -30,7 +30,7 @@ fn compareResultD(result: f64, expected: u64) bool { |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | 32 | fn test__divdf3(a: f64, b: f64, expected: u64) !void { |
| 33 | const x = __divdf3(a, b); | |
| 33 | const x = div_f64(a, b); | |
| 34 | 34 | const ret = compareResultD(x, expected); |
| 35 | 35 | try testing.expect(ret == true); |
| 36 | 36 | } |
lib/compiler_rt/divhc3.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const divc3 = @import("./divc3.zig"); | |
| 4 | const Complex = @import("./mulc3.zig").Complex; | |
| 5 | ||
| 6 | comptime { | |
| 7 | if (@import("builtin").zig_backend != .stage2_c) { | |
| 8 | symbol(&__divhc3, "__divhc3"); | |
| 9 | } | |
| 10 | } | |
| 11 | ||
| 12 | pub fn __divhc3(a: f16, b: f16, c: f16, d: f16) callconv(.c) Complex(f16) { | |
| 13 | return divc3.divc3(f16, a, b, c, d); | |
| 14 | } |
lib/compiler_rt/divhf3.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 2 | const divsf3 = @import("./divsf3.zig"); | |
| 3 | ||
| 4 | comptime { | |
| 5 | symbol(&__divhf3, "__divhf3"); | |
| 6 | } | |
| 7 | ||
| 8 | pub fn __divhf3(a: f16, b: f16) callconv(.c) f16 { | |
| 9 | // TODO: more efficient implementation | |
| 10 | return @floatCast(divsf3.__divsf3(a, b)); | |
| 11 | } |
lib/compiler_rt/divmodei4.zig+1-1| ... | ... | @@ -5,7 +5,7 @@ const std = @import("std"); |
| 5 | 5 | |
| 6 | 6 | const compiler_rt = @import("../compiler_rt.zig"); |
| 7 | 7 | const udivmod = @import("udivmodei4.zig").divmod; |
| 8 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 8 | const symbol = compiler_rt.symbol; | |
| 9 | 9 | |
| 10 | 10 | comptime { |
| 11 | 11 | symbol(&__divei4, "__divei4"); |
lib/compiler_rt/divsc3.zig deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | const divc3 = @import("./divc3.zig"); | |
| 2 | const Complex = @import("./mulc3.zig").Complex; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | |
| 7 | symbol(&__divsc3, "__divsc3"); | |
| 8 | } | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __divsc3(a: f32, b: f32, c: f32, d: f32) callconv(.c) Complex(f32) { | |
| 12 | return divc3.divc3(f32, a, b, c, d); | |
| 13 | } |
lib/compiler_rt/divsf3.zig+13-4| ... | ... | @@ -9,6 +9,7 @@ const symbol = compiler_rt.symbol; |
| 9 | 9 | const normalize = compiler_rt.normalize; |
| 10 | 10 | |
| 11 | 11 | comptime { |
| 12 | symbol(&__divhf3, "__divhf3"); | |
| 12 | 13 | if (compiler_rt.want_aeabi) { |
| 13 | 14 | symbol(&__aeabi_fdiv, "__aeabi_fdiv"); |
| 14 | 15 | } else { |
| ... | ... | @@ -16,15 +17,23 @@ comptime { |
| 16 | 17 | } |
| 17 | 18 | } |
| 18 | 19 | |
| 19 | pub fn __divsf3(a: f32, b: f32) callconv(.c) f32 { | |
| 20 | return div(a, b); | |
| 20 | fn __divhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 21 | return compiler_rt.f16.toAbi(div_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); | |
| 22 | } | |
| 23 | pub fn div_f16(a: f16, b: f16) f16 { | |
| 24 | // TODO: more efficient implementation | |
| 25 | return @floatCast(div_f32(a, b)); | |
| 26 | } | |
| 27 | ||
| 28 | fn __divsf3(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 29 | return compiler_rt.f32.toAbi(div_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); | |
| 21 | 30 | } |
| 22 | 31 | |
| 23 | 32 | fn __aeabi_fdiv(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { |
| 24 | return div(a, b); | |
| 33 | return div_f32(a, b); | |
| 25 | 34 | } |
| 26 | 35 | |
| 27 | inline fn div(a: f32, b: f32) f32 { | |
| 36 | pub fn div_f32(a: f32, b: f32) f32 { | |
| 28 | 37 | const Z = @Int(.unsigned, 32); |
| 29 | 38 | |
| 30 | 39 | const significandBits = std.math.floatMantissaBits(f32); |
lib/compiler_rt/divsf3_test.zig+2-2| ... | ... | @@ -6,7 +6,7 @@ const std = @import("std"); |
| 6 | 6 | const math = std.math; |
| 7 | 7 | const testing = std.testing; |
| 8 | 8 | |
| 9 | const __divsf3 = @import("divsf3.zig").__divsf3; | |
| 9 | const div_f32 = @import("divsf3.zig").div_f32; | |
| 10 | 10 | |
| 11 | 11 | const nanRep: u32 = @as(u32, @bitCast(math.nan(f32))); |
| 12 | 12 | const infRep: u32 = @as(u32, @bitCast(math.inf(f32))); |
| ... | ... | @@ -30,7 +30,7 @@ fn compareResultF(result: f32, expected: u32) bool { |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | 32 | fn test__divsf3(a: f32, b: f32, expected: u32) !void { |
| 33 | const x = __divsf3(a, b); | |
| 33 | const x = div_f32(a, b); | |
| 34 | 34 | const ret = compareResultF(x, expected); |
| 35 | 35 | try testing.expect(ret == true); |
| 36 | 36 | } |
lib/compiler_rt/divtc3.zig deleted-16| ... | ... | @@ -1,16 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const divc3 = @import("./divc3.zig"); | |
| 3 | const Complex = @import("./mulc3.zig").Complex; | |
| 4 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 5 | ||
| 6 | comptime { | |
| 7 | if (@import("builtin").zig_backend != .stage2_c) { | |
| 8 | if (compiler_rt.want_ppc_abi) | |
| 9 | symbol(&__divtc3, "__divkc3"); | |
| 10 | symbol(&__divtc3, "__divtc3"); | |
| 11 | } | |
| 12 | } | |
| 13 | ||
| 14 | pub fn __divtc3(a: f128, b: f128, c: f128, d: f128) callconv(.c) Complex(f128) { | |
| 15 | return divc3.divc3(f128, a, b, c, d); | |
| 16 | } |
lib/compiler_rt/divtf3.zig+6-5| ... | ... | @@ -13,19 +13,20 @@ comptime { |
| 13 | 13 | symbol(&_Qp_div, "_Qp_div"); |
| 14 | 14 | } else if (compiler_rt.want_sparc32_abi) { |
| 15 | 15 | symbol(&__divtf3, "_Q_div"); |
| 16 | } else { | |
| 17 | symbol(&__divtf3, "__divtf3"); | |
| 16 | 18 | } |
| 17 | symbol(&__divtf3, "__divtf3"); | |
| 18 | 19 | } |
| 19 | 20 | |
| 20 | pub fn __divtf3(a: f128, b: f128) callconv(.c) f128 { | |
| 21 | return div(a, b); | |
| 21 | fn __divtf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 22 | return compiler_rt.f128.toAbi(div_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); | |
| 22 | 23 | } |
| 23 | 24 | |
| 24 | 25 | fn _Qp_div(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { |
| 25 | c.* = div(a.*, b.*); | |
| 26 | c.* = div_f128(a.*, b.*); | |
| 26 | 27 | } |
| 27 | 28 | |
| 28 | inline fn div(a: f128, b: f128) f128 { | |
| 29 | pub fn div_f128(a: f128, b: f128) f128 { | |
| 29 | 30 | const Z = @Int(.unsigned, 128); |
| 30 | 31 | |
| 31 | 32 | const significandBits = std.math.floatMantissaBits(f128); |
lib/compiler_rt/divtf3_test.zig+2-2| ... | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | const math = std.math; |
| 3 | 3 | const testing = std.testing; |
| 4 | 4 | |
| 5 | const __divtf3 = @import("divtf3.zig").__divtf3; | |
| 5 | const div_f128 = @import("divtf3.zig").div_f128; | |
| 6 | 6 | |
| 7 | 7 | fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool { |
| 8 | 8 | const rep: u128 = @bitCast(result); |
| ... | ... | @@ -24,7 +24,7 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool { |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | 26 | fn test__divtf3(a: f128, b: f128, expectedHi: u64, expectedLo: u64) !void { |
| 27 | const x = __divtf3(a, b); | |
| 27 | const x = div_f128(a, b); | |
| 28 | 28 | const ret = compareResultLD(x, expectedHi, expectedLo); |
| 29 | 29 | try testing.expect(ret == true); |
| 30 | 30 | } |
lib/compiler_rt/divxc3.zig deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 2 | const divc3 = @import("./divc3.zig"); | |
| 3 | const Complex = @import("./mulc3.zig").Complex; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | |
| 7 | symbol(&__divxc3, "__divxc3"); | |
| 8 | } | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __divxc3(a: f80, b: f80, c: f80, d: f80) callconv(.c) Complex(f80) { | |
| 12 | return divc3.divc3(f80, a, b, c, d); | |
| 13 | } |
lib/compiler_rt/divxf3.zig+4-1| ... | ... | @@ -11,7 +11,10 @@ comptime { |
| 11 | 11 | symbol(&__divxf3, "__divxf3"); |
| 12 | 12 | } |
| 13 | 13 | |
| 14 | pub fn __divxf3(a: f80, b: f80) callconv(.c) f80 { | |
| 14 | fn __divxf3(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 15 | return compiler_rt.f80.toAbi(div_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); | |
| 16 | } | |
| 17 | pub fn div_f80(a: f80, b: f80) f80 { | |
| 15 | 18 | const T = f80; |
| 16 | 19 | const Z = @Int(.unsigned, @bitSizeOf(T)); |
| 17 | 20 |
lib/compiler_rt/divxf3_test.zig+3-3| ... | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | const math = std.math; |
| 3 | 3 | const testing = std.testing; |
| 4 | 4 | |
| 5 | const __divxf3 = @import("divxf3.zig").__divxf3; | |
| 5 | const div_f80 = @import("divxf3.zig").div_f80; | |
| 6 | 6 | |
| 7 | 7 | const nanRep: u80 = @as(u80, @bitCast(math.nan(f80))); |
| 8 | 8 | const infRep: u80 = @as(u80, @bitCast(math.inf(f80))); |
| ... | ... | @@ -19,14 +19,14 @@ fn compareResult(result: f80, expected: u80) bool { |
| 19 | 19 | } |
| 20 | 20 | |
| 21 | 21 | fn expect__divxf3_result(a: f80, b: f80, expected: u80) !void { |
| 22 | const x = __divxf3(a, b); | |
| 22 | const x = div_f80(a, b); | |
| 23 | 23 | const ret = compareResult(x, expected); |
| 24 | 24 | try testing.expect(ret == true); |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | 27 | fn test__divxf3(a: f80, b: f80) !void { |
| 28 | 28 | const integerBit = 1 << math.floatFractionalBits(f80); |
| 29 | const x = __divxf3(a, b); | |
| 29 | const x = div_f80(a, b); | |
| 30 | 30 | |
| 31 | 31 | // Next float (assuming normal, non-zero result) |
| 32 | 32 | const x_plus_eps: f80 = @bitCast((@as(u80, @bitCast(x)) + 1) | integerBit); |
lib/compiler_rt/exp.zig+104-90| ... | ... | @@ -14,7 +14,7 @@ const expect = std.testing.expect; |
| 14 | 14 | const expectEqual = std.testing.expectEqual; |
| 15 | 15 | |
| 16 | 16 | const compiler_rt = @import("../compiler_rt.zig"); |
| 17 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 17 | const symbol = compiler_rt.symbol; | |
| 18 | 18 | |
| 19 | 19 | comptime { |
| 20 | 20 | symbol(&__exph, "__exph"); |
| ... | ... | @@ -28,12 +28,18 @@ comptime { |
| 28 | 28 | symbol(&expl, "expl"); |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | pub fn __exph(a: f16) callconv(.c) f16 { | |
| 31 | fn __exph(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 32 | return compiler_rt.f16.toAbi(exp_f16(compiler_rt.f16.fromAbi(x))); | |
| 33 | } | |
| 34 | pub fn exp_f16(x: f16) f16 { | |
| 32 | 35 | // TODO: more efficient implementation |
| 33 | return @floatCast(expf(a)); | |
| 36 | return @floatCast(exp_f32(x)); | |
| 34 | 37 | } |
| 35 | 38 | |
| 36 | pub fn expf(x_: f32) callconv(.c) f32 { | |
| 39 | fn expf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 40 | return compiler_rt.f32.toAbi(exp_f32(compiler_rt.f32.fromAbi(x))); | |
| 41 | } | |
| 42 | pub fn exp_f32(x_: f32) f32 { | |
| 37 | 43 | const half = [_]f32{ 0.5, -0.5 }; |
| 38 | 44 | const ln2hi = 6.9314575195e-1; |
| 39 | 45 | const ln2lo = 1.4286067653e-6; |
| ... | ... | @@ -108,7 +114,10 @@ pub fn expf(x_: f32) callconv(.c) f32 { |
| 108 | 114 | } |
| 109 | 115 | } |
| 110 | 116 | |
| 111 | pub fn exp(x_: f64) callconv(.c) f64 { | |
| 117 | fn exp(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 118 | return compiler_rt.f64.toAbi(exp_f64(compiler_rt.f64.fromAbi(x))); | |
| 119 | } | |
| 120 | pub fn exp_f64(x_: f64) f64 { | |
| 112 | 121 | const half = [_]f64{ 0.5, -0.5 }; |
| 113 | 122 | const ln2hi: f64 = 6.93147180369123816490e-01; |
| 114 | 123 | const ln2lo: f64 = 1.90821492927058770002e-10; |
| ... | ... | @@ -189,116 +198,121 @@ pub fn exp(x_: f64) callconv(.c) f64 { |
| 189 | 198 | } |
| 190 | 199 | } |
| 191 | 200 | |
| 192 | pub fn __expx(a: f80) callconv(.c) f80 { | |
| 201 | fn __expx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 202 | return compiler_rt.f80.toAbi(exp_f80(compiler_rt.f80.fromAbi(x))); | |
| 203 | } | |
| 204 | pub fn exp_f80(x: f80) f80 { | |
| 193 | 205 | // TODO: more efficient implementation |
| 194 | return @floatCast(expq(a)); | |
| 206 | return @floatCast(exp_f128(x)); | |
| 195 | 207 | } |
| 196 | 208 | |
| 197 | const expq = @import("exp_f128.zig").exp; | |
| 209 | fn expq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 210 | return compiler_rt.f128.toAbi(exp_f128(compiler_rt.f128.fromAbi(x))); | |
| 211 | } | |
| 212 | pub const exp_f128 = @import("exp_f128.zig").exp; | |
| 198 | 213 | |
| 199 | 214 | pub fn expl(x: c_longdouble) callconv(.c) c_longdouble { |
| 200 | 215 | switch (@typeInfo(c_longdouble).float.bits) { |
| 201 | 64 => return exp(x), | |
| 202 | 80 => return __expx(x), | |
| 203 | 128 => return expq(x), | |
| 204 | else => @compileError("unreachable"), | |
| 216 | 64 => return exp_f64(x), | |
| 217 | 80 => return exp_f80(x), | |
| 218 | 128 => return exp_f128(x), | |
| 219 | else => comptime unreachable, | |
| 205 | 220 | } |
| 206 | 221 | } |
| 207 | 222 | |
| 208 | 223 | test "expf() special" { |
| 209 | try expectEqual(expf(0.0), 1.0); | |
| 210 | try expectEqual(expf(-0.0), 1.0); | |
| 211 | try expectEqual(expf(1.0), math.e); | |
| 212 | try expectEqual(expf(math.ln2), 2.0); | |
| 213 | try expectEqual(expf(math.inf(f32)), math.inf(f32)); | |
| 214 | try expect(math.isPositiveZero(expf(-math.inf(f32)))); | |
| 215 | try expect(math.isNan(expf(math.nan(f32)))); | |
| 216 | try expect(math.isNan(expf(math.snan(f32)))); | |
| 224 | try expectEqual(exp_f32(0.0), 1.0); | |
| 225 | try expectEqual(exp_f32(-0.0), 1.0); | |
| 226 | try expectEqual(exp_f32(1.0), math.e); | |
| 227 | try expectEqual(exp_f32(math.ln2), 2.0); | |
| 228 | try expectEqual(exp_f32(math.inf(f32)), math.inf(f32)); | |
| 229 | try expect(math.isPositiveZero(exp_f32(-math.inf(f32)))); | |
| 230 | try expect(math.isNan(exp_f32(math.nan(f32)))); | |
| 231 | try expect(math.isNan(exp_f32(math.snan(f32)))); | |
| 217 | 232 | } |
| 218 | 233 | |
| 219 | 234 | test "expf() sanity" { |
| 220 | try expectEqual(expf(-0x1.0223a0p+3), 0x1.490320p-12); | |
| 221 | try expectEqual(expf(0x1.161868p+2), 0x1.34712ap+6); | |
| 222 | try expectEqual(expf(-0x1.0c34b4p+3), 0x1.e06b1ap-13); | |
| 223 | try expectEqual(expf(-0x1.a206f0p+2), 0x1.7dd484p-10); | |
| 224 | try expectEqual(expf(0x1.288bbcp+3), 0x1.4abc80p+13); | |
| 225 | try expectEqual(expf(0x1.52efd0p-1), 0x1.f04a9cp+0); | |
| 226 | try expectEqual(expf(-0x1.a05cc8p-2), 0x1.54f1e0p-1); | |
| 227 | try expectEqual(expf(0x1.1f9efap-1), 0x1.c0f628p+0); | |
| 228 | try expectEqual(expf(0x1.8c5db0p-1), 0x1.1599b2p+1); | |
| 229 | try expectEqual(expf(-0x1.5b86eap-1), 0x1.03b572p-1); | |
| 230 | try expectEqual(expf(-0x1.57f25cp+2), 0x1.2fbea2p-8); | |
| 231 | try expectEqual(expf(0x1.c7d310p+3), 0x1.76eefp+20); | |
| 232 | try expectEqual(expf(0x1.19be70p+4), 0x1.52d3dep+25); | |
| 233 | try expectEqual(expf(-0x1.ab6d70p+3), 0x1.a88adep-20); | |
| 234 | try expectEqual(expf(-0x1.5ac18ep+2), 0x1.22b328p-8); | |
| 235 | try expectEqual(expf(-0x1.925982p-1), 0x1.d2acc0p-2); | |
| 236 | try expectEqual(expf(0x1.7221cep+3), 0x1.9c2ceap+16); | |
| 237 | try expectEqual(expf(0x1.11a0d4p+4), 0x1.980ee6p+24); | |
| 238 | try expectEqual(expf(-0x1.ae41a2p+1), 0x1.1c28d0p-5); | |
| 239 | try expectEqual(expf(-0x1.329154p+4), 0x1.47ef94p-28); | |
| 235 | try expectEqual(exp_f32(-0x1.0223a0p+3), 0x1.490320p-12); | |
| 236 | try expectEqual(exp_f32(0x1.161868p+2), 0x1.34712ap+6); | |
| 237 | try expectEqual(exp_f32(-0x1.0c34b4p+3), 0x1.e06b1ap-13); | |
| 238 | try expectEqual(exp_f32(-0x1.a206f0p+2), 0x1.7dd484p-10); | |
| 239 | try expectEqual(exp_f32(0x1.288bbcp+3), 0x1.4abc80p+13); | |
| 240 | try expectEqual(exp_f32(0x1.52efd0p-1), 0x1.f04a9cp+0); | |
| 241 | try expectEqual(exp_f32(-0x1.a05cc8p-2), 0x1.54f1e0p-1); | |
| 242 | try expectEqual(exp_f32(0x1.1f9efap-1), 0x1.c0f628p+0); | |
| 243 | try expectEqual(exp_f32(0x1.8c5db0p-1), 0x1.1599b2p+1); | |
| 244 | try expectEqual(exp_f32(-0x1.5b86eap-1), 0x1.03b572p-1); | |
| 245 | try expectEqual(exp_f32(-0x1.57f25cp+2), 0x1.2fbea2p-8); | |
| 246 | try expectEqual(exp_f32(0x1.c7d310p+3), 0x1.76eefp+20); | |
| 247 | try expectEqual(exp_f32(0x1.19be70p+4), 0x1.52d3dep+25); | |
| 248 | try expectEqual(exp_f32(-0x1.ab6d70p+3), 0x1.a88adep-20); | |
| 249 | try expectEqual(exp_f32(-0x1.5ac18ep+2), 0x1.22b328p-8); | |
| 250 | try expectEqual(exp_f32(-0x1.925982p-1), 0x1.d2acc0p-2); | |
| 251 | try expectEqual(exp_f32(0x1.7221cep+3), 0x1.9c2ceap+16); | |
| 252 | try expectEqual(exp_f32(0x1.11a0d4p+4), 0x1.980ee6p+24); | |
| 253 | try expectEqual(exp_f32(-0x1.ae41a2p+1), 0x1.1c28d0p-5); | |
| 254 | try expectEqual(exp_f32(-0x1.329154p+4), 0x1.47ef94p-28); | |
| 240 | 255 | } |
| 241 | 256 | |
| 242 | 257 | test "expf() boundary" { |
| 243 | try expectEqual(expf(0x1.62e42ep+6), 0x1.ffff08p+127); // The last value before the result gets infinite | |
| 244 | try expectEqual(expf(0x1.62e430p+6), math.inf(f32)); // The first value that gives inf | |
| 245 | try expectEqual(expf(0x1.fffffep+127), math.inf(f32)); // Max input value | |
| 246 | try expectEqual(expf(0x1p-149), 1.0); // Min positive input value | |
| 247 | try expectEqual(expf(-0x1p-149), 1.0); // Min negative input value | |
| 248 | try expectEqual(expf(0x1p-126), 1.0); // First positive subnormal input | |
| 249 | try expectEqual(expf(-0x1p-126), 1.0); // First negative subnormal input | |
| 250 | try expectEqual(expf(-0x1.9fe368p+6), 0x1p-149); // The last value before the result flushes to zero | |
| 251 | try expectEqual(expf(-0x1.9fe36ap+6), 0.0); // The first value at which the result flushes to zero | |
| 252 | try expectEqual(expf(-0x1.5d589ep+6), 0x1.00004cp-126); // The last value before the result flushes to subnormal | |
| 253 | try expectEqual(expf(-0x1.5d58a0p+6), 0x1.ffff98p-127); // The first value for which the result flushes to subnormal | |
| 254 | ||
| 258 | try expectEqual(exp_f32(0x1.62e42ep+6), 0x1.ffff08p+127); // The last value before the result gets infinite | |
| 259 | try expectEqual(exp_f32(0x1.62e430p+6), math.inf(f32)); // The first value that gives inf | |
| 260 | try expectEqual(exp_f32(0x1.fffffep+127), math.inf(f32)); // Max input value | |
| 261 | try expectEqual(exp_f32(0x1p-149), 1.0); // Min positive input value | |
| 262 | try expectEqual(exp_f32(-0x1p-149), 1.0); // Min negative input value | |
| 263 | try expectEqual(exp_f32(0x1p-126), 1.0); // First positive subnormal input | |
| 264 | try expectEqual(exp_f32(-0x1p-126), 1.0); // First negative subnormal input | |
| 265 | try expectEqual(exp_f32(-0x1.9fe368p+6), 0x1p-149); // The last value before the result flushes to zero | |
| 266 | try expectEqual(exp_f32(-0x1.9fe36ap+6), 0.0); // The first value at which the result flushes to zero | |
| 267 | try expectEqual(exp_f32(-0x1.5d589ep+6), 0x1.00004cp-126); // The last value before the result flushes to subnormal | |
| 268 | try expectEqual(exp_f32(-0x1.5d58a0p+6), 0x1.ffff98p-127); // The first value for which the result flushes to subnormal | |
| 255 | 269 | } |
| 256 | 270 | |
| 257 | 271 | test "exp() special" { |
| 258 | try expectEqual(exp(0.0), 1.0); | |
| 259 | try expectEqual(exp(-0.0), 1.0); | |
| 272 | try expectEqual(exp_f64(0.0), 1.0); | |
| 273 | try expectEqual(exp_f64(-0.0), 1.0); | |
| 260 | 274 | // TODO: Accuracy error - off in the last bit in 64-bit, disagreeing with GCC |
| 261 | 275 | // try expectEqual(exp(1.0), math.e); |
| 262 | try expectEqual(exp(math.ln2), 2.0); | |
| 263 | try expectEqual(exp(math.inf(f64)), math.inf(f64)); | |
| 264 | try expect(math.isPositiveZero(exp(-math.inf(f64)))); | |
| 265 | try expect(math.isNan(exp(math.nan(f64)))); | |
| 266 | try expect(math.isNan(exp(math.snan(f64)))); | |
| 276 | try expectEqual(exp_f64(math.ln2), 2.0); | |
| 277 | try expectEqual(exp_f64(math.inf(f64)), math.inf(f64)); | |
| 278 | try expect(math.isPositiveZero(exp_f64(-math.inf(f64)))); | |
| 279 | try expect(math.isNan(exp_f64(math.nan(f64)))); | |
| 280 | try expect(math.isNan(exp_f64(math.snan(f64)))); | |
| 267 | 281 | } |
| 268 | 282 | |
| 269 | 283 | test "exp() sanity" { |
| 270 | try expectEqual(exp(-0x1.02239f3c6a8f1p+3), 0x1.490327ea61235p-12); | |
| 271 | try expectEqual(exp(0x1.161868e18bc67p+2), 0x1.34712ed238c04p+6); | |
| 272 | try expectEqual(exp(-0x1.0c34b3e01e6e7p+3), 0x1.e06b1b6c18e64p-13); | |
| 273 | try expectEqual(exp(-0x1.a206f0a19dcc4p+2), 0x1.7dd47f810e68cp-10); | |
| 274 | try expectEqual(exp(0x1.288bbb0d6a1e6p+3), 0x1.4abc77496e07ep+13); | |
| 275 | try expectEqual(exp(0x1.52efd0cd80497p-1), 0x1.f04a9c1080500p+0); | |
| 276 | try expectEqual(exp(-0x1.a05cc754481d1p-2), 0x1.54f1e0fd3ea0dp-1); | |
| 277 | try expectEqual(exp(0x1.1f9ef934745cbp-1), 0x1.c0f6266a6a547p+0); | |
| 278 | try expectEqual(exp(0x1.8c5db097f7442p-1), 0x1.1599b1d4a25fbp+1); | |
| 279 | try expectEqual(exp(-0x1.5b86ea8118a0ep-1), 0x1.03b5728a00229p-1); | |
| 280 | try expectEqual(exp(-0x1.57f25b2b5006dp+2), 0x1.2fbea6a01cab9p-8); | |
| 281 | try expectEqual(exp(0x1.c7d30fb825911p+3), 0x1.76eeed45a0634p+20); | |
| 282 | try expectEqual(exp(0x1.19be709de7505p+4), 0x1.52d3eb7be6844p+25); | |
| 283 | try expectEqual(exp(-0x1.ab6d6fba96889p+3), 0x1.a88ae12f985d6p-20); | |
| 284 | try expectEqual(exp(-0x1.5ac18e27084ddp+2), 0x1.22b327da9cca6p-8); | |
| 285 | try expectEqual(exp(-0x1.925981b093c41p-1), 0x1.d2acc046b55f7p-2); | |
| 286 | try expectEqual(exp(0x1.7221cd18455f5p+3), 0x1.9c2cde8699cfbp+16); | |
| 287 | try expectEqual(exp(0x1.11a0d4a51b239p+4), 0x1.980ef612ff182p+24); | |
| 288 | try expectEqual(exp(-0x1.ae41a1079de4dp+1), 0x1.1c28d16bb3222p-5); | |
| 289 | try expectEqual(exp(-0x1.329153103b871p+4), 0x1.47efa6ddd0d22p-28); | |
| 284 | try expectEqual(exp_f64(-0x1.02239f3c6a8f1p+3), 0x1.490327ea61235p-12); | |
| 285 | try expectEqual(exp_f64(0x1.161868e18bc67p+2), 0x1.34712ed238c04p+6); | |
| 286 | try expectEqual(exp_f64(-0x1.0c34b3e01e6e7p+3), 0x1.e06b1b6c18e64p-13); | |
| 287 | try expectEqual(exp_f64(-0x1.a206f0a19dcc4p+2), 0x1.7dd47f810e68cp-10); | |
| 288 | try expectEqual(exp_f64(0x1.288bbb0d6a1e6p+3), 0x1.4abc77496e07ep+13); | |
| 289 | try expectEqual(exp_f64(0x1.52efd0cd80497p-1), 0x1.f04a9c1080500p+0); | |
| 290 | try expectEqual(exp_f64(-0x1.a05cc754481d1p-2), 0x1.54f1e0fd3ea0dp-1); | |
| 291 | try expectEqual(exp_f64(0x1.1f9ef934745cbp-1), 0x1.c0f6266a6a547p+0); | |
| 292 | try expectEqual(exp_f64(0x1.8c5db097f7442p-1), 0x1.1599b1d4a25fbp+1); | |
| 293 | try expectEqual(exp_f64(-0x1.5b86ea8118a0ep-1), 0x1.03b5728a00229p-1); | |
| 294 | try expectEqual(exp_f64(-0x1.57f25b2b5006dp+2), 0x1.2fbea6a01cab9p-8); | |
| 295 | try expectEqual(exp_f64(0x1.c7d30fb825911p+3), 0x1.76eeed45a0634p+20); | |
| 296 | try expectEqual(exp_f64(0x1.19be709de7505p+4), 0x1.52d3eb7be6844p+25); | |
| 297 | try expectEqual(exp_f64(-0x1.ab6d6fba96889p+3), 0x1.a88ae12f985d6p-20); | |
| 298 | try expectEqual(exp_f64(-0x1.5ac18e27084ddp+2), 0x1.22b327da9cca6p-8); | |
| 299 | try expectEqual(exp_f64(-0x1.925981b093c41p-1), 0x1.d2acc046b55f7p-2); | |
| 300 | try expectEqual(exp_f64(0x1.7221cd18455f5p+3), 0x1.9c2cde8699cfbp+16); | |
| 301 | try expectEqual(exp_f64(0x1.11a0d4a51b239p+4), 0x1.980ef612ff182p+24); | |
| 302 | try expectEqual(exp_f64(-0x1.ae41a1079de4dp+1), 0x1.1c28d16bb3222p-5); | |
| 303 | try expectEqual(exp_f64(-0x1.329153103b871p+4), 0x1.47efa6ddd0d22p-28); | |
| 290 | 304 | } |
| 291 | 305 | |
| 292 | 306 | test "exp() boundary" { |
| 293 | try expectEqual(exp(0x1.62e42fefa39efp+9), 0x1.fffffffffff2ap+1023); // The last value before the result gets infinite | |
| 294 | try expectEqual(exp(0x1.62e42fefa39f0p+9), math.inf(f64)); // The first value that gives inf | |
| 295 | try expectEqual(exp(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value | |
| 296 | try expectEqual(exp(0x1p-1074), 1.0); // Min positive input value | |
| 297 | try expectEqual(exp(-0x1p-1074), 1.0); // Min negative input value | |
| 298 | try expectEqual(exp(0x1p-1022), 1.0); // First positive subnormal input | |
| 299 | try expectEqual(exp(-0x1p-1022), 1.0); // First negative subnormal input | |
| 300 | try expectEqual(exp(-0x1.74910d52d3051p+9), 0x1p-1074); // The last value before the result flushes to zero | |
| 301 | try expectEqual(exp(-0x1.74910d52d3052p+9), 0.0); // The first value at which the result flushes to zero | |
| 302 | try expectEqual(exp(-0x1.6232bdd7abcd2p+9), 0x1.000000000007cp-1022); // The last value before the result flushes to subnormal | |
| 303 | try expectEqual(exp(-0x1.6232bdd7abcd3p+9), 0x1.ffffffffffcf8p-1023); // The first value for which the result flushes to subnormal | |
| 307 | try expectEqual(exp_f64(0x1.62e42fefa39efp+9), 0x1.fffffffffff2ap+1023); // The last value before the result gets infinite | |
| 308 | try expectEqual(exp_f64(0x1.62e42fefa39f0p+9), math.inf(f64)); // The first value that gives inf | |
| 309 | try expectEqual(exp_f64(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value | |
| 310 | try expectEqual(exp_f64(0x1p-1074), 1.0); // Min positive input value | |
| 311 | try expectEqual(exp_f64(-0x1p-1074), 1.0); // Min negative input value | |
| 312 | try expectEqual(exp_f64(0x1p-1022), 1.0); // First positive subnormal input | |
| 313 | try expectEqual(exp_f64(-0x1p-1022), 1.0); // First negative subnormal input | |
| 314 | try expectEqual(exp_f64(-0x1.74910d52d3051p+9), 0x1p-1074); // The last value before the result flushes to zero | |
| 315 | try expectEqual(exp_f64(-0x1.74910d52d3052p+9), 0.0); // The first value at which the result flushes to zero | |
| 316 | try expectEqual(exp_f64(-0x1.6232bdd7abcd2p+9), 0x1.000000000007cp-1022); // The last value before the result flushes to subnormal | |
| 317 | try expectEqual(exp_f64(-0x1.6232bdd7abcd3p+9), 0x1.ffffffffffcf8p-1023); // The first value for which the result flushes to subnormal | |
| 304 | 318 | } |
lib/compiler_rt/exp2.zig+84-69| ... | ... | @@ -26,12 +26,18 @@ comptime { |
| 26 | 26 | symbol(&exp2l, "exp2l"); |
| 27 | 27 | } |
| 28 | 28 | |
| 29 | pub fn __exp2h(x: f16) callconv(.c) f16 { | |
| 29 | fn __exp2h(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 30 | return compiler_rt.f16.toAbi(exp2_f16(compiler_rt.f16.fromAbi(x))); | |
| 31 | } | |
| 32 | pub fn exp2_f16(x: f16) f16 { | |
| 30 | 33 | // TODO: more efficient implementation |
| 31 | return @floatCast(exp2f(x)); | |
| 34 | return @floatCast(exp2_f32(x)); | |
| 32 | 35 | } |
| 33 | 36 | |
| 34 | pub fn exp2f(x: f32) callconv(.c) f32 { | |
| 37 | fn exp2f(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 38 | return compiler_rt.f32.toAbi(exp2_f32(compiler_rt.f32.fromAbi(x))); | |
| 39 | } | |
| 40 | pub fn exp2_f32(x: f32) f32 { | |
| 35 | 41 | const tblsiz: u32 = @intCast(exp2ft.len); |
| 36 | 42 | const redux: f32 = 0x1.8p23 / @as(f32, @floatFromInt(tblsiz)); |
| 37 | 43 | const P1: f32 = 0x1.62e430p-1; |
| ... | ... | @@ -88,7 +94,10 @@ pub fn exp2f(x: f32) callconv(.c) f32 { |
| 88 | 94 | return @floatCast(r * uk); |
| 89 | 95 | } |
| 90 | 96 | |
| 91 | pub fn exp2(x: f64) callconv(.c) f64 { | |
| 97 | fn exp2(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 98 | return compiler_rt.f64.toAbi(exp2_f64(compiler_rt.f64.fromAbi(x))); | |
| 99 | } | |
| 100 | pub fn exp2_f64(x: f64) f64 { | |
| 92 | 101 | const tblsiz: u32 = @intCast(exp2dt.len / 2); |
| 93 | 102 | const redux: f64 = 0x1.8p52 / @as(f64, @floatFromInt(tblsiz)); |
| 94 | 103 | const P1: f64 = 0x1.62e42fefa39efp-1; |
| ... | ... | @@ -156,19 +165,25 @@ pub fn exp2(x: f64) callconv(.c) f64 { |
| 156 | 165 | return math.scalbn(r, ik); |
| 157 | 166 | } |
| 158 | 167 | |
| 159 | pub fn __exp2x(x: f80) callconv(.c) f80 { | |
| 168 | fn __exp2x(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 169 | return compiler_rt.f80.toAbi(exp2_f80(compiler_rt.f80.fromAbi(x))); | |
| 170 | } | |
| 171 | pub fn exp2_f80(x: f80) f80 { | |
| 160 | 172 | // TODO: more efficient implementation |
| 161 | return @floatCast(exp2q(x)); | |
| 173 | return @floatCast(exp2_f128(x)); | |
| 162 | 174 | } |
| 163 | 175 | |
| 164 | pub const exp2q = @import("exp_f128.zig").exp2; | |
| 176 | fn exp2q(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 177 | return compiler_rt.f128.toAbi(exp2_f128(compiler_rt.f128.fromAbi(x))); | |
| 178 | } | |
| 179 | pub const exp2_f128 = @import("exp_f128.zig").exp2; | |
| 165 | 180 | |
| 166 | 181 | pub fn exp2l(x: c_longdouble) callconv(.c) c_longdouble { |
| 167 | 182 | switch (@typeInfo(c_longdouble).float.bits) { |
| 168 | 64 => return exp2(x), | |
| 169 | 80 => return __exp2x(x), | |
| 170 | 128 => return exp2q(x), | |
| 171 | else => @compileError("unreachable"), | |
| 183 | 64 => return exp2_f64(x), | |
| 184 | 80 => return exp2_f80(x), | |
| 185 | 128 => return exp2_f128(x), | |
| 186 | else => comptime unreachable, | |
| 172 | 187 | } |
| 173 | 188 | } |
| 174 | 189 | |
| ... | ... | @@ -452,77 +467,77 @@ const exp2dt = [_]f64{ |
| 452 | 467 | }; |
| 453 | 468 | |
| 454 | 469 | test "exp2f() special" { |
| 455 | try expectEqual(exp2f(0.0), 1.0); | |
| 456 | try expectEqual(exp2f(-0.0), 1.0); | |
| 457 | try expectEqual(exp2f(1.0), 2.0); | |
| 458 | try expectEqual(exp2f(-1.0), 0.5); | |
| 459 | try expectEqual(exp2f(math.inf(f32)), math.inf(f32)); | |
| 460 | try expect(math.isPositiveZero(exp2f(-math.inf(f32)))); | |
| 461 | try expect(math.isNan(exp2f(math.nan(f32)))); | |
| 462 | try expect(math.isNan(exp2f(math.snan(f32)))); | |
| 470 | try expectEqual(exp2_f32(0.0), 1.0); | |
| 471 | try expectEqual(exp2_f32(-0.0), 1.0); | |
| 472 | try expectEqual(exp2_f32(1.0), 2.0); | |
| 473 | try expectEqual(exp2_f32(-1.0), 0.5); | |
| 474 | try expectEqual(exp2_f32(math.inf(f32)), math.inf(f32)); | |
| 475 | try expect(math.isPositiveZero(exp2_f32(-math.inf(f32)))); | |
| 476 | try expect(math.isNan(exp2_f32(math.nan(f32)))); | |
| 477 | try expect(math.isNan(exp2_f32(math.snan(f32)))); | |
| 463 | 478 | } |
| 464 | 479 | |
| 465 | 480 | test "exp2f() sanity" { |
| 466 | try expectEqual(exp2f(-0x1.0223a0p+3), 0x1.e8d134p-9); | |
| 467 | try expectEqual(exp2f(0x1.161868p+2), 0x1.453672p+4); | |
| 468 | try expectEqual(exp2f(-0x1.0c34b4p+3), 0x1.890ca0p-9); | |
| 469 | try expectEqual(exp2f(-0x1.a206f0p+2), 0x1.622d4ep-7); | |
| 470 | try expectEqual(exp2f(0x1.288bbcp+3), 0x1.340ecep+9); | |
| 471 | try expectEqual(exp2f(0x1.52efd0p-1), 0x1.950eeep+0); | |
| 472 | try expectEqual(exp2f(-0x1.a05cc8p-2), 0x1.824056p-1); | |
| 473 | try expectEqual(exp2f(0x1.1f9efap-1), 0x1.79dfa2p+0); | |
| 474 | try expectEqual(exp2f(0x1.8c5db0p-1), 0x1.b5ceacp+0); | |
| 475 | try expectEqual(exp2f(-0x1.5b86eap-1), 0x1.3fd8bap-1); | |
| 481 | try expectEqual(exp2_f32(-0x1.0223a0p+3), 0x1.e8d134p-9); | |
| 482 | try expectEqual(exp2_f32(0x1.161868p+2), 0x1.453672p+4); | |
| 483 | try expectEqual(exp2_f32(-0x1.0c34b4p+3), 0x1.890ca0p-9); | |
| 484 | try expectEqual(exp2_f32(-0x1.a206f0p+2), 0x1.622d4ep-7); | |
| 485 | try expectEqual(exp2_f32(0x1.288bbcp+3), 0x1.340ecep+9); | |
| 486 | try expectEqual(exp2_f32(0x1.52efd0p-1), 0x1.950eeep+0); | |
| 487 | try expectEqual(exp2_f32(-0x1.a05cc8p-2), 0x1.824056p-1); | |
| 488 | try expectEqual(exp2_f32(0x1.1f9efap-1), 0x1.79dfa2p+0); | |
| 489 | try expectEqual(exp2_f32(0x1.8c5db0p-1), 0x1.b5ceacp+0); | |
| 490 | try expectEqual(exp2_f32(-0x1.5b86eap-1), 0x1.3fd8bap-1); | |
| 476 | 491 | } |
| 477 | 492 | |
| 478 | 493 | test "exp2f() boundary" { |
| 479 | try expectEqual(exp2f(0x1.fffffep+6), 0x1.ffff4ep+127); // The last value before the result gets infinite | |
| 480 | try expectEqual(exp2f(0x1p+7), math.inf(f32)); // The first value that gives infinite result | |
| 481 | try expectEqual(exp2f(-0x1.2bccccp+7), 0x1p-149); // The last value before the result flushes to zero | |
| 482 | try expectEqual(exp2f(-0x1.2cp+7), 0); // The first value at which the result flushes to zero | |
| 483 | try expectEqual(exp2f(-0x1.f8p+6), 0x1p-126); // The last value before the result flushes to subnormal | |
| 484 | try expectEqual(exp2f(-0x1.f80002p+6), 0x1.ffff50p-127); // The first value for which the result flushes to subnormal | |
| 485 | try expectEqual(exp2f(0x1.fffffep+127), math.inf(f32)); // Max input value | |
| 486 | try expectEqual(exp2f(0x1p-149), 1); // Min positive input value | |
| 487 | try expectEqual(exp2f(-0x1p-149), 1); // Min negative input value | |
| 488 | try expectEqual(exp2f(0x1p-126), 1); // First positive subnormal input | |
| 489 | try expectEqual(exp2f(-0x1p-126), 1); // First negative subnormal input | |
| 494 | try expectEqual(exp2_f32(0x1.fffffep+6), 0x1.ffff4ep+127); // The last value before the result gets infinite | |
| 495 | try expectEqual(exp2_f32(0x1p+7), math.inf(f32)); // The first value that gives infinite result | |
| 496 | try expectEqual(exp2_f32(-0x1.2bccccp+7), 0x1p-149); // The last value before the result flushes to zero | |
| 497 | try expectEqual(exp2_f32(-0x1.2cp+7), 0); // The first value at which the result flushes to zero | |
| 498 | try expectEqual(exp2_f32(-0x1.f8p+6), 0x1p-126); // The last value before the result flushes to subnormal | |
| 499 | try expectEqual(exp2_f32(-0x1.f80002p+6), 0x1.ffff50p-127); // The first value for which the result flushes to subnormal | |
| 500 | try expectEqual(exp2_f32(0x1.fffffep+127), math.inf(f32)); // Max input value | |
| 501 | try expectEqual(exp2_f32(0x1p-149), 1); // Min positive input value | |
| 502 | try expectEqual(exp2_f32(-0x1p-149), 1); // Min negative input value | |
| 503 | try expectEqual(exp2_f32(0x1p-126), 1); // First positive subnormal input | |
| 504 | try expectEqual(exp2_f32(-0x1p-126), 1); // First negative subnormal input | |
| 490 | 505 | } |
| 491 | 506 | |
| 492 | 507 | test "exp2() special" { |
| 493 | try expectEqual(exp2(0.0), 1.0); | |
| 494 | try expectEqual(exp2(-0.0), 1.0); | |
| 495 | try expectEqual(exp2(1.0), 2.0); | |
| 496 | try expectEqual(exp2(-1.0), 0.5); | |
| 497 | try expectEqual(exp2(math.inf(f64)), math.inf(f64)); | |
| 498 | try expect(math.isPositiveZero(exp2(-math.inf(f64)))); | |
| 499 | try expect(math.isNan(exp2(math.nan(f64)))); | |
| 500 | try expect(math.isNan(exp2(math.snan(f64)))); | |
| 508 | try expectEqual(exp2_f64(0.0), 1.0); | |
| 509 | try expectEqual(exp2_f64(-0.0), 1.0); | |
| 510 | try expectEqual(exp2_f64(1.0), 2.0); | |
| 511 | try expectEqual(exp2_f64(-1.0), 0.5); | |
| 512 | try expectEqual(exp2_f64(math.inf(f64)), math.inf(f64)); | |
| 513 | try expect(math.isPositiveZero(exp2_f64(-math.inf(f64)))); | |
| 514 | try expect(math.isNan(exp2_f64(math.nan(f64)))); | |
| 515 | try expect(math.isNan(exp2_f64(math.snan(f64)))); | |
| 501 | 516 | } |
| 502 | 517 | |
| 503 | 518 | test "exp2() sanity" { |
| 504 | try expectEqual(exp2(-0x1.02239f3c6a8f1p+3), 0x1.e8d13c396f452p-9); | |
| 505 | try expectEqual(exp2(0x1.161868e18bc67p+2), 0x1.4536746bb6f12p+4); | |
| 506 | try expectEqual(exp2(-0x1.0c34b3e01e6e7p+3), 0x1.890ca0c00b9a2p-9); | |
| 507 | try expectEqual(exp2(-0x1.a206f0a19dcc4p+2), 0x1.622d4b0ebc6c1p-7); | |
| 508 | try expectEqual(exp2(0x1.288bbb0d6a1e6p+3), 0x1.340ec7f3e607ep+9); | |
| 509 | try expectEqual(exp2(0x1.52efd0cd80497p-1), 0x1.950eef4bc5451p+0); | |
| 510 | try expectEqual(exp2(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1); | |
| 511 | try expectEqual(exp2(0x1.1f9ef934745cbp-1), 0x1.79dfa14ab121ep+0); | |
| 512 | try expectEqual(exp2(0x1.8c5db097f7442p-1), 0x1.b5cead2247372p+0); | |
| 513 | try expectEqual(exp2(-0x1.5b86ea8118a0ep-1), 0x1.3fd8ba33216b9p-1); | |
| 519 | try expectEqual(exp2_f64(-0x1.02239f3c6a8f1p+3), 0x1.e8d13c396f452p-9); | |
| 520 | try expectEqual(exp2_f64(0x1.161868e18bc67p+2), 0x1.4536746bb6f12p+4); | |
| 521 | try expectEqual(exp2_f64(-0x1.0c34b3e01e6e7p+3), 0x1.890ca0c00b9a2p-9); | |
| 522 | try expectEqual(exp2_f64(-0x1.a206f0a19dcc4p+2), 0x1.622d4b0ebc6c1p-7); | |
| 523 | try expectEqual(exp2_f64(0x1.288bbb0d6a1e6p+3), 0x1.340ec7f3e607ep+9); | |
| 524 | try expectEqual(exp2_f64(0x1.52efd0cd80497p-1), 0x1.950eef4bc5451p+0); | |
| 525 | try expectEqual(exp2_f64(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1); | |
| 526 | try expectEqual(exp2_f64(0x1.1f9ef934745cbp-1), 0x1.79dfa14ab121ep+0); | |
| 527 | try expectEqual(exp2_f64(0x1.8c5db097f7442p-1), 0x1.b5cead2247372p+0); | |
| 528 | try expectEqual(exp2_f64(-0x1.5b86ea8118a0ep-1), 0x1.3fd8ba33216b9p-1); | |
| 514 | 529 | } |
| 515 | 530 | |
| 516 | 531 | test "exp2() boundary" { |
| 517 | try expectEqual(exp2(0x1.fffffffffffffp+9), 0x1.ffffffffffd3ap+1023); // The last value before the result gets infinite | |
| 518 | try expectEqual(exp2(0x1p+10), math.inf(f64)); // The first value that gives infinite result | |
| 519 | try expectEqual(exp2(-0x1.0cbffffffffffp+10), 0x1p-1074); // The last value before the result flushes to zero | |
| 520 | try expectEqual(exp2(-0x1.0ccp+10), 0); // The first value at which the result flushes to zero | |
| 521 | try expectEqual(exp2(-0x1.ffp+9), 0x1p-1022); // The last value before the result flushes to subnormal | |
| 522 | try expectEqual(exp2(-0x1.ff00000000001p+9), 0x1.ffffffffffd3ap-1023); // The first value for which the result flushes to subnormal | |
| 523 | try expectEqual(exp2(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value | |
| 524 | try expectEqual(exp2(0x1p-1074), 1); // Min positive input value | |
| 525 | try expectEqual(exp2(-0x1p-1074), 1); // Min negative input value | |
| 526 | try expectEqual(exp2(0x1p-1022), 1); // First positive subnormal input | |
| 527 | try expectEqual(exp2(-0x1p-1022), 1); // First negative subnormal input | |
| 532 | try expectEqual(exp2_f64(0x1.fffffffffffffp+9), 0x1.ffffffffffd3ap+1023); // The last value before the result gets infinite | |
| 533 | try expectEqual(exp2_f64(0x1p+10), math.inf(f64)); // The first value that gives infinite result | |
| 534 | try expectEqual(exp2_f64(-0x1.0cbffffffffffp+10), 0x1p-1074); // The last value before the result flushes to zero | |
| 535 | try expectEqual(exp2_f64(-0x1.0ccp+10), 0); // The first value at which the result flushes to zero | |
| 536 | try expectEqual(exp2_f64(-0x1.ffp+9), 0x1p-1022); // The last value before the result flushes to subnormal | |
| 537 | try expectEqual(exp2_f64(-0x1.ff00000000001p+9), 0x1.ffffffffffd3ap-1023); // The first value for which the result flushes to subnormal | |
| 538 | try expectEqual(exp2_f64(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value | |
| 539 | try expectEqual(exp2_f64(0x1p-1074), 1); // Min positive input value | |
| 540 | try expectEqual(exp2_f64(-0x1p-1074), 1); // Min negative input value | |
| 541 | try expectEqual(exp2_f64(0x1p-1022), 1); // First positive subnormal input | |
| 542 | try expectEqual(exp2_f64(-0x1p-1022), 1); // First negative subnormal input | |
| 528 | 543 | } |
lib/compiler_rt/exp_f128.zig+2-2| ... | ... | @@ -26,7 +26,7 @@ const exp_f128 = @This(); |
| 26 | 26 | const std = @import("std"); |
| 27 | 27 | const math = std.math; |
| 28 | 28 | |
| 29 | pub fn exp(x: f128) callconv(.c) f128 { | |
| 29 | pub fn exp(x: f128) f128 { | |
| 30 | 30 | if (!math.isFinite(x)) { |
| 31 | 31 | if (math.isNan(x)) { |
| 32 | 32 | if (math.isSignalNan(x)) math.raiseInvalid(); |
| ... | ... | @@ -91,7 +91,7 @@ fn expPoly(r_hi: f128, r_lo: f128) f128 { |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | 93 | /// Computes 2^x |
| 94 | pub fn exp2(x: f128) callconv(.c) f128 { | |
| 94 | pub fn exp2(x: f128) f128 { | |
| 95 | 95 | if (!math.isFinite(x)) { |
| 96 | 96 | if (math.isNan(x)) { |
| 97 | 97 | if (math.isSignalNan(x)) math.raiseInvalid(); |
lib/compiler_rt/extenddftf2.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const extendf = @import("./extendf.zig").extendf; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) { | |
| 7 | symbol(&__extenddftf2, "__extenddfkf2"); | |
| 8 | } else if (compiler_rt.want_sparc64_abi) { | |
| 9 | symbol(&_Qp_dtoq, "_Qp_dtoq"); | |
| 10 | } else if (compiler_rt.want_sparc32_abi) { | |
| 11 | symbol(&__extenddftf2, "_Q_dtoq"); | |
| 12 | } | |
| 13 | symbol(&__extenddftf2, "__extenddftf2"); | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __extenddftf2(a: f64) callconv(.c) f128 { | |
| 17 | return extendf(f128, f64, @as(u64, @bitCast(a))); | |
| 18 | } | |
| 19 | ||
| 20 | fn _Qp_dtoq(c: *f128, a: f64) callconv(.c) void { | |
| 21 | c.* = extendf(f128, f64, @as(u64, @bitCast(a))); | |
| 22 | } |
lib/compiler_rt/extenddfxf2.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const extend_f80 = @import("./extendf.zig").extend_f80; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__extenddfxf2, "__extenddfxf2"); | |
| 7 | } | |
| 8 | ||
| 9 | pub fn __extenddfxf2(a: f64) callconv(.c) f80 { | |
| 10 | return extend_f80(f64, @as(u64, @bitCast(a))); | |
| 11 | } |
lib/compiler_rt/extendf.zig+174-7| ... | ... | @@ -1,10 +1,175 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | |
| 3 | pub inline fn extendf( | |
| 4 | comptime dst_t: type, | |
| 5 | comptime src_t: type, | |
| 6 | a: @Int(.unsigned, @typeInfo(src_t).float.bits), | |
| 7 | ) dst_t { | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | ||
| 6 | comptime { | |
| 7 | if (compiler_rt.want_aeabi) { | |
| 8 | if (compiler_rt.gnu_f16_abi) { | |
| 9 | symbol(&__aeabi_h2f, "__gnu_h2f_ieee"); | |
| 10 | } else { | |
| 11 | symbol(&__aeabi_h2f, "__aeabi_h2f"); | |
| 12 | } | |
| 13 | } else if (compiler_rt.gnu_f16_abi) { | |
| 14 | symbol(&__extendhfsf2, "__gnu_h2f_ieee"); | |
| 15 | } | |
| 16 | symbol(&__extendhfsf2, "__extendhfsf2"); | |
| 17 | symbol(&__extendhfdf2, "__extendhfdf2"); | |
| 18 | symbol(&__extendhfxf2, "__extendhfxf2"); | |
| 19 | if (compiler_rt.want_ppc_abi) { | |
| 20 | symbol(&__extendhftf2, "__extendhfkf2"); | |
| 21 | } else { | |
| 22 | symbol(&__extendhftf2, "__extendhftf2"); | |
| 23 | } | |
| 24 | ||
| 25 | if (compiler_rt.want_aeabi) { | |
| 26 | symbol(&__aeabi_f2d, "__aeabi_f2d"); | |
| 27 | } else { | |
| 28 | symbol(&__extendsfdf2, "__extendsfdf2"); | |
| 29 | } | |
| 30 | symbol(&__extendsfxf2, "__extendsfxf2"); | |
| 31 | if (compiler_rt.want_ppc_abi) { | |
| 32 | symbol(&__extendsftf2, "__extendsfkf2"); | |
| 33 | } else if (compiler_rt.want_sparc64_abi) { | |
| 34 | symbol(&_Qp_stoq, "_Qp_stoq"); | |
| 35 | } else if (compiler_rt.want_sparc32_abi) { | |
| 36 | symbol(&__extendsftf2, "_Q_stoq"); | |
| 37 | } else { | |
| 38 | symbol(&__extendsftf2, "__extendsftf2"); | |
| 39 | } | |
| 40 | ||
| 41 | symbol(&__extenddfxf2, "__extenddfxf2"); | |
| 42 | if (compiler_rt.want_ppc_abi) { | |
| 43 | symbol(&__extenddftf2, "__extenddfkf2"); | |
| 44 | } else if (compiler_rt.want_sparc64_abi) { | |
| 45 | symbol(&_Qp_dtoq, "_Qp_dtoq"); | |
| 46 | } else if (compiler_rt.want_sparc32_abi) { | |
| 47 | symbol(&__extenddftf2, "_Q_dtoq"); | |
| 48 | } else { | |
| 49 | symbol(&__extenddftf2, "__extenddftf2"); | |
| 50 | } | |
| 51 | ||
| 52 | if (compiler_rt.want_ppc_abi) { | |
| 53 | symbol(&__extendxftf2, "__extendxfkf2"); | |
| 54 | } else { | |
| 55 | symbol(&__extendxftf2, "__extendxftf2"); | |
| 56 | } | |
| 57 | } | |
| 58 | ||
| 59 | fn __extendhfsf2(a: compiler_rt.f16Conv(f32).Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 60 | return compiler_rt.f32.toAbi(f32_floatCast_f16(compiler_rt.f16Conv(f32).fromAbi(a))); | |
| 61 | } | |
| 62 | fn __aeabi_h2f(a: u16) callconv(.{ .arm_aapcs = .{} }) u32 { | |
| 63 | return @bitCast(f32_floatCast_f16(@bitCast(a))); | |
| 64 | } | |
| 65 | pub fn f32_floatCast_f16(a: f16) f32 { | |
| 66 | return extendf(f32, f16, a); | |
| 67 | } | |
| 68 | ||
| 69 | fn __extendhfdf2(a: compiler_rt.f16Conv(f64).Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 70 | return compiler_rt.f64.toAbi(f64_floatCast_f16(compiler_rt.f16Conv(f64).fromAbi(a))); | |
| 71 | } | |
| 72 | pub fn f64_floatCast_f16(a: f16) f64 { | |
| 73 | return extendf(f64, f16, a); | |
| 74 | } | |
| 75 | ||
| 76 | fn __extendhfxf2(a: compiler_rt.f16Conv(f80).Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 77 | return compiler_rt.f80.toAbi(f80_floatCast_f16(compiler_rt.f16Conv(f80).fromAbi(a))); | |
| 78 | } | |
| 79 | pub fn f80_floatCast_f16(a: f16) f80 { | |
| 80 | return extend_f80(f16, a); | |
| 81 | } | |
| 82 | ||
| 83 | fn __extendhftf2(a: compiler_rt.f16Conv(f128).Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 84 | return compiler_rt.f128.toAbi(f128_floatCast_f16(compiler_rt.f16Conv(f128).fromAbi(a))); | |
| 85 | } | |
| 86 | pub fn f128_floatCast_f16(a: f16) f128 { | |
| 87 | return extendf(f128, f16, a); | |
| 88 | } | |
| 89 | ||
| 90 | fn __extendsfdf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 91 | return compiler_rt.f64.toAbi(f64_floatCast_f32(compiler_rt.f32.fromAbi(a))); | |
| 92 | } | |
| 93 | fn __aeabi_f2d(a: f32) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 94 | return f64_floatCast_f32(a); | |
| 95 | } | |
| 96 | pub fn f64_floatCast_f32(a: f32) f64 { | |
| 97 | return extendf(f64, f32, a); | |
| 98 | } | |
| 99 | ||
| 100 | fn __extendsfxf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 101 | return compiler_rt.f80.toAbi(f80_floatCast_f32(compiler_rt.f32.fromAbi(a))); | |
| 102 | } | |
| 103 | pub fn f80_floatCast_f32(a: f32) f80 { | |
| 104 | return extend_f80(f32, a); | |
| 105 | } | |
| 106 | ||
| 107 | pub fn __extendsftf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 108 | return compiler_rt.f128.toAbi(f128_floatCast_f32(compiler_rt.f32.fromAbi(a))); | |
| 109 | } | |
| 110 | fn _Qp_stoq(c: *f128, a: f32) callconv(.c) void { | |
| 111 | c.* = f128_floatCast_f32(a); | |
| 112 | } | |
| 113 | pub fn f128_floatCast_f32(a: f32) f128 { | |
| 114 | return extendf(f128, f32, a); | |
| 115 | } | |
| 116 | ||
| 117 | fn __extenddfxf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 118 | return compiler_rt.f80.toAbi(f80_floatCast_f64(compiler_rt.f64.fromAbi(a))); | |
| 119 | } | |
| 120 | pub fn f80_floatCast_f64(a: f64) f80 { | |
| 121 | return extend_f80(f64, a); | |
| 122 | } | |
| 123 | ||
| 124 | fn __extenddftf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 125 | return compiler_rt.f128.toAbi(f128_floatCast_f64(compiler_rt.f64.fromAbi(a))); | |
| 126 | } | |
| 127 | fn _Qp_dtoq(c: *f128, a: f64) callconv(.c) void { | |
| 128 | c.* = f128_floatCast_f64(a); | |
| 129 | } | |
| 130 | pub fn f128_floatCast_f64(a: f64) f128 { | |
| 131 | return extendf(f128, f64, a); | |
| 132 | } | |
| 133 | ||
| 134 | fn __extendxftf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 135 | return compiler_rt.f128.toAbi(f128_floatCast_f80(compiler_rt.f80.fromAbi(a))); | |
| 136 | } | |
| 137 | pub fn f128_floatCast_f80(a: f80) f128 { | |
| 138 | const src_int_bit: u64 = 0x8000000000000000; | |
| 139 | const src_sig_mask = ~src_int_bit; | |
| 140 | const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit | |
| 141 | const dst_sig_bits = std.math.floatMantissaBits(f128); | |
| 142 | ||
| 143 | const dst_bits = @bitSizeOf(f128); | |
| 144 | ||
| 145 | // Break a into a sign and representation of the absolute value | |
| 146 | var a_rep: std.math.F80 = .fromFloat(a); | |
| 147 | const sign = a_rep.exp & 0x8000; | |
| 148 | a_rep.exp &= 0x7FFF; | |
| 149 | var abs_result: u128 = undefined; | |
| 150 | ||
| 151 | if (a_rep.exp == 0 and a_rep.fraction == 0) { | |
| 152 | // zero | |
| 153 | abs_result = 0; | |
| 154 | } else if (a_rep.exp == 0x7FFF) { | |
| 155 | // a is nan or infinite | |
| 156 | abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits); | |
| 157 | abs_result |= @as(u128, a_rep.exp) << dst_sig_bits; | |
| 158 | } else if (a_rep.fraction & src_int_bit != 0) { | |
| 159 | // a is a normal value | |
| 160 | abs_result = @as(u128, a_rep.fraction & src_sig_mask) << (dst_sig_bits - src_sig_bits); | |
| 161 | abs_result |= @as(u128, a_rep.exp) << dst_sig_bits; | |
| 162 | } else { | |
| 163 | // a is denormal | |
| 164 | abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits); | |
| 165 | } | |
| 166 | ||
| 167 | // Apply the signbit to (dst_t)abs(a). | |
| 168 | const result: u128 = abs_result | @as(u128, sign) << (dst_bits - 16); | |
| 169 | return @bitCast(result); | |
| 170 | } | |
| 171 | ||
| 172 | inline fn extendf(comptime dst_t: type, comptime src_t: type, f: src_t) dst_t { | |
| 8 | 173 | const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits); |
| 9 | 174 | const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits); |
| 10 | 175 | const srcSigBits = std.math.floatMantissaBits(src_t); |
| ... | ... | @@ -31,6 +196,7 @@ pub inline fn extendf( |
| 31 | 196 | |
| 32 | 197 | const dstMinNormal: dst_rep_t = @as(dst_rep_t, 1) << dstSigBits; |
| 33 | 198 | |
| 199 | const a: src_rep_t = @bitCast(f); | |
| 34 | 200 | // Break a into a sign and representation of the absolute value |
| 35 | 201 | const aRep: src_rep_t = @bitCast(a); |
| 36 | 202 | const aAbs: src_rep_t = aRep & srcAbsMask; |
| ... | ... | @@ -66,11 +232,11 @@ pub inline fn extendf( |
| 66 | 232 | } |
| 67 | 233 | |
| 68 | 234 | // Apply the signbit to (dst_t)abs(a). |
| 69 | const result: dst_rep_t align(@alignOf(dst_t)) = absResult | @as(dst_rep_t, sign) << (dstBits - srcBits); | |
| 235 | const result: dst_rep_t = absResult | @as(dst_rep_t, sign) << (dstBits - srcBits); | |
| 70 | 236 | return @bitCast(result); |
| 71 | 237 | } |
| 72 | 238 | |
| 73 | pub inline fn extend_f80(comptime src_t: type, a: @Int(.unsigned, @typeInfo(src_t).float.bits)) f80 { | |
| 239 | inline fn extend_f80(comptime src_t: type, f: src_t) f80 { | |
| 74 | 240 | const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits); |
| 75 | 241 | const src_sig_bits = std.math.floatMantissaBits(src_t); |
| 76 | 242 | const dst_int_bit = 0x8000000000000000; |
| ... | ... | @@ -92,6 +258,7 @@ pub inline fn extend_f80(comptime src_t: type, a: @Int(.unsigned, @typeInfo(src_ |
| 92 | 258 | |
| 93 | 259 | var dst: std.math.F80 = undefined; |
| 94 | 260 | |
| 261 | const a: src_rep_t = @bitCast(f); | |
| 95 | 262 | // Break a into a sign and representation of the absolute value |
| 96 | 263 | const a_abs = a & src_abs_mask; |
| 97 | 264 | const sign: u16 = if (a & src_sign_mask != 0) 0x8000 else 0; |
lib/compiler_rt/extendf_test.zig+94-95| ... | ... | @@ -1,31 +1,37 @@ |
| 1 | 1 | const builtin = @import("builtin"); |
| 2 | ||
| 3 | 2 | const std = @import("std"); |
| 4 | const math = std.math; | |
| 3 | const testing = std.testing; | |
| 4 | ||
| 5 | const impl = @import("extendf.zig"); | |
| 6 | ||
| 7 | const f32_floatCast_f16 = impl.f32_floatCast_f16; | |
| 8 | const f64_floatCast_f16 = impl.f64_floatCast_f16; | |
| 9 | const f80_floatCast_f16 = impl.f80_floatCast_f16; | |
| 10 | const f128_floatCast_f16 = impl.f128_floatCast_f16; | |
| 11 | ||
| 12 | const f64_floatCast_f32 = impl.f64_floatCast_f32; | |
| 13 | const f80_floatCast_f32 = impl.f80_floatCast_f32; | |
| 14 | const f128_floatCast_f32 = impl.f128_floatCast_f32; | |
| 5 | 15 | |
| 6 | const __extendhfsf2 = @import("extendhfsf2.zig").__extendhfsf2; | |
| 7 | const __extendhftf2 = @import("extendhftf2.zig").__extendhftf2; | |
| 8 | const __extendsftf2 = @import("extendsftf2.zig").__extendsftf2; | |
| 9 | const __extenddftf2 = @import("extenddftf2.zig").__extenddftf2; | |
| 10 | const __extenddfxf2 = @import("extenddfxf2.zig").__extenddfxf2; | |
| 11 | const F16T = @import("../compiler_rt.zig").F16T; | |
| 16 | const f80_floatCast_f64 = impl.f80_floatCast_f64; | |
| 17 | const f128_floatCast_f64 = impl.f128_floatCast_f64; | |
| 12 | 18 | |
| 13 | fn test__extenddfxf2(a: f64, expected: u80) !void { | |
| 14 | const x = __extenddfxf2(a); | |
| 19 | const f128_floatCast_f80 = impl.f128_floatCast_f80; | |
| 20 | ||
| 21 | fn test_f80_floatCast_f64(a: f64, expected: u80) !void { | |
| 22 | const x = f80_floatCast_f64(a); | |
| 15 | 23 | |
| 16 | 24 | const rep: u80 = @bitCast(x); |
| 17 | 25 | if (rep == expected) |
| 18 | 26 | return; |
| 19 | ||
| 20 | 27 | // test other possible NaN representation(signal NaN) |
| 21 | if (math.isNan(@as(f80, @bitCast(expected))) and math.isNan(x)) | |
| 28 | if (std.math.isNan(@as(f80, @bitCast(expected))) and std.math.isNan(x)) | |
| 22 | 29 | return; |
| 23 | ||
| 24 | @panic("__extenddfxf2 test failure"); | |
| 30 | return error.TestFailure; | |
| 25 | 31 | } |
| 26 | 32 | |
| 27 | fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void { | |
| 28 | const x = __extenddftf2(a); | |
| 33 | fn test_f128_floatCast_f64(a: f64, expected_hi: u64, expected_lo: u64) !void { | |
| 34 | const x = f128_floatCast_f64(a); | |
| 29 | 35 | |
| 30 | 36 | const rep: u128 = @bitCast(x); |
| 31 | 37 | const hi: u64 = @intCast(rep >> 64); |
| ... | ... | @@ -33,7 +39,6 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void { |
| 33 | 39 | |
| 34 | 40 | if (hi == expected_hi and lo == expected_lo) |
| 35 | 41 | return; |
| 36 | ||
| 37 | 42 | // test other possible NaN representation(signal NaN) |
| 38 | 43 | if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) { |
| 39 | 44 | if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and |
| ... | ... | @@ -42,12 +47,11 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void { |
| 42 | 47 | return; |
| 43 | 48 | } |
| 44 | 49 | } |
| 45 | ||
| 46 | @panic("__extenddftf2 test failure"); | |
| 50 | return error.TestFailure; | |
| 47 | 51 | } |
| 48 | 52 | |
| 49 | fn test__extendhfsf2(a: u16, expected: u32) !void { | |
| 50 | const x = __extendhfsf2(@as(F16T(f32), @bitCast(a))); | |
| 53 | fn test_f32_floatCast_f16(a: u16, expected: u32) !void { | |
| 54 | const x = f32_floatCast_f16(@bitCast(a)); | |
| 51 | 55 | const rep: u32 = @bitCast(x); |
| 52 | 56 | |
| 53 | 57 | if (rep == expected) { |
| ... | ... | @@ -58,12 +62,11 @@ fn test__extendhfsf2(a: u16, expected: u32) !void { |
| 58 | 62 | return; |
| 59 | 63 | } |
| 60 | 64 | } |
| 61 | ||
| 62 | 65 | return error.TestFailure; |
| 63 | 66 | } |
| 64 | 67 | |
| 65 | fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void { | |
| 66 | const x = __extendsftf2(a); | |
| 68 | fn test_f128_floatCast_f32(a: f32, expected_hi: u64, expected_lo: u64) !void { | |
| 69 | const x = f128_floatCast_f32(a); | |
| 67 | 70 | |
| 68 | 71 | const rep: u128 = @bitCast(x); |
| 69 | 72 | const hi: u64 = @intCast(rep >> 64); |
| ... | ... | @@ -71,7 +74,6 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void { |
| 71 | 74 | |
| 72 | 75 | if (hi == expected_hi and lo == expected_lo) |
| 73 | 76 | return; |
| 74 | ||
| 75 | 77 | // test other possible NaN representation(signal NaN) |
| 76 | 78 | if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) { |
| 77 | 79 | if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and |
| ... | ... | @@ -80,111 +82,108 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void { |
| 80 | 82 | return; |
| 81 | 83 | } |
| 82 | 84 | } |
| 83 | ||
| 84 | 85 | return error.TestFailure; |
| 85 | 86 | } |
| 86 | 87 | |
| 87 | test "extenddfxf2" { | |
| 88 | test f80_floatCast_f64 { | |
| 88 | 89 | // qNaN |
| 89 | try test__extenddfxf2(makeQNaN64(), 0x7fffc000000000000000); | |
| 90 | try test_f80_floatCast_f64(makeQNaN64(), 0x7fffc000000000000000); | |
| 90 | 91 | |
| 91 | 92 | // NaN |
| 92 | try test__extenddfxf2(makeNaN64(0x7100000000000), 0x7fffe080000000000000); | |
| 93 | try test_f80_floatCast_f64(makeNaN64(0x7100000000000), 0x7fffe080000000000000); | |
| 93 | 94 | // This is bad? |
| 94 | 95 | |
| 95 | 96 | // inf |
| 96 | try test__extenddfxf2(makeInf64(), 0x7fff8000000000000000); | |
| 97 | try test_f80_floatCast_f64(makeInf64(), 0x7fff8000000000000000); | |
| 97 | 98 | |
| 98 | 99 | // zero |
| 99 | try test__extenddfxf2(0.0, 0x0); | |
| 100 | try test_f80_floatCast_f64(0.0, 0x0); | |
| 100 | 101 | |
| 101 | try test__extenddfxf2(0x0.a3456789abcdefp+6, 0x4004a3456789abcdf000); | |
| 102 | try test_f80_floatCast_f64(0x0.a3456789abcdefp+6, 0x4004a3456789abcdf000); | |
| 102 | 103 | |
| 103 | try test__extenddfxf2(0x0.edcba987654321fp-8, 0x3ff6edcba98765432000); | |
| 104 | try test_f80_floatCast_f64(0x0.edcba987654321fp-8, 0x3ff6edcba98765432000); | |
| 104 | 105 | |
| 105 | try test__extenddfxf2(0x0.a3456789abcdefp+46, 0x402ca3456789abcdf000); | |
| 106 | try test_f80_floatCast_f64(0x0.a3456789abcdefp+46, 0x402ca3456789abcdf000); | |
| 106 | 107 | |
| 107 | try test__extenddfxf2(0x0.edcba987654321fp-44, 0x3fd2edcba98765432000); | |
| 108 | try test_f80_floatCast_f64(0x0.edcba987654321fp-44, 0x3fd2edcba98765432000); | |
| 108 | 109 | |
| 109 | 110 | // subnormal |
| 110 | try test__extenddfxf2(0x1.8000000000001p-1022, 0x3c01c000000000000800); | |
| 111 | try test__extenddfxf2(0x1.8000000000002p-1023, 0x3c00c000000000001000); | |
| 111 | try test_f80_floatCast_f64(0x1.8000000000001p-1022, 0x3c01c000000000000800); | |
| 112 | try test_f80_floatCast_f64(0x1.8000000000002p-1023, 0x3c00c000000000001000); | |
| 112 | 113 | } |
| 113 | 114 | |
| 114 | test "extenddftf2" { | |
| 115 | if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; | |
| 116 | ||
| 115 | test f128_floatCast_f64 { | |
| 117 | 116 | // qNaN |
| 118 | try test__extenddftf2(makeQNaN64(), 0x7fff800000000000, 0x0); | |
| 117 | try test_f128_floatCast_f64(makeQNaN64(), 0x7fff800000000000, 0x0); | |
| 119 | 118 | |
| 120 | 119 | // NaN |
| 121 | try test__extenddftf2(makeNaN64(0x7100000000000), 0x7fff710000000000, 0x0); | |
| 120 | try test_f128_floatCast_f64(makeNaN64(0x7100000000000), 0x7fff710000000000, 0x0); | |
| 122 | 121 | |
| 123 | 122 | // inf |
| 124 | try test__extenddftf2(makeInf64(), 0x7fff000000000000, 0x0); | |
| 123 | try test_f128_floatCast_f64(makeInf64(), 0x7fff000000000000, 0x0); | |
| 125 | 124 | |
| 126 | 125 | // zero |
| 127 | try test__extenddftf2(0.0, 0x0, 0x0); | |
| 126 | try test_f128_floatCast_f64(0.0, 0x0, 0x0); | |
| 128 | 127 | |
| 129 | try test__extenddftf2(0x1.23456789abcdefp+5, 0x400423456789abcd, 0xf000000000000000); | |
| 128 | try test_f128_floatCast_f64(0x1.23456789abcdefp+5, 0x400423456789abcd, 0xf000000000000000); | |
| 130 | 129 | |
| 131 | try test__extenddftf2(0x1.edcba987654321fp-9, 0x3ff6edcba9876543, 0x2000000000000000); | |
| 130 | try test_f128_floatCast_f64(0x1.edcba987654321fp-9, 0x3ff6edcba9876543, 0x2000000000000000); | |
| 132 | 131 | |
| 133 | try test__extenddftf2(0x1.23456789abcdefp+45, 0x402c23456789abcd, 0xf000000000000000); | |
| 132 | try test_f128_floatCast_f64(0x1.23456789abcdefp+45, 0x402c23456789abcd, 0xf000000000000000); | |
| 134 | 133 | |
| 135 | try test__extenddftf2(0x1.edcba987654321fp-45, 0x3fd2edcba9876543, 0x2000000000000000); | |
| 134 | try test_f128_floatCast_f64(0x1.edcba987654321fp-45, 0x3fd2edcba9876543, 0x2000000000000000); | |
| 136 | 135 | |
| 137 | 136 | // subnormal |
| 138 | try test__extenddftf2(0x1.8p-1022, 0x3c01800000000000, 0x0); | |
| 139 | try test__extenddftf2(0x1.8p-1023, 0x3c00800000000000, 0x0); | |
| 137 | try test_f128_floatCast_f64(0x1.8p-1022, 0x3c01800000000000, 0x0); | |
| 138 | try test_f128_floatCast_f64(0x1.8p-1023, 0x3c00800000000000, 0x0); | |
| 140 | 139 | } |
| 141 | 140 | |
| 142 | test "extendhfsf2" { | |
| 143 | try test__extendhfsf2(0x7e00, 0x7fc00000); // qNaN | |
| 144 | try test__extendhfsf2(0x7f00, 0x7fe00000); // sNaN | |
| 141 | test f32_floatCast_f16 { | |
| 142 | try test_f32_floatCast_f16(0x7e00, 0x7fc00000); // qNaN | |
| 143 | try test_f32_floatCast_f16(0x7f00, 0x7fe00000); // sNaN | |
| 145 | 144 | // On x86 the NaN becomes quiet because the return is pushed on the x87 |
| 146 | 145 | // stack due to ABI requirements |
| 147 | 146 | if (builtin.target.cpu.arch != .x86 and builtin.target.os.tag == .windows) |
| 148 | try test__extendhfsf2(0x7c01, 0x7f802000); // sNaN | |
| 147 | try test_f32_floatCast_f16(0x7c01, 0x7f802000); // sNaN | |
| 149 | 148 | |
| 150 | try test__extendhfsf2(0, 0); // 0 | |
| 151 | try test__extendhfsf2(0x8000, 0x80000000); // -0 | |
| 149 | try test_f32_floatCast_f16(0, 0); // 0 | |
| 150 | try test_f32_floatCast_f16(0x8000, 0x80000000); // -0 | |
| 152 | 151 | |
| 153 | try test__extendhfsf2(0x7c00, 0x7f800000); // inf | |
| 154 | try test__extendhfsf2(0xfc00, 0xff800000); // -inf | |
| 152 | try test_f32_floatCast_f16(0x7c00, 0x7f800000); // inf | |
| 153 | try test_f32_floatCast_f16(0xfc00, 0xff800000); // -inf | |
| 155 | 154 | |
| 156 | try test__extendhfsf2(0x0001, 0x33800000); // denormal (min), 2**-24 | |
| 157 | try test__extendhfsf2(0x8001, 0xb3800000); // denormal (min), -2**-24 | |
| 155 | try test_f32_floatCast_f16(0x0001, 0x33800000); // denormal (min), 2**-24 | |
| 156 | try test_f32_floatCast_f16(0x8001, 0xb3800000); // denormal (min), -2**-24 | |
| 158 | 157 | |
| 159 | try test__extendhfsf2(0x03ff, 0x387fc000); // denormal (max), 2**-14 - 2**-24 | |
| 160 | try test__extendhfsf2(0x83ff, 0xb87fc000); // denormal (max), -2**-14 + 2**-24 | |
| 158 | try test_f32_floatCast_f16(0x03ff, 0x387fc000); // denormal (max), 2**-14 - 2**-24 | |
| 159 | try test_f32_floatCast_f16(0x83ff, 0xb87fc000); // denormal (max), -2**-14 + 2**-24 | |
| 161 | 160 | |
| 162 | try test__extendhfsf2(0x0400, 0x38800000); // normal (min), 2**-14 | |
| 163 | try test__extendhfsf2(0x8400, 0xb8800000); // normal (min), -2**-14 | |
| 161 | try test_f32_floatCast_f16(0x0400, 0x38800000); // normal (min), 2**-14 | |
| 162 | try test_f32_floatCast_f16(0x8400, 0xb8800000); // normal (min), -2**-14 | |
| 164 | 163 | |
| 165 | try test__extendhfsf2(0x7bff, 0x477fe000); // normal (max), 65504 | |
| 166 | try test__extendhfsf2(0xfbff, 0xc77fe000); // normal (max), -65504 | |
| 164 | try test_f32_floatCast_f16(0x7bff, 0x477fe000); // normal (max), 65504 | |
| 165 | try test_f32_floatCast_f16(0xfbff, 0xc77fe000); // normal (max), -65504 | |
| 167 | 166 | |
| 168 | try test__extendhfsf2(0x3c01, 0x3f802000); // normal, 1 + 2**-10 | |
| 169 | try test__extendhfsf2(0xbc01, 0xbf802000); // normal, -1 - 2**-10 | |
| 167 | try test_f32_floatCast_f16(0x3c01, 0x3f802000); // normal, 1 + 2**-10 | |
| 168 | try test_f32_floatCast_f16(0xbc01, 0xbf802000); // normal, -1 - 2**-10 | |
| 170 | 169 | |
| 171 | try test__extendhfsf2(0x3555, 0x3eaaa000); // normal, approx. 1/3 | |
| 172 | try test__extendhfsf2(0xb555, 0xbeaaa000); // normal, approx. -1/3 | |
| 170 | try test_f32_floatCast_f16(0x3555, 0x3eaaa000); // normal, approx. 1/3 | |
| 171 | try test_f32_floatCast_f16(0xb555, 0xbeaaa000); // normal, approx. -1/3 | |
| 173 | 172 | } |
| 174 | 173 | |
| 175 | test "extendsftf2" { | |
| 174 | test f128_floatCast_f32 { | |
| 176 | 175 | // qNaN |
| 177 | try test__extendsftf2(makeQNaN32(), 0x7fff800000000000, 0x0); | |
| 176 | try test_f128_floatCast_f32(makeQNaN32(), 0x7fff800000000000, 0x0); | |
| 178 | 177 | // NaN |
| 179 | try test__extendsftf2(makeNaN32(0x410000), 0x7fff820000000000, 0x0); | |
| 178 | try test_f128_floatCast_f32(makeNaN32(0x410000), 0x7fff820000000000, 0x0); | |
| 180 | 179 | // inf |
| 181 | try test__extendsftf2(makeInf32(), 0x7fff000000000000, 0x0); | |
| 180 | try test_f128_floatCast_f32(makeInf32(), 0x7fff000000000000, 0x0); | |
| 182 | 181 | // zero |
| 183 | try test__extendsftf2(0.0, 0x0, 0x0); | |
| 184 | try test__extendsftf2(0x1.23456p+5, 0x4004234560000000, 0x0); | |
| 185 | try test__extendsftf2(0x1.edcbap-9, 0x3ff6edcba0000000, 0x0); | |
| 186 | try test__extendsftf2(0x1.23456p+45, 0x402c234560000000, 0x0); | |
| 187 | try test__extendsftf2(0x1.edcbap-45, 0x3fd2edcba0000000, 0x0); | |
| 182 | try test_f128_floatCast_f32(0.0, 0x0, 0x0); | |
| 183 | try test_f128_floatCast_f32(0x1.23456p+5, 0x4004234560000000, 0x0); | |
| 184 | try test_f128_floatCast_f32(0x1.edcbap-9, 0x3ff6edcba0000000, 0x0); | |
| 185 | try test_f128_floatCast_f32(0x1.23456p+45, 0x402c234560000000, 0x0); | |
| 186 | try test_f128_floatCast_f32(0x1.edcbap-45, 0x3fd2edcba0000000, 0x0); | |
| 188 | 187 | } |
| 189 | 188 | |
| 190 | 189 | fn makeQNaN64() f64 { |
| ... | ... | @@ -211,8 +210,8 @@ fn makeInf32() f32 { |
| 211 | 210 | return @bitCast(@as(u32, 0x7f800000)); |
| 212 | 211 | } |
| 213 | 212 | |
| 214 | fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void { | |
| 215 | const x = __extendhftf2(@as(F16T(f128), @bitCast(a))); | |
| 213 | fn test_f128_floatCast_f16(a: u16, expected_hi: u64, expected_lo: u64) !void { | |
| 214 | const x = f128_floatCast_f16(@bitCast(a)); | |
| 216 | 215 | |
| 217 | 216 | const rep: u128 = @bitCast(x); |
| 218 | 217 | const hi: u64 = @intCast(rep >> 64); |
| ... | ... | @@ -233,26 +232,26 @@ fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void { |
| 233 | 232 | return error.TestFailure; |
| 234 | 233 | } |
| 235 | 234 | |
| 236 | test "extendhftf2" { | |
| 235 | test f128_floatCast_f16 { | |
| 237 | 236 | // qNaN |
| 238 | try test__extendhftf2(0x7e00, 0x7fff800000000000, 0x0); | |
| 237 | try test_f128_floatCast_f16(0x7e00, 0x7fff800000000000, 0x0); | |
| 239 | 238 | // NaN |
| 240 | try test__extendhftf2(0x7d00, 0x7fff400000000000, 0x0); | |
| 239 | try test_f128_floatCast_f16(0x7d00, 0x7fff400000000000, 0x0); | |
| 241 | 240 | // inf |
| 242 | try test__extendhftf2(0x7c00, 0x7fff000000000000, 0x0); | |
| 243 | try test__extendhftf2(0xfc00, 0xffff000000000000, 0x0); | |
| 241 | try test_f128_floatCast_f16(0x7c00, 0x7fff000000000000, 0x0); | |
| 242 | try test_f128_floatCast_f16(0xfc00, 0xffff000000000000, 0x0); | |
| 244 | 243 | // zero |
| 245 | try test__extendhftf2(0x0000, 0x0000000000000000, 0x0); | |
| 246 | try test__extendhftf2(0x8000, 0x8000000000000000, 0x0); | |
| 244 | try test_f128_floatCast_f16(0x0000, 0x0000000000000000, 0x0); | |
| 245 | try test_f128_floatCast_f16(0x8000, 0x8000000000000000, 0x0); | |
| 247 | 246 | // denormal |
| 248 | try test__extendhftf2(0x0010, 0x3feb000000000000, 0x0); | |
| 249 | try test__extendhftf2(0x0001, 0x3fe7000000000000, 0x0); | |
| 250 | try test__extendhftf2(0x8001, 0xbfe7000000000000, 0x0); | |
| 247 | try test_f128_floatCast_f16(0x0010, 0x3feb000000000000, 0x0); | |
| 248 | try test_f128_floatCast_f16(0x0001, 0x3fe7000000000000, 0x0); | |
| 249 | try test_f128_floatCast_f16(0x8001, 0xbfe7000000000000, 0x0); | |
| 251 | 250 | |
| 252 | 251 | // pi |
| 253 | try test__extendhftf2(0x4248, 0x4000920000000000, 0x0); | |
| 254 | try test__extendhftf2(0xc248, 0xc000920000000000, 0x0); | |
| 252 | try test_f128_floatCast_f16(0x4248, 0x4000920000000000, 0x0); | |
| 253 | try test_f128_floatCast_f16(0xc248, 0xc000920000000000, 0x0); | |
| 255 | 254 | |
| 256 | try test__extendhftf2(0x508c, 0x4004230000000000, 0x0); | |
| 257 | try test__extendhftf2(0x1bb7, 0x3ff6edc000000000, 0x0); | |
| 255 | try test_f128_floatCast_f16(0x508c, 0x4004230000000000, 0x0); | |
| 256 | try test_f128_floatCast_f16(0x1bb7, 0x3ff6edc000000000, 0x0); | |
| 258 | 257 | } |
lib/compiler_rt/extendhfdf2.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | const extendf = @import("./extendf.zig").extendf; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__extendhfdf2, "__extendhfdf2"); | |
| 7 | } | |
| 8 | ||
| 9 | pub fn __extendhfdf2(a: compiler_rt.F16T(f64)) callconv(.c) f64 { | |
| 10 | return extendf(f64, f16, @as(u16, @bitCast(a))); | |
| 11 | } |
lib/compiler_rt/extendhfsf2.zig deleted-24| ... | ... | @@ -1,24 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const extendf = @import("./extendf.zig").extendf; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.gnu_f16_abi) { | |
| 7 | symbol(&__gnu_h2f_ieee, "__gnu_h2f_ieee"); | |
| 8 | } else if (compiler_rt.want_aeabi) { | |
| 9 | symbol(&__aeabi_h2f, "__aeabi_h2f"); | |
| 10 | } | |
| 11 | symbol(&__extendhfsf2, "__extendhfsf2"); | |
| 12 | } | |
| 13 | ||
| 14 | pub fn __extendhfsf2(a: compiler_rt.F16T(f32)) callconv(.c) f32 { | |
| 15 | return extendf(f32, f16, @as(u16, @bitCast(a))); | |
| 16 | } | |
| 17 | ||
| 18 | fn __gnu_h2f_ieee(a: compiler_rt.F16T(f32)) callconv(.c) f32 { | |
| 19 | return extendf(f32, f16, @as(u16, @bitCast(a))); | |
| 20 | } | |
| 21 | ||
| 22 | fn __aeabi_h2f(a: u16) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 23 | return extendf(f32, f16, @as(u16, @bitCast(a))); | |
| 24 | } |
lib/compiler_rt/extendhftf2.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const extendf = @import("./extendf.zig").extendf; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__extendhftf2, "__extendhftf2"); | |
| 7 | } | |
| 8 | ||
| 9 | pub fn __extendhftf2(a: compiler_rt.F16T(f128)) callconv(.c) f128 { | |
| 10 | return extendf(f128, f16, @as(u16, @bitCast(a))); | |
| 11 | } |
lib/compiler_rt/extendhfxf2.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const extend_f80 = @import("./extendf.zig").extend_f80; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__extendhfxf2, "__extendhfxf2"); | |
| 7 | } | |
| 8 | ||
| 9 | fn __extendhfxf2(a: compiler_rt.F16T(f80)) callconv(.c) f80 { | |
| 10 | return extend_f80(f16, @as(u16, @bitCast(a))); | |
| 11 | } |
lib/compiler_rt/extendsfdf2.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const extendf = @import("./extendf.zig").extendf; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_f2d, "__aeabi_f2d"); | |
| 8 | } else { | |
| 9 | symbol(&__extendsfdf2, "__extendsfdf2"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | fn __extendsfdf2(a: f32) callconv(.c) f64 { | |
| 14 | return extendf(f64, f32, @as(u32, @bitCast(a))); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_f2d(a: f32) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 18 | return extendf(f64, f32, @as(u32, @bitCast(a))); | |
| 19 | } |
lib/compiler_rt/extendsftf2.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const extendf = @import("./extendf.zig").extendf; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) { | |
| 7 | symbol(&__extendsftf2, "__extendsfkf2"); | |
| 8 | } else if (compiler_rt.want_sparc64_abi) { | |
| 9 | symbol(&_Qp_stoq, "_Qp_stoq"); | |
| 10 | } else if (compiler_rt.want_sparc32_abi) { | |
| 11 | symbol(&__extendsftf2, "_Q_stoq"); | |
| 12 | } | |
| 13 | symbol(&__extendsftf2, "__extendsftf2"); | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __extendsftf2(a: f32) callconv(.c) f128 { | |
| 17 | return extendf(f128, f32, @as(u32, @bitCast(a))); | |
| 18 | } | |
| 19 | ||
| 20 | fn _Qp_stoq(c: *f128, a: f32) callconv(.c) void { | |
| 21 | c.* = extendf(f128, f32, @as(u32, @bitCast(a))); | |
| 22 | } |
lib/compiler_rt/extendsfxf2.zig deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 2 | const extend_f80 = @import("./extendf.zig").extend_f80; | |
| 3 | ||
| 4 | comptime { | |
| 5 | symbol(&__extendsfxf2, "__extendsfxf2"); | |
| 6 | } | |
| 7 | ||
| 8 | fn __extendsfxf2(a: f32) callconv(.c) f80 { | |
| 9 | return extend_f80(f32, @as(u32, @bitCast(a))); | |
| 10 | } |
lib/compiler_rt/extendxftf2.zig deleted-42| ... | ... | @@ -1,42 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__extendxftf2, "__extendxftf2"); | |
| 7 | } | |
| 8 | ||
| 9 | fn __extendxftf2(a: f80) callconv(.c) f128 { | |
| 10 | const src_int_bit: u64 = 0x8000000000000000; | |
| 11 | const src_sig_mask = ~src_int_bit; | |
| 12 | const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit | |
| 13 | const dst_sig_bits = std.math.floatMantissaBits(f128); | |
| 14 | ||
| 15 | const dst_bits = @bitSizeOf(f128); | |
| 16 | ||
| 17 | // Break a into a sign and representation of the absolute value | |
| 18 | var a_rep = std.math.F80.fromFloat(a); | |
| 19 | const sign = a_rep.exp & 0x8000; | |
| 20 | a_rep.exp &= 0x7FFF; | |
| 21 | var abs_result: u128 = undefined; | |
| 22 | ||
| 23 | if (a_rep.exp == 0 and a_rep.fraction == 0) { | |
| 24 | // zero | |
| 25 | abs_result = 0; | |
| 26 | } else if (a_rep.exp == 0x7FFF) { | |
| 27 | // a is nan or infinite | |
| 28 | abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits); | |
| 29 | abs_result |= @as(u128, a_rep.exp) << dst_sig_bits; | |
| 30 | } else if (a_rep.fraction & src_int_bit != 0) { | |
| 31 | // a is a normal value | |
| 32 | abs_result = @as(u128, a_rep.fraction & src_sig_mask) << (dst_sig_bits - src_sig_bits); | |
| 33 | abs_result |= @as(u128, a_rep.exp) << dst_sig_bits; | |
| 34 | } else { | |
| 35 | // a is denormal | |
| 36 | abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits); | |
| 37 | } | |
| 38 | ||
| 39 | // Apply the signbit to (dst_t)abs(a). | |
| 40 | const result: u128 align(@alignOf(f128)) = abs_result | @as(u128, sign) << (dst_bits - 16); | |
| 41 | return @bitCast(result); | |
| 42 | } |
lib/compiler_rt/fabs.zig+24-9| ... | ... | @@ -16,32 +16,47 @@ comptime { |
| 16 | 16 | symbol(&fabsl, "fabsl"); |
| 17 | 17 | } |
| 18 | 18 | |
| 19 | pub fn __fabsh(a: f16) callconv(.c) f16 { | |
| 19 | fn __fabsh(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 20 | return compiler_rt.f16.toAbi(fabs_f16(compiler_rt.f16.fromAbi(a))); | |
| 21 | } | |
| 22 | pub fn fabs_f16(a: f16) f16 { | |
| 20 | 23 | return generic_fabs(a); |
| 21 | 24 | } |
| 22 | 25 | |
| 23 | pub fn fabsf(a: f32) callconv(.c) f32 { | |
| 26 | fn fabsf(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 27 | return compiler_rt.f32.toAbi(fabs_f32(compiler_rt.f32.fromAbi(a))); | |
| 28 | } | |
| 29 | pub fn fabs_f32(a: f32) f32 { | |
| 24 | 30 | return generic_fabs(a); |
| 25 | 31 | } |
| 26 | 32 | |
| 27 | pub fn fabs(a: f64) callconv(.c) f64 { | |
| 33 | fn fabs(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 34 | return compiler_rt.f64.toAbi(fabs_f64(compiler_rt.f64.fromAbi(a))); | |
| 35 | } | |
| 36 | pub fn fabs_f64(a: f64) f64 { | |
| 28 | 37 | return generic_fabs(a); |
| 29 | 38 | } |
| 30 | 39 | |
| 31 | pub fn __fabsx(a: f80) callconv(.c) f80 { | |
| 40 | fn __fabsx(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 41 | return compiler_rt.f80.toAbi(fabs_f80(compiler_rt.f80.fromAbi(a))); | |
| 42 | } | |
| 43 | pub fn fabs_f80(a: f80) f80 { | |
| 32 | 44 | return generic_fabs(a); |
| 33 | 45 | } |
| 34 | 46 | |
| 35 | pub fn fabsq(a: f128) callconv(.c) f128 { | |
| 47 | fn fabsq(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 48 | return compiler_rt.f128.toAbi(fabs_f128(compiler_rt.f128.fromAbi(a))); | |
| 49 | } | |
| 50 | pub fn fabs_f128(a: f128) f128 { | |
| 36 | 51 | return generic_fabs(a); |
| 37 | 52 | } |
| 38 | 53 | |
| 39 | 54 | pub fn fabsl(x: c_longdouble) callconv(.c) c_longdouble { |
| 40 | 55 | switch (@typeInfo(c_longdouble).float.bits) { |
| 41 | 64 => return fabs(x), | |
| 42 | 80 => return __fabsx(x), | |
| 43 | 128 => return fabsq(x), | |
| 44 | else => @compileError("unreachable"), | |
| 56 | 64 => return fabs_f64(x), | |
| 57 | 80 => return fabs_f80(x), | |
| 58 | 128 => return fabs_f128(x), | |
| 59 | else => comptime unreachable, | |
| 45 | 60 | } |
| 46 | 61 | } |
| 47 | 62 |
lib/compiler_rt/fixdfdi.zig deleted-23| ... | ... | @@ -1,23 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 3 | const symbol = compiler_rt.symbol; | |
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 5 | ||
| 6 | comptime { | |
| 7 | if (compiler_rt.want_aeabi) { | |
| 8 | symbol(&__aeabi_d2lz, "__aeabi_d2lz"); | |
| 9 | } else { | |
| 10 | if (compiler_rt.want_windows_arm_abi) { | |
| 11 | symbol(&__fixdfdi, "__dtoi64"); | |
| 12 | } | |
| 13 | symbol(&__fixdfdi, "__fixdfdi"); | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | pub fn __fixdfdi(a: f64) callconv(.c) i64 { | |
| 18 | return intFromFloat(i64, a); | |
| 19 | } | |
| 20 | ||
| 21 | fn __aeabi_d2lz(a: f64) callconv(.{ .arm_aapcs = .{} }) i64 { | |
| 22 | return intFromFloat(i64, a); | |
| 23 | } |
lib/compiler_rt/fixdfei.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | |
| 6 | ||
| 7 | comptime { | |
| 8 | symbol(&__fixdfei, "__fixdfei"); | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __fixdfei(r: [*]u8, bits: usize, a: f64) callconv(.c) void { | |
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 13 | return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); | |
| 14 | } |
lib/compiler_rt/fixdfsi.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_d2iz, "__aeabi_d2iz"); | |
| 8 | } else { | |
| 9 | symbol(&__fixdfsi, "__fixdfsi"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | pub fn __fixdfsi(a: f64) callconv(.c) i32 { | |
| 14 | return intFromFloat(i32, a); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_d2iz(a: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 18 | return intFromFloat(i32, a); | |
| 19 | } |
lib/compiler_rt/fixdfti.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__fixdfti, "__fixdfti"); | |
| 7 | } | |
| 8 | ||
| 9 | pub fn __fixdfti(a: f64) callconv(.c) i128 { | |
| 10 | return intFromFloat(i128, a); | |
| 11 | } |
lib/compiler_rt/fixhfei.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | |
| 6 | ||
| 7 | comptime { | |
| 8 | symbol(&__fixhfei, "__fixhfei"); | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __fixhfei(r: [*]u8, bits: usize, a: f16) callconv(.c) void { | |
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 13 | return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); | |
| 14 | } |
lib/compiler_rt/fixint_test.zig deleted-149| ... | ... | @@ -1,149 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const math = std.math; | |
| 3 | const testing = std.testing; | |
| 4 | ||
| 5 | const fixint = @import("fixint.zig").fixint; | |
| 6 | ||
| 7 | fn test__fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t, expected: fixint_t) !void { | |
| 8 | const x = fixint(fp_t, fixint_t, a); | |
| 9 | try testing.expect(x == expected); | |
| 10 | } | |
| 11 | ||
| 12 | test "fixint.i1" { | |
| 13 | try test__fixint(f32, i1, -math.inf(f32), -1); | |
| 14 | try test__fixint(f32, i1, -math.floatMax(f32), -1); | |
| 15 | try test__fixint(f32, i1, -2.0, -1); | |
| 16 | try test__fixint(f32, i1, -1.1, -1); | |
| 17 | try test__fixint(f32, i1, -1.0, -1); | |
| 18 | try test__fixint(f32, i1, -0.9, 0); | |
| 19 | try test__fixint(f32, i1, -0.1, 0); | |
| 20 | try test__fixint(f32, i1, -math.floatMin(f32), 0); | |
| 21 | try test__fixint(f32, i1, -0.0, 0); | |
| 22 | try test__fixint(f32, i1, 0.0, 0); | |
| 23 | try test__fixint(f32, i1, math.floatMin(f32), 0); | |
| 24 | try test__fixint(f32, i1, 0.1, 0); | |
| 25 | try test__fixint(f32, i1, 0.9, 0); | |
| 26 | try test__fixint(f32, i1, 1.0, 0); | |
| 27 | try test__fixint(f32, i1, 2.0, 0); | |
| 28 | try test__fixint(f32, i1, math.floatMax(f32), 0); | |
| 29 | try test__fixint(f32, i1, math.inf(f32), 0); | |
| 30 | } | |
| 31 | ||
| 32 | test "fixint.i2" { | |
| 33 | try test__fixint(f32, i2, -math.inf(f32), -2); | |
| 34 | try test__fixint(f32, i2, -math.floatMax(f32), -2); | |
| 35 | try test__fixint(f32, i2, -2.0, -2); | |
| 36 | try test__fixint(f32, i2, -1.9, -1); | |
| 37 | try test__fixint(f32, i2, -1.1, -1); | |
| 38 | try test__fixint(f32, i2, -1.0, -1); | |
| 39 | try test__fixint(f32, i2, -0.9, 0); | |
| 40 | try test__fixint(f32, i2, -0.1, 0); | |
| 41 | try test__fixint(f32, i2, -math.floatMin(f32), 0); | |
| 42 | try test__fixint(f32, i2, -0.0, 0); | |
| 43 | try test__fixint(f32, i2, 0.0, 0); | |
| 44 | try test__fixint(f32, i2, math.floatMin(f32), 0); | |
| 45 | try test__fixint(f32, i2, 0.1, 0); | |
| 46 | try test__fixint(f32, i2, 0.9, 0); | |
| 47 | try test__fixint(f32, i2, 1.0, 1); | |
| 48 | try test__fixint(f32, i2, 2.0, 1); | |
| 49 | try test__fixint(f32, i2, math.floatMax(f32), 1); | |
| 50 | try test__fixint(f32, i2, math.inf(f32), 1); | |
| 51 | } | |
| 52 | ||
| 53 | test "fixint.i3" { | |
| 54 | try test__fixint(f32, i3, -math.inf(f32), -4); | |
| 55 | try test__fixint(f32, i3, -math.floatMax(f32), -4); | |
| 56 | try test__fixint(f32, i3, -4.0, -4); | |
| 57 | try test__fixint(f32, i3, -3.0, -3); | |
| 58 | try test__fixint(f32, i3, -2.0, -2); | |
| 59 | try test__fixint(f32, i3, -1.9, -1); | |
| 60 | try test__fixint(f32, i3, -1.1, -1); | |
| 61 | try test__fixint(f32, i3, -1.0, -1); | |
| 62 | try test__fixint(f32, i3, -0.9, 0); | |
| 63 | try test__fixint(f32, i3, -0.1, 0); | |
| 64 | try test__fixint(f32, i3, -math.floatMin(f32), 0); | |
| 65 | try test__fixint(f32, i3, -0.0, 0); | |
| 66 | try test__fixint(f32, i3, 0.0, 0); | |
| 67 | try test__fixint(f32, i3, math.floatMin(f32), 0); | |
| 68 | try test__fixint(f32, i3, 0.1, 0); | |
| 69 | try test__fixint(f32, i3, 0.9, 0); | |
| 70 | try test__fixint(f32, i3, 1.0, 1); | |
| 71 | try test__fixint(f32, i3, 2.0, 2); | |
| 72 | try test__fixint(f32, i3, 3.0, 3); | |
| 73 | try test__fixint(f32, i3, 4.0, 3); | |
| 74 | try test__fixint(f32, i3, math.floatMax(f32), 3); | |
| 75 | try test__fixint(f32, i3, math.inf(f32), 3); | |
| 76 | } | |
| 77 | ||
| 78 | test "fixint.i32" { | |
| 79 | try test__fixint(f64, i32, -math.inf(f64), math.minInt(i32)); | |
| 80 | try test__fixint(f64, i32, -math.floatMax(f64), math.minInt(i32)); | |
| 81 | try test__fixint(f64, i32, @as(f64, math.minInt(i32)), math.minInt(i32)); | |
| 82 | try test__fixint(f64, i32, @as(f64, math.minInt(i32)) + 1, math.minInt(i32) + 1); | |
| 83 | try test__fixint(f64, i32, -2.0, -2); | |
| 84 | try test__fixint(f64, i32, -1.9, -1); | |
| 85 | try test__fixint(f64, i32, -1.1, -1); | |
| 86 | try test__fixint(f64, i32, -1.0, -1); | |
| 87 | try test__fixint(f64, i32, -0.9, 0); | |
| 88 | try test__fixint(f64, i32, -0.1, 0); | |
| 89 | try test__fixint(f64, i32, -@as(f64, math.floatMin(f32)), 0); | |
| 90 | try test__fixint(f64, i32, -0.0, 0); | |
| 91 | try test__fixint(f64, i32, 0.0, 0); | |
| 92 | try test__fixint(f64, i32, @as(f64, math.floatMin(f32)), 0); | |
| 93 | try test__fixint(f64, i32, 0.1, 0); | |
| 94 | try test__fixint(f64, i32, 0.9, 0); | |
| 95 | try test__fixint(f64, i32, 1.0, 1); | |
| 96 | try test__fixint(f64, i32, @as(f64, math.maxInt(i32)) - 1, math.maxInt(i32) - 1); | |
| 97 | try test__fixint(f64, i32, @as(f64, math.maxInt(i32)), math.maxInt(i32)); | |
| 98 | try test__fixint(f64, i32, math.floatMax(f64), math.maxInt(i32)); | |
| 99 | try test__fixint(f64, i32, math.inf(f64), math.maxInt(i32)); | |
| 100 | } | |
| 101 | ||
| 102 | test "fixint.i64" { | |
| 103 | try test__fixint(f64, i64, -math.inf(f64), math.minInt(i64)); | |
| 104 | try test__fixint(f64, i64, -math.floatMax(f64), math.minInt(i64)); | |
| 105 | try test__fixint(f64, i64, @as(f64, math.minInt(i64)), math.minInt(i64)); | |
| 106 | try test__fixint(f64, i64, @as(f64, math.minInt(i64)) + 1, math.minInt(i64)); | |
| 107 | try test__fixint(f64, i64, @as(f64, math.minInt(i64) / 2), math.minInt(i64) / 2); | |
| 108 | try test__fixint(f64, i64, -2.0, -2); | |
| 109 | try test__fixint(f64, i64, -1.9, -1); | |
| 110 | try test__fixint(f64, i64, -1.1, -1); | |
| 111 | try test__fixint(f64, i64, -1.0, -1); | |
| 112 | try test__fixint(f64, i64, -0.9, 0); | |
| 113 | try test__fixint(f64, i64, -0.1, 0); | |
| 114 | try test__fixint(f64, i64, -@as(f64, math.floatMin(f32)), 0); | |
| 115 | try test__fixint(f64, i64, -0.0, 0); | |
| 116 | try test__fixint(f64, i64, 0.0, 0); | |
| 117 | try test__fixint(f64, i64, @as(f64, math.floatMin(f32)), 0); | |
| 118 | try test__fixint(f64, i64, 0.1, 0); | |
| 119 | try test__fixint(f64, i64, 0.9, 0); | |
| 120 | try test__fixint(f64, i64, 1.0, 1); | |
| 121 | try test__fixint(f64, i64, @as(f64, math.maxInt(i64)) - 1, math.maxInt(i64)); | |
| 122 | try test__fixint(f64, i64, @as(f64, math.maxInt(i64)), math.maxInt(i64)); | |
| 123 | try test__fixint(f64, i64, math.floatMax(f64), math.maxInt(i64)); | |
| 124 | try test__fixint(f64, i64, math.inf(f64), math.maxInt(i64)); | |
| 125 | } | |
| 126 | ||
| 127 | test "fixint.i128" { | |
| 128 | try test__fixint(f64, i128, -math.inf(f64), math.minInt(i128)); | |
| 129 | try test__fixint(f64, i128, -math.floatMax(f64), math.minInt(i128)); | |
| 130 | try test__fixint(f64, i128, @as(f64, math.minInt(i128)), math.minInt(i128)); | |
| 131 | try test__fixint(f64, i128, @as(f64, math.minInt(i128)) + 1, math.minInt(i128)); | |
| 132 | try test__fixint(f64, i128, -2.0, -2); | |
| 133 | try test__fixint(f64, i128, -1.9, -1); | |
| 134 | try test__fixint(f64, i128, -1.1, -1); | |
| 135 | try test__fixint(f64, i128, -1.0, -1); | |
| 136 | try test__fixint(f64, i128, -0.9, 0); | |
| 137 | try test__fixint(f64, i128, -0.1, 0); | |
| 138 | try test__fixint(f64, i128, -@as(f64, math.floatMin(f32)), 0); | |
| 139 | try test__fixint(f64, i128, -0.0, 0); | |
| 140 | try test__fixint(f64, i128, 0.0, 0); | |
| 141 | try test__fixint(f64, i128, @as(f64, math.floatMin(f32)), 0); | |
| 142 | try test__fixint(f64, i128, 0.1, 0); | |
| 143 | try test__fixint(f64, i128, 0.9, 0); | |
| 144 | try test__fixint(f64, i128, 1.0, 1); | |
| 145 | try test__fixint(f64, i128, @as(f64, math.maxInt(i128)) - 1, math.maxInt(i128)); | |
| 146 | try test__fixint(f64, i128, @as(f64, math.maxInt(i128)), math.maxInt(i128)); | |
| 147 | try test__fixint(f64, i128, math.floatMax(f64), math.maxInt(i128)); | |
| 148 | try test__fixint(f64, i128, math.inf(f64), math.maxInt(i128)); | |
| 149 | } |
lib/compiler_rt/fixsfdi.zig deleted-23| ... | ... | @@ -1,23 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 4 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 5 | ||
| 6 | comptime { | |
| 7 | if (compiler_rt.want_aeabi) { | |
| 8 | symbol(&__aeabi_f2lz, "__aeabi_f2lz"); | |
| 9 | } else { | |
| 10 | if (compiler_rt.want_windows_arm_abi) { | |
| 11 | symbol(&__fixsfdi, "__stoi64"); | |
| 12 | } | |
| 13 | symbol(&__fixsfdi, "__fixsfdi"); | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | pub fn __fixsfdi(a: f32) callconv(.c) i64 { | |
| 18 | return intFromFloat(i64, a); | |
| 19 | } | |
| 20 | ||
| 21 | fn __aeabi_f2lz(a: f32) callconv(.{ .arm_aapcs = .{} }) i64 { | |
| 22 | return intFromFloat(i64, a); | |
| 23 | } |
lib/compiler_rt/fixsfei.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | |
| 6 | ||
| 7 | comptime { | |
| 8 | symbol(&__fixsfei, "__fixsfei"); | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __fixsfei(r: [*]u8, bits: usize, a: f32) callconv(.c) void { | |
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 13 | return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); | |
| 14 | } |
lib/compiler_rt/fixsfsi.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_f2iz, "__aeabi_f2iz"); | |
| 8 | } else { | |
| 9 | symbol(&__fixsfsi, "__fixsfsi"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | pub fn __fixsfsi(a: f32) callconv(.c) i32 { | |
| 14 | return intFromFloat(i32, a); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_f2iz(a: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 18 | return intFromFloat(i32, a); | |
| 19 | } |
lib/compiler_rt/fixsfti.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 3 | const symbol = compiler_rt.symbol; | |
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 5 | ||
| 6 | comptime { | |
| 7 | symbol(&__fixsfti, "__fixsfti"); | |
| 8 | } | |
| 9 | ||
| 10 | pub fn __fixsfti(a: f32) callconv(.c) i128 { | |
| 11 | return intFromFloat(i128, a); | |
| 12 | } |
lib/compiler_rt/fixtfdi.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) { | |
| 7 | symbol(&__fixtfdi, "__fixkfdi"); | |
| 8 | } else if (compiler_rt.want_sparc64_abi) { | |
| 9 | symbol(&_Qp_qtox, "_Qp_qtox"); | |
| 10 | } else if (compiler_rt.want_sparc32_abi) { | |
| 11 | symbol(&__fixtfdi, "_Q_qtoll"); | |
| 12 | } | |
| 13 | symbol(&__fixtfdi, "__fixtfdi"); | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __fixtfdi(a: f128) callconv(.c) i64 { | |
| 17 | return intFromFloat(i64, a); | |
| 18 | } | |
| 19 | ||
| 20 | fn _Qp_qtox(a: *const f128) callconv(.c) i64 { | |
| 21 | return intFromFloat(i64, a.*); | |
| 22 | } |
lib/compiler_rt/fixtfei.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | |
| 6 | ||
| 7 | comptime { | |
| 8 | symbol(&__fixtfei, "__fixtfei"); | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __fixtfei(r: [*]u8, bits: usize, a: f128) callconv(.c) void { | |
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 13 | return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); | |
| 14 | } |
lib/compiler_rt/fixtfsi.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) { | |
| 7 | symbol(&__fixtfsi, "__fixkfsi"); | |
| 8 | } else if (compiler_rt.want_sparc64_abi) { | |
| 9 | symbol(&_Qp_qtoi, "_Qp_qtoi"); | |
| 10 | } else if (compiler_rt.want_sparc32_abi) { | |
| 11 | symbol(&__fixtfsi, "_Q_qtoi"); | |
| 12 | } | |
| 13 | symbol(&__fixtfsi, "__fixtfsi"); | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __fixtfsi(a: f128) callconv(.c) i32 { | |
| 17 | return intFromFloat(i32, a); | |
| 18 | } | |
| 19 | ||
| 20 | fn _Qp_qtoi(a: *const f128) callconv(.c) i32 { | |
| 21 | return intFromFloat(i32, a.*); | |
| 22 | } |
lib/compiler_rt/fixtfti.zig deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) | |
| 7 | symbol(&__fixtfti, "__fixkfti"); | |
| 8 | symbol(&__fixtfti, "__fixtfti"); | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __fixtfti(a: f128) callconv(.c) i128 { | |
| 12 | return intFromFloat(i128, a); | |
| 13 | } |
lib/compiler_rt/fixunsdfdi.zig deleted-23| ... | ... | @@ -1,23 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 3 | const symbol = compiler_rt.symbol; | |
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 5 | ||
| 6 | comptime { | |
| 7 | if (compiler_rt.want_aeabi) { | |
| 8 | symbol(&__aeabi_d2ulz, "__aeabi_d2ulz"); | |
| 9 | } else { | |
| 10 | if (compiler_rt.want_windows_arm_abi) { | |
| 11 | symbol(&__fixunsdfdi, "__dtou64"); | |
| 12 | } | |
| 13 | symbol(&__fixunsdfdi, "__fixunsdfdi"); | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | pub fn __fixunsdfdi(a: f64) callconv(.c) u64 { | |
| 18 | return intFromFloat(u64, a); | |
| 19 | } | |
| 20 | ||
| 21 | fn __aeabi_d2ulz(a: f64) callconv(.{ .arm_aapcs = .{} }) u64 { | |
| 22 | return intFromFloat(u64, a); | |
| 23 | } |
lib/compiler_rt/fixunsdfei.zig deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | ||
| 3 | const std = @import("std"); | |
| 4 | ||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 6 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | |
| 7 | ||
| 8 | comptime { | |
| 9 | symbol(&__fixunsdfei, "__fixunsdfei"); | |
| 10 | } | |
| 11 | ||
| 12 | pub fn __fixunsdfei(r: [*]u8, bits: usize, a: f64) callconv(.c) void { | |
| 13 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 14 | return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); | |
| 15 | } |
lib/compiler_rt/fixunsdfsi.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_d2uiz, "__aeabi_d2uiz"); | |
| 8 | } else { | |
| 9 | symbol(&__fixunsdfsi, "__fixunsdfsi"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | pub fn __fixunsdfsi(a: f64) callconv(.c) u32 { | |
| 14 | return intFromFloat(u32, a); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_d2uiz(a: f64) callconv(.{ .arm_aapcs = .{} }) u32 { | |
| 18 | return intFromFloat(u32, a); | |
| 19 | } |
lib/compiler_rt/fixunsdfti.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__fixunsdfti, "__fixunsdfti"); | |
| 7 | } | |
| 8 | ||
| 9 | pub fn __fixunsdfti(a: f64) callconv(.c) u128 { | |
| 10 | return intFromFloat(u128, a); | |
| 11 | } |
lib/compiler_rt/fixunshfdi.zig deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 3 | ||
| 4 | comptime { | |
| 5 | symbol(&__fixunshfdi, "__fixunshfdi"); | |
| 6 | } | |
| 7 | ||
| 8 | fn __fixunshfdi(a: f16) callconv(.c) u64 { | |
| 9 | return intFromFloat(u64, a); | |
| 10 | } |
lib/compiler_rt/fixunshfei.zig deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | ||
| 3 | const std = @import("std"); | |
| 4 | ||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 6 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | |
| 7 | ||
| 8 | comptime { | |
| 9 | symbol(&__fixunshfei, "__fixunshfei"); | |
| 10 | } | |
| 11 | ||
| 12 | pub fn __fixunshfei(r: [*]u8, bits: usize, a: f16) callconv(.c) void { | |
| 13 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 14 | return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); | |
| 15 | } |
lib/compiler_rt/fixunshfsi.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__fixunshfsi, "__fixunshfsi"); | |
| 7 | } | |
| 8 | ||
| 9 | fn __fixunshfsi(a: f16) callconv(.c) u32 { | |
| 10 | return intFromFloat(u32, a); | |
| 11 | } |
lib/compiler_rt/fixunshfti.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__fixunshfti, "__fixunshfti"); | |
| 7 | } | |
| 8 | ||
| 9 | pub fn __fixunshfti(a: f16) callconv(.c) u128 { | |
| 10 | return intFromFloat(u128, a); | |
| 11 | } |
lib/compiler_rt/fixunssfdi.zig deleted-23| ... | ... | @@ -1,23 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 3 | const symbol = compiler_rt.symbol; | |
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 5 | ||
| 6 | comptime { | |
| 7 | if (compiler_rt.want_aeabi) { | |
| 8 | symbol(&__aeabi_f2ulz, "__aeabi_f2ulz"); | |
| 9 | } else { | |
| 10 | if (compiler_rt.want_windows_arm_abi) { | |
| 11 | symbol(&__fixunssfdi, "__stou64"); | |
| 12 | } | |
| 13 | symbol(&__fixunssfdi, "__fixunssfdi"); | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | pub fn __fixunssfdi(a: f32) callconv(.c) u64 { | |
| 18 | return intFromFloat(u64, a); | |
| 19 | } | |
| 20 | ||
| 21 | fn __aeabi_f2ulz(a: f32) callconv(.{ .arm_aapcs = .{} }) u64 { | |
| 22 | return intFromFloat(u64, a); | |
| 23 | } |
lib/compiler_rt/fixunssfei.zig deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | ||
| 3 | const std = @import("std"); | |
| 4 | ||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 6 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | |
| 7 | ||
| 8 | comptime { | |
| 9 | symbol(&__fixunssfei, "__fixunssfei"); | |
| 10 | } | |
| 11 | ||
| 12 | pub fn __fixunssfei(r: [*]u8, bits: usize, a: f32) callconv(.c) void { | |
| 13 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 14 | return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); | |
| 15 | } |
lib/compiler_rt/fixunssfsi.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_f2uiz, "__aeabi_f2uiz"); | |
| 8 | } else { | |
| 9 | symbol(&__fixunssfsi, "__fixunssfsi"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | pub fn __fixunssfsi(a: f32) callconv(.c) u32 { | |
| 14 | return intFromFloat(u32, a); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_f2uiz(a: f32) callconv(.{ .arm_aapcs = .{} }) u32 { | |
| 18 | return intFromFloat(u32, a); | |
| 19 | } |
lib/compiler_rt/fixunssfti.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 4 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 5 | ||
| 6 | comptime { | |
| 7 | symbol(&__fixunssfti, "__fixunssfti"); | |
| 8 | } | |
| 9 | ||
| 10 | pub fn __fixunssfti(a: f32) callconv(.c) u128 { | |
| 11 | return intFromFloat(u128, a); | |
| 12 | } |
lib/compiler_rt/fixunstfdi.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) { | |
| 7 | symbol(&__fixunstfdi, "__fixunskfdi"); | |
| 8 | } else if (compiler_rt.want_sparc64_abi) { | |
| 9 | symbol(&_Qp_qtoux, "_Qp_qtoux"); | |
| 10 | } else if (compiler_rt.want_sparc32_abi) { | |
| 11 | symbol(&__fixunstfdi, "_Q_qtoull"); | |
| 12 | } | |
| 13 | symbol(&__fixunstfdi, "__fixunstfdi"); | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __fixunstfdi(a: f128) callconv(.c) u64 { | |
| 17 | return intFromFloat(u64, a); | |
| 18 | } | |
| 19 | ||
| 20 | fn _Qp_qtoux(a: *const f128) callconv(.c) u64 { | |
| 21 | return intFromFloat(u64, a.*); | |
| 22 | } |
lib/compiler_rt/fixunstfei.zig deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | ||
| 3 | const std = @import("std"); | |
| 4 | ||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 6 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | |
| 7 | ||
| 8 | comptime { | |
| 9 | symbol(&__fixunstfei, "__fixunstfei"); | |
| 10 | } | |
| 11 | ||
| 12 | pub fn __fixunstfei(r: [*]u8, bits: usize, a: f128) callconv(.c) void { | |
| 13 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 14 | return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); | |
| 15 | } |
lib/compiler_rt/fixunstfsi.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) { | |
| 7 | symbol(&__fixunstfsi, "__fixunskfsi"); | |
| 8 | } else if (compiler_rt.want_sparc64_abi) { | |
| 9 | symbol(&_Qp_qtoui, "_Qp_qtoui"); | |
| 10 | } else if (compiler_rt.want_sparc32_abi) { | |
| 11 | symbol(&__fixunstfsi, "_Q_qtou"); | |
| 12 | } | |
| 13 | symbol(&__fixunstfsi, "__fixunstfsi"); | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __fixunstfsi(a: f128) callconv(.c) u32 { | |
| 17 | return intFromFloat(u32, a); | |
| 18 | } | |
| 19 | ||
| 20 | fn _Qp_qtoui(a: *const f128) callconv(.c) u32 { | |
| 21 | return intFromFloat(u32, a.*); | |
| 22 | } |
lib/compiler_rt/fixunstfti.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 3 | const symbol = compiler_rt.symbol; | |
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 5 | ||
| 6 | comptime { | |
| 7 | if (compiler_rt.want_ppc_abi) | |
| 8 | symbol(&__fixunstfti, "__fixunskfti"); | |
| 9 | symbol(&__fixunstfti, "__fixunstfti"); | |
| 10 | } | |
| 11 | ||
| 12 | pub fn __fixunstfti(a: f128) callconv(.c) u128 { | |
| 13 | return intFromFloat(u128, a); | |
| 14 | } |
lib/compiler_rt/fixunsxfdi.zig deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | ||
| 4 | comptime { | |
| 5 | symbol(&__fixunsxfdi, "__fixunsxfdi"); | |
| 6 | } | |
| 7 | ||
| 8 | fn __fixunsxfdi(a: f80) callconv(.c) u64 { | |
| 9 | return intFromFloat(u64, a); | |
| 10 | } |
lib/compiler_rt/fixunsxfei.zig deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | |
| 5 | ||
| 6 | comptime { | |
| 7 | symbol(&__fixunsxfei, "__fixunsxfei"); | |
| 8 | } | |
| 9 | ||
| 10 | pub fn __fixunsxfei(r: [*]u8, bits: usize, a: f80) callconv(.c) void { | |
| 11 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 12 | return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); | |
| 13 | } |
lib/compiler_rt/fixunsxfsi.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__fixunsxfsi, "__fixunsxfsi"); | |
| 7 | } | |
| 8 | ||
| 9 | fn __fixunsxfsi(a: f80) callconv(.c) u32 { | |
| 10 | return intFromFloat(u32, a); | |
| 11 | } |
lib/compiler_rt/fixunsxfti.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 3 | const symbol = compiler_rt.symbol; | |
| 4 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 5 | ||
| 6 | comptime { | |
| 7 | symbol(&__fixunsxfti, "__fixunsxfti"); | |
| 8 | } | |
| 9 | ||
| 10 | pub fn __fixunsxfti(a: f80) callconv(.c) u128 { | |
| 11 | return intFromFloat(u128, a); | |
| 12 | } |
lib/compiler_rt/fixxfdi.zig deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 2 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 3 | ||
| 4 | comptime { | |
| 5 | symbol(&__fixxfdi, "__fixxfdi"); | |
| 6 | } | |
| 7 | ||
| 8 | fn __fixxfdi(a: f80) callconv(.c) i64 { | |
| 9 | return intFromFloat(i64, a); | |
| 10 | } |
lib/compiler_rt/fixxfei.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; | |
| 6 | ||
| 7 | comptime { | |
| 8 | symbol(&__fixxfei, "__fixxfei"); | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __fixxfei(r: [*]u8, bits: usize, a: f80) callconv(.c) void { | |
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 13 | return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); | |
| 14 | } |
lib/compiler_rt/fixxfsi.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const intFromFloat = @import("./int_from_float.zig").intFromFloat; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__fixxfsi, "__fixxfsi"); | |
| 7 | } | |
| 8 | ||
| 9 | fn __fixxfsi(a: f80) callconv(.c) i32 { | |
| 10 | return intFromFloat(i32, a); | |
| 11 | } |
lib/compiler_rt/float_from_int.zig+472-4| ... | ... | @@ -1,7 +1,475 @@ |
| 1 | const builtin = @import("builtin"); | |
| 1 | 2 | const std = @import("std"); |
| 2 | 3 | const math = std.math; |
| 3 | 4 | |
| 4 | pub fn floatFromInt(comptime T: type, x: anytype) T { | |
| 5 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 6 | const symbol = compiler_rt.symbol; | |
| 7 | ||
| 8 | comptime { | |
| 9 | symbol(&__floatsihf, "__floatsihf"); | |
| 10 | symbol(&__floatdihf, "__floatdihf"); | |
| 11 | symbol(&__floattihf, "__floattihf"); | |
| 12 | symbol(&__floateihf, "__floateihf"); | |
| 13 | ||
| 14 | if (compiler_rt.want_aeabi) { | |
| 15 | symbol(&__aeabi_i2f, "__aeabi_i2f"); | |
| 16 | symbol(&__aeabi_l2f, "__aeabi_l2f"); | |
| 17 | } else { | |
| 18 | symbol(&__floatsisf, "__floatsisf"); | |
| 19 | symbol(&__floatdisf, "__floatdisf"); | |
| 20 | if (compiler_rt.want_windows_arm_abi) symbol(&__floatdisf, "__i64tos"); | |
| 21 | } | |
| 22 | symbol(&__floattisf, "__floattisf"); | |
| 23 | symbol(&__floateisf, "__floateisf"); | |
| 24 | ||
| 25 | if (compiler_rt.want_aeabi) { | |
| 26 | symbol(&__aeabi_i2d, "__aeabi_i2d"); | |
| 27 | symbol(&__aeabi_l2d, "__aeabi_l2d"); | |
| 28 | } else { | |
| 29 | symbol(&__floatsidf, "__floatsidf"); | |
| 30 | symbol(&__floatdidf, "__floatdidf"); | |
| 31 | if (compiler_rt.want_windows_arm_abi) symbol(&__floatdidf, "__i64tod"); | |
| 32 | } | |
| 33 | symbol(&__floattidf, "__floattidf"); | |
| 34 | symbol(&__floateidf, "__floateidf"); | |
| 35 | ||
| 36 | symbol(&__floatsixf, "__floatsixf"); | |
| 37 | symbol(&__floatdixf, "__floatdixf"); | |
| 38 | symbol(&__floattixf, "__floattixf"); | |
| 39 | symbol(&__floateixf, "__floateixf"); | |
| 40 | ||
| 41 | if (compiler_rt.want_ppc_abi) { | |
| 42 | symbol(&__floatsitf, "__floatsikf"); | |
| 43 | symbol(&__floatditf, "__floatdikf"); | |
| 44 | } else if (compiler_rt.want_sparc64_abi) { | |
| 45 | symbol(&_Qp_itoq, "_Qp_itoq"); | |
| 46 | symbol(&_Qp_xtoq, "_Qp_xtoq"); | |
| 47 | } else if (compiler_rt.want_sparc32_abi) { | |
| 48 | symbol(&__floatsitf, "_Q_itoq"); | |
| 49 | symbol(&__floatditf, "_Q_lltoq"); | |
| 50 | } else { | |
| 51 | symbol(&__floatsitf, "__floatsitf"); | |
| 52 | symbol(&__floatditf, "__floatditf"); | |
| 53 | } | |
| 54 | if (compiler_rt.want_ppc_abi) { | |
| 55 | symbol(&__floattitf, "__floattikf"); | |
| 56 | symbol(&__floateitf, "__floateikf"); | |
| 57 | } else { | |
| 58 | if (builtin.cpu.arch == .x86) { | |
| 59 | symbol(&__floattitf_x86, "__floattitf"); | |
| 60 | } else { | |
| 61 | symbol(&__floattitf, "__floattitf"); | |
| 62 | } | |
| 63 | symbol(&__floateitf, "__floateitf"); | |
| 64 | } | |
| 65 | } | |
| 66 | ||
| 67 | fn __floatsihf(a: i32) callconv(.c) compiler_rt.f16.Abi { | |
| 68 | return compiler_rt.f16.toAbi(f16_floatFromInt_i32(a)); | |
| 69 | } | |
| 70 | pub fn f16_floatFromInt_i32(a: i32) f16 { | |
| 71 | return floatFromInt(f16, a); | |
| 72 | } | |
| 73 | ||
| 74 | fn __floatdihf(a: i64) callconv(.c) compiler_rt.f16.Abi { | |
| 75 | return compiler_rt.f16.toAbi(f16_floatFromInt_i64(a)); | |
| 76 | } | |
| 77 | pub fn f16_floatFromInt_i64(a: i64) f16 { | |
| 78 | return floatFromInt(f16, a); | |
| 79 | } | |
| 80 | ||
| 81 | fn __floattihf(a: i128) callconv(.c) compiler_rt.f16.Abi { | |
| 82 | return compiler_rt.f16.toAbi(f16_floatFromInt_i128(a)); | |
| 83 | } | |
| 84 | pub fn f16_floatFromInt_i128(a: i128) f16 { | |
| 85 | return floatFromInt(f16, a); | |
| 86 | } | |
| 87 | ||
| 88 | fn __floateihf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f16.Abi { | |
| 89 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 90 | return compiler_rt.f16.toAbi(f16_floatFromInt_signed(a[0..byte_size])); | |
| 91 | } | |
| 92 | pub fn f16_floatFromInt_signed(a: []const u8) f16 { | |
| 93 | return floatFromBigInt(f16, .signed, @ptrCast(@alignCast(a))); | |
| 94 | } | |
| 95 | ||
| 96 | fn __floatsisf(a: i32) callconv(.c) compiler_rt.f32.Abi { | |
| 97 | return compiler_rt.f32.toAbi(f32_floatFromInt_i32(a)); | |
| 98 | } | |
| 99 | fn __aeabi_i2f(a: i32) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 100 | return f32_floatFromInt_i32(a); | |
| 101 | } | |
| 102 | pub fn f32_floatFromInt_i32(a: i32) f32 { | |
| 103 | return floatFromInt(f32, a); | |
| 104 | } | |
| 105 | ||
| 106 | fn __floatdisf(a: i64) callconv(.c) compiler_rt.f32.Abi { | |
| 107 | return compiler_rt.f32.toAbi(f32_floatFromInt_i64(a)); | |
| 108 | } | |
| 109 | fn __aeabi_l2f(a: i64) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 110 | return f32_floatFromInt_i64(a); | |
| 111 | } | |
| 112 | pub fn f32_floatFromInt_i64(a: i64) f32 { | |
| 113 | return floatFromInt(f32, a); | |
| 114 | } | |
| 115 | ||
| 116 | fn __floattisf(a: i128) callconv(.c) compiler_rt.f32.Abi { | |
| 117 | return compiler_rt.f32.toAbi(f32_floatFromInt_i128(a)); | |
| 118 | } | |
| 119 | pub fn f32_floatFromInt_i128(a: i128) f32 { | |
| 120 | return floatFromInt(f32, a); | |
| 121 | } | |
| 122 | ||
| 123 | fn __floateisf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f32.Abi { | |
| 124 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 125 | return compiler_rt.f32.toAbi(f32_floatFromInt_signed(a[0..byte_size])); | |
| 126 | } | |
| 127 | pub fn f32_floatFromInt_signed(a: []const u8) f32 { | |
| 128 | return floatFromBigInt(f32, .signed, @ptrCast(@alignCast(a))); | |
| 129 | } | |
| 130 | ||
| 131 | fn __floatsidf(a: i32) callconv(.c) compiler_rt.f64.Abi { | |
| 132 | return compiler_rt.f64.toAbi(f64_floatFromInt_i32(a)); | |
| 133 | } | |
| 134 | fn __aeabi_i2d(a: i32) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 135 | return f64_floatFromInt_i32(a); | |
| 136 | } | |
| 137 | pub fn f64_floatFromInt_i32(a: i32) f64 { | |
| 138 | return floatFromInt(f64, a); | |
| 139 | } | |
| 140 | ||
| 141 | fn __floatdidf(a: i64) callconv(.c) compiler_rt.f64.Abi { | |
| 142 | return compiler_rt.f64.toAbi(f64_floatFromInt_i64(a)); | |
| 143 | } | |
| 144 | fn __aeabi_l2d(a: i64) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 145 | return f64_floatFromInt_i64(a); | |
| 146 | } | |
| 147 | pub fn f64_floatFromInt_i64(a: i64) f64 { | |
| 148 | return floatFromInt(f64, a); | |
| 149 | } | |
| 150 | ||
| 151 | fn __floattidf(a: i128) callconv(.c) compiler_rt.f64.Abi { | |
| 152 | return compiler_rt.f64.toAbi(f64_floatFromInt_i128(a)); | |
| 153 | } | |
| 154 | pub fn f64_floatFromInt_i128(a: i128) f64 { | |
| 155 | return floatFromInt(f64, a); | |
| 156 | } | |
| 157 | ||
| 158 | fn __floateidf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f64.Abi { | |
| 159 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 160 | return compiler_rt.f64.toAbi(f64_floatFromInt_signed(a[0..byte_size])); | |
| 161 | } | |
| 162 | pub fn f64_floatFromInt_signed(a: []const u8) f64 { | |
| 163 | return floatFromBigInt(f64, .signed, @ptrCast(@alignCast(a))); | |
| 164 | } | |
| 165 | ||
| 166 | fn __floatsixf(a: i32) callconv(.c) compiler_rt.f80.Abi { | |
| 167 | return compiler_rt.f80.toAbi(f80_floatFromInt_i32(a)); | |
| 168 | } | |
| 169 | pub fn f80_floatFromInt_i32(a: i32) f80 { | |
| 170 | return floatFromInt(f80, a); | |
| 171 | } | |
| 172 | ||
| 173 | fn __floatdixf(a: i64) callconv(.c) compiler_rt.f80.Abi { | |
| 174 | return compiler_rt.f80.toAbi(f80_floatFromInt_i64(a)); | |
| 175 | } | |
| 176 | pub fn f80_floatFromInt_i64(a: i64) f80 { | |
| 177 | return floatFromInt(f80, a); | |
| 178 | } | |
| 179 | ||
| 180 | fn __floattixf(a: i128) callconv(.c) compiler_rt.f80.Abi { | |
| 181 | return compiler_rt.f80.toAbi(f80_floatFromInt_i128(a)); | |
| 182 | } | |
| 183 | pub fn f80_floatFromInt_i128(a: i128) f80 { | |
| 184 | return floatFromInt(f80, a); | |
| 185 | } | |
| 186 | ||
| 187 | fn __floateixf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f80.Abi { | |
| 188 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 189 | return compiler_rt.f80.toAbi(f80_floatFromInt_signed(a[0..byte_size])); | |
| 190 | } | |
| 191 | pub fn f80_floatFromInt_signed(a: []const u8) f80 { | |
| 192 | return floatFromBigInt(f80, .signed, @ptrCast(@alignCast(a))); | |
| 193 | } | |
| 194 | ||
| 195 | fn __floatsitf(a: i32) callconv(.c) compiler_rt.f128.Abi { | |
| 196 | return compiler_rt.f128.toAbi(f128_floatFromInt_i32(a)); | |
| 197 | } | |
| 198 | fn _Qp_itoq(c: *f128, a: i32) callconv(.c) void { | |
| 199 | c.* = f128_floatFromInt_i32(a); | |
| 200 | } | |
| 201 | pub fn f128_floatFromInt_i32(a: i32) f128 { | |
| 202 | return floatFromInt(f128, a); | |
| 203 | } | |
| 204 | ||
| 205 | fn __floatditf(a: i64) callconv(.c) compiler_rt.f128.Abi { | |
| 206 | return compiler_rt.f128.toAbi(f128_floatFromInt_i64(a)); | |
| 207 | } | |
| 208 | fn _Qp_xtoq(c: *f128, a: i64) callconv(.c) void { | |
| 209 | c.* = f128_floatFromInt_i64(a); | |
| 210 | } | |
| 211 | pub fn f128_floatFromInt_i64(a: i64) f128 { | |
| 212 | return floatFromInt(f128, a); | |
| 213 | } | |
| 214 | ||
| 215 | fn __floattitf(a: i128) callconv(.c) compiler_rt.f128.Abi { | |
| 216 | return compiler_rt.f128.toAbi(f128_floatFromInt_i128(a)); | |
| 217 | } | |
| 218 | fn __floattitf_x86(a: f128) callconv(.c) compiler_rt.f128.Abi { | |
| 219 | return compiler_rt.f128.toAbi(f128_floatFromInt_i128(@bitCast(a))); | |
| 220 | } | |
| 221 | pub fn f128_floatFromInt_i128(a: i128) f128 { | |
| 222 | return floatFromInt(f128, a); | |
| 223 | } | |
| 224 | ||
| 225 | fn __floateitf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f128.Abi { | |
| 226 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 227 | return compiler_rt.f128.toAbi(f128_floatFromInt_signed(a[0..byte_size])); | |
| 228 | } | |
| 229 | pub fn f128_floatFromInt_signed(a: []const u8) f128 { | |
| 230 | return floatFromBigInt(f128, .signed, @ptrCast(@alignCast(a))); | |
| 231 | } | |
| 232 | ||
| 233 | comptime { | |
| 234 | symbol(&__floatunsihf, "__floatunsihf"); | |
| 235 | symbol(&__floatundihf, "__floatundihf"); | |
| 236 | symbol(&__floatuntihf, "__floatuntihf"); | |
| 237 | symbol(&__floatuneihf, "__floatuneihf"); | |
| 238 | ||
| 239 | if (compiler_rt.want_aeabi) { | |
| 240 | symbol(&__aeabi_ui2f, "__aeabi_ui2f"); | |
| 241 | symbol(&__aeabi_ul2f, "__aeabi_ul2f"); | |
| 242 | } else { | |
| 243 | symbol(&__floatunsisf, "__floatunsisf"); | |
| 244 | symbol(&__floatundisf, "__floatundisf"); | |
| 245 | if (compiler_rt.want_windows_arm_abi) symbol(&__floatundisf, "__u64tos"); | |
| 246 | } | |
| 247 | symbol(&__floatuntisf, "__floatuntisf"); | |
| 248 | symbol(&__floatuneisf, "__floatuneisf"); | |
| 249 | ||
| 250 | if (compiler_rt.want_aeabi) { | |
| 251 | symbol(&__aeabi_ui2d, "__aeabi_ui2d"); | |
| 252 | } else { | |
| 253 | symbol(&__floatunsidf, "__floatunsidf"); | |
| 254 | } | |
| 255 | if (compiler_rt.want_aeabi) { | |
| 256 | symbol(&__aeabi_ul2d, "__aeabi_ul2d"); | |
| 257 | } else { | |
| 258 | if (compiler_rt.want_windows_arm_abi) { | |
| 259 | symbol(&__floatundidf, "__u64tod"); | |
| 260 | } | |
| 261 | symbol(&__floatundidf, "__floatundidf"); | |
| 262 | } | |
| 263 | symbol(&__floatuntidf, "__floatuntidf"); | |
| 264 | symbol(&__floatuneidf, "__floatuneidf"); | |
| 265 | ||
| 266 | symbol(&__floatunsixf, "__floatunsixf"); | |
| 267 | symbol(&__floatundixf, "__floatundixf"); | |
| 268 | symbol(&__floatuntixf, "__floatuntixf"); | |
| 269 | symbol(&__floatuneixf, "__floatuneixf"); | |
| 270 | ||
| 271 | if (compiler_rt.want_ppc_abi) { | |
| 272 | symbol(&__floatunsitf, "__floatunsikf"); | |
| 273 | symbol(&__floatunditf, "__floatundikf"); | |
| 274 | } else if (compiler_rt.want_sparc64_abi) { | |
| 275 | symbol(&_Qp_uitoq, "_Qp_uitoq"); | |
| 276 | symbol(&_Qp_uxtoq, "_Qp_uxtoq"); | |
| 277 | } else if (compiler_rt.want_sparc32_abi) { | |
| 278 | symbol(&__floatunsitf, "_Q_utoq"); | |
| 279 | symbol(&__floatunditf, "_Q_ulltoq"); | |
| 280 | } else { | |
| 281 | symbol(&__floatunsitf, "__floatunsitf"); | |
| 282 | symbol(&__floatunditf, "__floatunditf"); | |
| 283 | } | |
| 284 | if (compiler_rt.want_ppc_abi) { | |
| 285 | symbol(&__floatuntitf, "__floatuntikf"); | |
| 286 | symbol(&__floatuneitf, "__floatuneikf"); | |
| 287 | } else { | |
| 288 | if (builtin.cpu.arch == .x86) { | |
| 289 | symbol(&__floatuntitf_x86, "__floatuntitf"); | |
| 290 | } else if (builtin.cpu.arch == .x86_64 and | |
| 291 | (builtin.os.tag == .windows or builtin.os.tag == .uefi)) | |
| 292 | { | |
| 293 | symbol(&__floatuntitf_x86_64_windows, "__floatuntitf"); | |
| 294 | } else { | |
| 295 | symbol(&__floatuntitf, "__floatuntitf"); | |
| 296 | } | |
| 297 | symbol(&__floatuneitf, "__floatuneitf"); | |
| 298 | } | |
| 299 | } | |
| 300 | ||
| 301 | fn __floatunsihf(a: u32) callconv(.c) compiler_rt.f16.Abi { | |
| 302 | return compiler_rt.f16.toAbi(f16_floatFromInt_u32(a)); | |
| 303 | } | |
| 304 | pub fn f16_floatFromInt_u32(a: u32) f16 { | |
| 305 | return floatFromInt(f16, a); | |
| 306 | } | |
| 307 | ||
| 308 | fn __floatundihf(a: u64) callconv(.c) compiler_rt.f16.Abi { | |
| 309 | return compiler_rt.f16.toAbi(f16_floatFromInt_u64(a)); | |
| 310 | } | |
| 311 | pub fn f16_floatFromInt_u64(a: u64) f16 { | |
| 312 | return floatFromInt(f16, a); | |
| 313 | } | |
| 314 | ||
| 315 | fn __floatuntihf(a: u128) callconv(.c) compiler_rt.f16.Abi { | |
| 316 | return compiler_rt.f16.toAbi(f16_floatFromInt_u128(a)); | |
| 317 | } | |
| 318 | pub fn f16_floatFromInt_u128(a: u128) f16 { | |
| 319 | return floatFromInt(f16, a); | |
| 320 | } | |
| 321 | ||
| 322 | fn __floatuneihf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f16.Abi { | |
| 323 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 324 | return compiler_rt.f16.toAbi(f16_floatFromInt_unsigned(a[0..byte_size])); | |
| 325 | } | |
| 326 | pub fn f16_floatFromInt_unsigned(a: []const u8) f16 { | |
| 327 | return floatFromBigInt(f16, .unsigned, @ptrCast(@alignCast(a))); | |
| 328 | } | |
| 329 | ||
| 330 | fn __floatunsisf(a: u32) callconv(.c) compiler_rt.f32.Abi { | |
| 331 | return compiler_rt.f32.toAbi(f32_floatFromInt_u32(a)); | |
| 332 | } | |
| 333 | fn __aeabi_ui2f(a: u32) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 334 | return f32_floatFromInt_u32(a); | |
| 335 | } | |
| 336 | pub fn f32_floatFromInt_u32(a: u32) f32 { | |
| 337 | return floatFromInt(f32, a); | |
| 338 | } | |
| 339 | ||
| 340 | fn __floatundisf(a: u64) callconv(.c) compiler_rt.f32.Abi { | |
| 341 | return compiler_rt.f32.toAbi(f32_floatFromInt_u64(a)); | |
| 342 | } | |
| 343 | fn __aeabi_ul2f(a: u64) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 344 | return f32_floatFromInt_u64(a); | |
| 345 | } | |
| 346 | pub fn f32_floatFromInt_u64(a: u64) f32 { | |
| 347 | return floatFromInt(f32, a); | |
| 348 | } | |
| 349 | ||
| 350 | fn __floatuntisf(a: u128) callconv(.c) compiler_rt.f32.Abi { | |
| 351 | return compiler_rt.f32.toAbi(f32_floatFromInt_u128(a)); | |
| 352 | } | |
| 353 | pub fn f32_floatFromInt_u128(a: u128) f32 { | |
| 354 | return floatFromInt(f32, a); | |
| 355 | } | |
| 356 | ||
| 357 | fn __floatuneisf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f32.Abi { | |
| 358 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 359 | return compiler_rt.f32.toAbi(f32_floatFromInt_unsigned(a[0..byte_size])); | |
| 360 | } | |
| 361 | pub fn f32_floatFromInt_unsigned(a: []const u8) f32 { | |
| 362 | return floatFromBigInt(f32, .unsigned, @ptrCast(@alignCast(a))); | |
| 363 | } | |
| 364 | ||
| 365 | fn __floatunsidf(a: u32) callconv(.c) compiler_rt.f64.Abi { | |
| 366 | return compiler_rt.f64.toAbi(f64_floatFromInt_u32(a)); | |
| 367 | } | |
| 368 | fn __aeabi_ui2d(a: u32) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 369 | return f64_floatFromInt_u32(a); | |
| 370 | } | |
| 371 | pub fn f64_floatFromInt_u32(a: u32) f64 { | |
| 372 | return floatFromInt(f64, a); | |
| 373 | } | |
| 374 | ||
| 375 | fn __floatundidf(a: u64) callconv(.c) compiler_rt.f64.Abi { | |
| 376 | return compiler_rt.f64.toAbi(f64_floatFromInt_u64(a)); | |
| 377 | } | |
| 378 | fn __aeabi_ul2d(a: u64) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 379 | return f64_floatFromInt_u64(a); | |
| 380 | } | |
| 381 | pub fn f64_floatFromInt_u64(a: u64) f64 { | |
| 382 | return floatFromInt(f64, a); | |
| 383 | } | |
| 384 | ||
| 385 | fn __floatuntidf(a: u128) callconv(.c) compiler_rt.f64.Abi { | |
| 386 | return compiler_rt.f64.toAbi(f64_floatFromInt_u128(a)); | |
| 387 | } | |
| 388 | pub fn f64_floatFromInt_u128(a: u128) f64 { | |
| 389 | return floatFromInt(f64, a); | |
| 390 | } | |
| 391 | ||
| 392 | fn __floatuneidf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f64.Abi { | |
| 393 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 394 | return compiler_rt.f64.toAbi(f64_floatFromInt_unsigned(a[0..byte_size])); | |
| 395 | } | |
| 396 | pub fn f64_floatFromInt_unsigned(a: []const u8) f64 { | |
| 397 | return floatFromBigInt(f64, .unsigned, @ptrCast(@alignCast(a))); | |
| 398 | } | |
| 399 | ||
| 400 | fn __floatunsixf(a: u32) callconv(.c) compiler_rt.f80.Abi { | |
| 401 | return compiler_rt.f80.toAbi(f80_floatFromInt_u32(a)); | |
| 402 | } | |
| 403 | pub fn f80_floatFromInt_u32(a: u32) f80 { | |
| 404 | return floatFromInt(f80, a); | |
| 405 | } | |
| 406 | ||
| 407 | fn __floatundixf(a: u64) callconv(.c) compiler_rt.f80.Abi { | |
| 408 | return compiler_rt.f80.toAbi(f80_floatFromInt_u64(a)); | |
| 409 | } | |
| 410 | pub fn f80_floatFromInt_u64(a: u64) f80 { | |
| 411 | return floatFromInt(f80, a); | |
| 412 | } | |
| 413 | ||
| 414 | fn __floatuntixf(a: u128) callconv(.c) compiler_rt.f80.Abi { | |
| 415 | return compiler_rt.f80.toAbi(f80_floatFromInt_u128(a)); | |
| 416 | } | |
| 417 | pub fn f80_floatFromInt_u128(a: u128) f80 { | |
| 418 | return floatFromInt(f80, a); | |
| 419 | } | |
| 420 | ||
| 421 | fn __floatuneixf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f80.Abi { | |
| 422 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 423 | return compiler_rt.f80.toAbi(f80_floatFromInt_unsigned(a[0..byte_size])); | |
| 424 | } | |
| 425 | pub fn f80_floatFromInt_unsigned(a: []const u8) f80 { | |
| 426 | return floatFromBigInt(f80, .unsigned, @ptrCast(@alignCast(a))); | |
| 427 | } | |
| 428 | ||
| 429 | fn __floatunsitf(a: u32) callconv(.c) compiler_rt.f128.Abi { | |
| 430 | return compiler_rt.f128.toAbi(f128_floatFromInt_u32(a)); | |
| 431 | } | |
| 432 | fn _Qp_uitoq(c: *f128, a: u32) callconv(.c) void { | |
| 433 | c.* = f128_floatFromInt_u32(a); | |
| 434 | } | |
| 435 | pub fn f128_floatFromInt_u32(a: u32) f128 { | |
| 436 | return floatFromInt(f128, a); | |
| 437 | } | |
| 438 | ||
| 439 | fn __floatunditf(a: u64) callconv(.c) compiler_rt.f128.Abi { | |
| 440 | return compiler_rt.f128.toAbi(f128_floatFromInt_u64(a)); | |
| 441 | } | |
| 442 | fn _Qp_uxtoq(c: *f128, a: u64) callconv(.c) void { | |
| 443 | c.* = f128_floatFromInt_u64(a); | |
| 444 | } | |
| 445 | pub fn f128_floatFromInt_u64(a: u64) f128 { | |
| 446 | return floatFromInt(f128, a); | |
| 447 | } | |
| 448 | ||
| 449 | fn __floatuntitf(a: u128) callconv(.c) compiler_rt.f128.Abi { | |
| 450 | return compiler_rt.f128.toAbi(f128_floatFromInt_u128(a)); | |
| 451 | } | |
| 452 | fn __floatuntitf_x86(a: f128) callconv(.c) compiler_rt.f128.Abi { | |
| 453 | return compiler_rt.f128.toAbi(f128_floatFromInt_u128(@bitCast(a))); | |
| 454 | } | |
| 455 | fn __floatuntitf_x86_64_windows(a_lo: u64, a_hi: u64) callconv(.c) compiler_rt.f128.Abi { | |
| 456 | return compiler_rt.f128.toAbi(f128_floatFromInt_u128(@bitCast( | |
| 457 | packed struct { lo: u64, hi: u64 }{ .lo = a_lo, .hi = a_hi }, | |
| 458 | ))); | |
| 459 | } | |
| 460 | pub fn f128_floatFromInt_u128(a: u128) f128 { | |
| 461 | return floatFromInt(f128, a); | |
| 462 | } | |
| 463 | ||
| 464 | fn __floatuneitf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f128.Abi { | |
| 465 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 466 | return compiler_rt.f128.toAbi(f128_floatFromInt_unsigned(a[0..byte_size])); | |
| 467 | } | |
| 468 | pub fn f128_floatFromInt_unsigned(a: []const u8) f128 { | |
| 469 | return floatFromBigInt(f128, .unsigned, @ptrCast(@alignCast(a))); | |
| 470 | } | |
| 471 | ||
| 472 | inline fn floatFromInt(comptime T: type, x: anytype) T { | |
| 5 | 473 | if (x == 0) return 0; |
| 6 | 474 | |
| 7 | 475 | // Various constants whose values follow from the type parameters. |
| ... | ... | @@ -53,7 +521,7 @@ pub fn floatFromInt(comptime T: type, x: anytype) T { |
| 53 | 521 | return @bitCast(sign_bit | result); |
| 54 | 522 | } |
| 55 | 523 | |
| 56 | const endian = @import("builtin").cpu.arch.endian(); | |
| 524 | const endian = builtin.cpu.arch.endian(); | |
| 57 | 525 | inline fn limb(limbs: []const u32, index: usize) u32 { |
| 58 | 526 | return switch (endian) { |
| 59 | 527 | .little => limbs[index], |
| ... | ... | @@ -61,11 +529,11 @@ inline fn limb(limbs: []const u32, index: usize) u32 { |
| 61 | 529 | }; |
| 62 | 530 | } |
| 63 | 531 | |
| 64 | pub inline fn floatFromBigInt(comptime T: type, comptime signedness: std.builtin.Signedness, x: []const u32) T { | |
| 532 | inline fn floatFromBigInt(comptime T: type, comptime signedness: std.lang.Signedness, x: []const u32) T { | |
| 65 | 533 | switch (x.len) { |
| 66 | 534 | 0 => return 0, |
| 67 | 535 | inline 1...4 => |limbs_len| { |
| 68 | const low_to_high: [limbs_len]u32 = switch (@import("builtin").cpu.arch.endian()) { | |
| 536 | const low_to_high: [limbs_len]u32 = switch (endian) { | |
| 69 | 537 | .little => x[0..limbs_len].*, |
| 70 | 538 | .big => switch (limbs_len) { |
| 71 | 539 | 1 => .{x[0]}, |
lib/compiler_rt/float_from_int_test.zig+757-733| ... | ... | @@ -2,571 +2,593 @@ const std = @import("std"); |
| 2 | 2 | const testing = std.testing; |
| 3 | 3 | const math = std.math; |
| 4 | 4 | |
| 5 | const __floatunsihf = @import("floatunsihf.zig").__floatunsihf; | |
| 6 | ||
| 7 | // Conversion to f32 | |
| 8 | const __floatsisf = @import("floatsisf.zig").__floatsisf; | |
| 9 | const __floatunsisf = @import("floatunsisf.zig").__floatunsisf; | |
| 10 | const __floatdisf = @import("floatdisf.zig").__floatdisf; | |
| 11 | const __floatundisf = @import("floatundisf.zig").__floatundisf; | |
| 12 | const __floattisf = @import("floattisf.zig").__floattisf; | |
| 13 | const __floatuntisf = @import("floatuntisf.zig").__floatuntisf; | |
| 14 | const __floateisf = @import("floateisf.zig").__floateisf; | |
| 15 | const __floatuneisf = @import("floatuneisf.zig").__floatuneisf; | |
| 16 | ||
| 17 | // Conversion to f64 | |
| 18 | const __floatsidf = @import("floatsidf.zig").__floatsidf; | |
| 19 | const __floatunsidf = @import("floatunsidf.zig").__floatunsidf; | |
| 20 | const __floatdidf = @import("floatdidf.zig").__floatdidf; | |
| 21 | const __floatundidf = @import("floatundidf.zig").__floatundidf; | |
| 22 | const __floattidf = @import("floattidf.zig").__floattidf; | |
| 23 | const __floatuntidf = @import("floatuntidf.zig").__floatuntidf; | |
| 24 | ||
| 25 | // Conversion to f128 | |
| 26 | const __floatsitf = @import("floatsitf.zig").__floatsitf; | |
| 27 | const __floatunsitf = @import("floatunsitf.zig").__floatunsitf; | |
| 28 | const __floatditf = @import("floatditf.zig").__floatditf; | |
| 29 | const __floatunditf = @import("floatunditf.zig").__floatunditf; | |
| 30 | const __floattitf = @import("floattitf.zig").__floattitf; | |
| 31 | const __floatuntitf = @import("floatuntitf.zig").__floatuntitf; | |
| 32 | ||
| 33 | fn test__floatsisf(a: i32, expected: u32) !void { | |
| 34 | const r = __floatsisf(a); | |
| 5 | const impl = @import("float_from_int.zig"); | |
| 6 | ||
| 7 | const f16_floatFromInt_i32 = impl.f16_floatFromInt_i32; | |
| 8 | const f16_floatFromInt_u32 = impl.f16_floatFromInt_u32; | |
| 9 | const f16_floatFromInt_i64 = impl.f16_floatFromInt_i64; | |
| 10 | const f16_floatFromInt_u64 = impl.f16_floatFromInt_u64; | |
| 11 | const f16_floatFromInt_i128 = impl.f16_floatFromInt_i128; | |
| 12 | const f16_floatFromInt_u128 = impl.f16_floatFromInt_u128; | |
| 13 | const f16_floatFromInt_signed = impl.f16_floatFromInt_signed; | |
| 14 | const f16_floatFromInt_unsigned = impl.f16_floatFromInt_unsigned; | |
| 15 | ||
| 16 | const f32_floatFromInt_i32 = impl.f32_floatFromInt_i32; | |
| 17 | const f32_floatFromInt_u32 = impl.f32_floatFromInt_u32; | |
| 18 | const f32_floatFromInt_i64 = impl.f32_floatFromInt_i64; | |
| 19 | const f32_floatFromInt_u64 = impl.f32_floatFromInt_u64; | |
| 20 | const f32_floatFromInt_i128 = impl.f32_floatFromInt_i128; | |
| 21 | const f32_floatFromInt_u128 = impl.f32_floatFromInt_u128; | |
| 22 | const f32_floatFromInt_signed = impl.f32_floatFromInt_signed; | |
| 23 | const f32_floatFromInt_unsigned = impl.f32_floatFromInt_unsigned; | |
| 24 | ||
| 25 | const f64_floatFromInt_i32 = impl.f64_floatFromInt_i32; | |
| 26 | const f64_floatFromInt_u32 = impl.f64_floatFromInt_u32; | |
| 27 | const f64_floatFromInt_i64 = impl.f64_floatFromInt_i64; | |
| 28 | const f64_floatFromInt_u64 = impl.f64_floatFromInt_u64; | |
| 29 | const f64_floatFromInt_i128 = impl.f64_floatFromInt_i128; | |
| 30 | const f64_floatFromInt_u128 = impl.f64_floatFromInt_u128; | |
| 31 | const f64_floatFromInt_signed = impl.f64_floatFromInt_signed; | |
| 32 | const f64_floatFromInt_unsigned = impl.f64_floatFromInt_unsigned; | |
| 33 | ||
| 34 | const f80_floatFromInt_i32 = impl.f80_floatFromInt_i32; | |
| 35 | const f80_floatFromInt_u32 = impl.f80_floatFromInt_u32; | |
| 36 | const f80_floatFromInt_i64 = impl.f80_floatFromInt_i64; | |
| 37 | const f80_floatFromInt_u64 = impl.f80_floatFromInt_u64; | |
| 38 | const f80_floatFromInt_i128 = impl.f80_floatFromInt_i128; | |
| 39 | const f80_floatFromInt_u128 = impl.f80_floatFromInt_u128; | |
| 40 | const f80_floatFromInt_signed = impl.f80_floatFromInt_signed; | |
| 41 | const f80_floatFromInt_unsigned = impl.f80_floatFromInt_unsigned; | |
| 42 | ||
| 43 | const f128_floatFromInt_i32 = impl.f128_floatFromInt_i32; | |
| 44 | const f128_floatFromInt_u32 = impl.f128_floatFromInt_u32; | |
| 45 | const f128_floatFromInt_i64 = impl.f128_floatFromInt_i64; | |
| 46 | const f128_floatFromInt_u64 = impl.f128_floatFromInt_u64; | |
| 47 | const f128_floatFromInt_i128 = impl.f128_floatFromInt_i128; | |
| 48 | const f128_floatFromInt_u128 = impl.f128_floatFromInt_u128; | |
| 49 | const f128_floatFromInt_signed = impl.f128_floatFromInt_signed; | |
| 50 | const f128_floatFromInt_unsigned = impl.f128_floatFromInt_unsigned; | |
| 51 | ||
| 52 | fn test_f32_floatFromInt_i32(a: i32, expected: u32) !void { | |
| 53 | const r = f32_floatFromInt_i32(a); | |
| 35 | 54 | try std.testing.expect(@as(u32, @bitCast(r)) == expected); |
| 36 | 55 | } |
| 37 | 56 | |
| 38 | fn test_one_floatunsisf(a: u32, expected: u32) !void { | |
| 39 | const r = __floatunsisf(a); | |
| 57 | fn test_f32_floatFromInt_u32(a: u32, expected: u32) !void { | |
| 58 | const r = f32_floatFromInt_u32(a); | |
| 40 | 59 | try std.testing.expect(@as(u32, @bitCast(r)) == expected); |
| 41 | 60 | } |
| 42 | 61 | |
| 43 | test "floatsisf" { | |
| 44 | try test__floatsisf(0, 0x00000000); | |
| 45 | try test__floatsisf(1, 0x3f800000); | |
| 46 | try test__floatsisf(-1, 0xbf800000); | |
| 47 | try test__floatsisf(0x7FFFFFFF, 0x4f000000); | |
| 48 | try test__floatsisf(@bitCast(@as(u32, @intCast(0x80000000))), 0xcf000000); | |
| 62 | test f32_floatFromInt_i32 { | |
| 63 | try test_f32_floatFromInt_i32(0, 0x00000000); | |
| 64 | try test_f32_floatFromInt_i32(1, 0x3f800000); | |
| 65 | try test_f32_floatFromInt_i32(-1, 0xbf800000); | |
| 66 | try test_f32_floatFromInt_i32(0x7FFFFFFF, 0x4f000000); | |
| 67 | try test_f32_floatFromInt_i32(@bitCast(@as(u32, @intCast(0x80000000))), 0xcf000000); | |
| 68 | ||
| 69 | try testing.expect(f32_floatFromInt_i32(math.minInt(i32)) == math.minInt(i32)); | |
| 49 | 70 | } |
| 50 | 71 | |
| 51 | test "floatunsisf" { | |
| 72 | test f32_floatFromInt_u32 { | |
| 52 | 73 | // Test the produced bit pattern |
| 53 | try test_one_floatunsisf(0, 0); | |
| 54 | try test_one_floatunsisf(1, 0x3f800000); | |
| 55 | try test_one_floatunsisf(0x7FFFFFFF, 0x4f000000); | |
| 56 | try test_one_floatunsisf(0x80000000, 0x4f000000); | |
| 57 | try test_one_floatunsisf(0xFFFFFFFF, 0x4f800000); | |
| 74 | try test_f32_floatFromInt_u32(0, 0); | |
| 75 | try test_f32_floatFromInt_u32(1, 0x3f800000); | |
| 76 | try test_f32_floatFromInt_u32(0x7FFFFFFF, 0x4f000000); | |
| 77 | try test_f32_floatFromInt_u32(0x80000000, 0x4f000000); | |
| 78 | try test_f32_floatFromInt_u32(0xFFFFFFFF, 0x4f800000); | |
| 79 | ||
| 80 | try testing.expect(f32_floatFromInt_u32(0) == 0.0); | |
| 81 | try testing.expect(f32_floatFromInt_u32(math.maxInt(u24)) == math.maxInt(u24)); | |
| 82 | try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 1) == math.maxInt(u24) + 1); // 0x100_0000 - Exact | |
| 83 | try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 2) == math.maxInt(u24) + 1); // 0x100_0001 - Tie: Rounds down to even | |
| 84 | try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 3) == math.maxInt(u24) + 3); // 0x100_0002 - Exact | |
| 85 | try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 4) == math.maxInt(u24) + 5); // 0x100_0003 - Tie: Rounds up to even | |
| 86 | try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 5) == math.maxInt(u24) + 5); // 0x100_0004 - Exact | |
| 87 | try testing.expect(f32_floatFromInt_u32(math.maxInt(u32)) == math.maxInt(u32) + 1); | |
| 88 | } | |
| 89 | ||
| 90 | fn test_f32_floatFromInt_i64(a: i64, expected: f32) !void { | |
| 91 | const x = f32_floatFromInt_i64(a); | |
| 92 | try testing.expect(x == expected); | |
| 58 | 93 | } |
| 59 | 94 | |
| 60 | fn test__floatdisf(a: i64, expected: f32) !void { | |
| 61 | const x = __floatdisf(a); | |
| 95 | fn test_f32_floatFromInt_u64(a: u64, expected: f32) !void { | |
| 96 | const x = f32_floatFromInt_u64(a); | |
| 62 | 97 | try testing.expect(x == expected); |
| 63 | 98 | } |
| 64 | 99 | |
| 65 | fn test__floatundisf(a: u64, expected: f32) !void { | |
| 66 | try std.testing.expectEqual(expected, __floatundisf(a)); | |
| 67 | } | |
| 68 | ||
| 69 | test "floatdisf" { | |
| 70 | try test__floatdisf(0, 0.0); | |
| 71 | try test__floatdisf(1, 1.0); | |
| 72 | try test__floatdisf(2, 2.0); | |
| 73 | try test__floatdisf(-1, -1.0); | |
| 74 | try test__floatdisf(-2, -2.0); | |
| 75 | try test__floatdisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 76 | try test__floatdisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 77 | try test__floatdisf(@bitCast(@as(u64, 0x8000008000000000)), -0x1.FFFFFEp+62); | |
| 78 | try test__floatdisf(@bitCast(@as(u64, 0x8000010000000000)), -0x1.FFFFFCp+62); | |
| 79 | try test__floatdisf(@bitCast(@as(u64, 0x8000000000000000)), -0x1.000000p+63); | |
| 80 | try test__floatdisf(@bitCast(@as(u64, 0x8000000000000001)), -0x1.000000p+63); | |
| 81 | try test__floatdisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 82 | try test__floatdisf(0x0007FB72EA000000, 0x1.FEDCBAp+50); | |
| 83 | try test__floatdisf(0x0007FB72EB000000, 0x1.FEDCBAp+50); | |
| 84 | try test__floatdisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); | |
| 85 | try test__floatdisf(0x0007FB72EC000000, 0x1.FEDCBCp+50); | |
| 86 | try test__floatdisf(0x0007FB72E8000001, 0x1.FEDCBAp+50); | |
| 87 | try test__floatdisf(0x0007FB72E6000000, 0x1.FEDCBAp+50); | |
| 88 | try test__floatdisf(0x0007FB72E7000000, 0x1.FEDCBAp+50); | |
| 89 | try test__floatdisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); | |
| 90 | try test__floatdisf(0x0007FB72E4000001, 0x1.FEDCBAp+50); | |
| 91 | try test__floatdisf(0x0007FB72E4000000, 0x1.FEDCB8p+50); | |
| 92 | } | |
| 93 | ||
| 94 | test "floatundisf" { | |
| 95 | try test__floatundisf(0, 0.0); | |
| 96 | try test__floatundisf(1, 1.0); | |
| 97 | try test__floatundisf(2, 2.0); | |
| 98 | try test__floatundisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 99 | try test__floatundisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 100 | try test__floatundisf(0x8000008000000000, 0x1p+63); | |
| 101 | try test__floatundisf(0x8000010000000000, 0x1.000002p+63); | |
| 102 | try test__floatundisf(0x8000000000000000, 0x1p+63); | |
| 103 | try test__floatundisf(0x8000000000000001, 0x1p+63); | |
| 104 | try test__floatundisf(0xFFFFFFFFFFFFFFFE, 0x1p+64); | |
| 105 | try test__floatundisf(0xFFFFFFFFFFFFFFFF, 0x1p+64); | |
| 106 | try test__floatundisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 107 | try test__floatundisf(0x0007FB72EA000000, 0x1.FEDCBAp+50); | |
| 108 | try test__floatundisf(0x0007FB72EB000000, 0x1.FEDCBAp+50); | |
| 109 | try test__floatundisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); | |
| 110 | try test__floatundisf(0x0007FB72EC000000, 0x1.FEDCBCp+50); | |
| 111 | try test__floatundisf(0x0007FB72E8000001, 0x1.FEDCBAp+50); | |
| 112 | try test__floatundisf(0x0007FB72E6000000, 0x1.FEDCBAp+50); | |
| 113 | try test__floatundisf(0x0007FB72E7000000, 0x1.FEDCBAp+50); | |
| 114 | try test__floatundisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); | |
| 115 | try test__floatundisf(0x0007FB72E4000001, 0x1.FEDCBAp+50); | |
| 116 | try test__floatundisf(0x0007FB72E4000000, 0x1.FEDCB8p+50); | |
| 117 | } | |
| 118 | ||
| 119 | fn test__floattisf(a: i128, expected: f32) !void { | |
| 120 | const x = __floattisf(a); | |
| 100 | test f32_floatFromInt_i64 { | |
| 101 | try test_f32_floatFromInt_i64(0, 0.0); | |
| 102 | try test_f32_floatFromInt_i64(1, 1.0); | |
| 103 | try test_f32_floatFromInt_i64(2, 2.0); | |
| 104 | try test_f32_floatFromInt_i64(-1, -1.0); | |
| 105 | try test_f32_floatFromInt_i64(-2, -2.0); | |
| 106 | try test_f32_floatFromInt_i64(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 107 | try test_f32_floatFromInt_i64(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 108 | try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000008000000000)), -0x1.FFFFFEp+62); | |
| 109 | try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000010000000000)), -0x1.FFFFFCp+62); | |
| 110 | try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000000)), -0x1.000000p+63); | |
| 111 | try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000001)), -0x1.000000p+63); | |
| 112 | try test_f32_floatFromInt_i64(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 113 | try test_f32_floatFromInt_i64(0x0007FB72EA000000, 0x1.FEDCBAp+50); | |
| 114 | try test_f32_floatFromInt_i64(0x0007FB72EB000000, 0x1.FEDCBAp+50); | |
| 115 | try test_f32_floatFromInt_i64(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); | |
| 116 | try test_f32_floatFromInt_i64(0x0007FB72EC000000, 0x1.FEDCBCp+50); | |
| 117 | try test_f32_floatFromInt_i64(0x0007FB72E8000001, 0x1.FEDCBAp+50); | |
| 118 | try test_f32_floatFromInt_i64(0x0007FB72E6000000, 0x1.FEDCBAp+50); | |
| 119 | try test_f32_floatFromInt_i64(0x0007FB72E7000000, 0x1.FEDCBAp+50); | |
| 120 | try test_f32_floatFromInt_i64(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); | |
| 121 | try test_f32_floatFromInt_i64(0x0007FB72E4000001, 0x1.FEDCBAp+50); | |
| 122 | try test_f32_floatFromInt_i64(0x0007FB72E4000000, 0x1.FEDCB8p+50); | |
| 123 | } | |
| 124 | ||
| 125 | test f32_floatFromInt_u64 { | |
| 126 | try test_f32_floatFromInt_u64(0, 0.0); | |
| 127 | try test_f32_floatFromInt_u64(1, 1.0); | |
| 128 | try test_f32_floatFromInt_u64(2, 2.0); | |
| 129 | try test_f32_floatFromInt_u64(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 130 | try test_f32_floatFromInt_u64(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 131 | try test_f32_floatFromInt_u64(0x8000008000000000, 0x1p+63); | |
| 132 | try test_f32_floatFromInt_u64(0x8000010000000000, 0x1.000002p+63); | |
| 133 | try test_f32_floatFromInt_u64(0x8000000000000000, 0x1p+63); | |
| 134 | try test_f32_floatFromInt_u64(0x8000000000000001, 0x1p+63); | |
| 135 | try test_f32_floatFromInt_u64(0xFFFFFFFFFFFFFFFE, 0x1p+64); | |
| 136 | try test_f32_floatFromInt_u64(0xFFFFFFFFFFFFFFFF, 0x1p+64); | |
| 137 | try test_f32_floatFromInt_u64(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 138 | try test_f32_floatFromInt_u64(0x0007FB72EA000000, 0x1.FEDCBAp+50); | |
| 139 | try test_f32_floatFromInt_u64(0x0007FB72EB000000, 0x1.FEDCBAp+50); | |
| 140 | try test_f32_floatFromInt_u64(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); | |
| 141 | try test_f32_floatFromInt_u64(0x0007FB72EC000000, 0x1.FEDCBCp+50); | |
| 142 | try test_f32_floatFromInt_u64(0x0007FB72E8000001, 0x1.FEDCBAp+50); | |
| 143 | try test_f32_floatFromInt_u64(0x0007FB72E6000000, 0x1.FEDCBAp+50); | |
| 144 | try test_f32_floatFromInt_u64(0x0007FB72E7000000, 0x1.FEDCBAp+50); | |
| 145 | try test_f32_floatFromInt_u64(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); | |
| 146 | try test_f32_floatFromInt_u64(0x0007FB72E4000001, 0x1.FEDCBAp+50); | |
| 147 | try test_f32_floatFromInt_u64(0x0007FB72E4000000, 0x1.FEDCB8p+50); | |
| 148 | } | |
| 149 | ||
| 150 | fn test_f32_floatFromInt_i128(a: i128, expected: f32) !void { | |
| 151 | const x = f32_floatFromInt_i128(a); | |
| 121 | 152 | try testing.expect(x == expected); |
| 122 | 153 | } |
| 123 | 154 | |
| 124 | fn test__floatuntisf(a: u128, expected: f32) !void { | |
| 125 | const x = __floatuntisf(a); | |
| 155 | fn test_f32_floatFromInt_u128(a: u128, expected: f32) !void { | |
| 156 | const x = f32_floatFromInt_u128(a); | |
| 126 | 157 | try testing.expect(x == expected); |
| 127 | 158 | } |
| 128 | 159 | |
| 129 | test "floattisf" { | |
| 130 | try test__floattisf(0, 0.0); | |
| 160 | test f32_floatFromInt_i128 { | |
| 161 | try test_f32_floatFromInt_i128(0, 0.0); | |
| 131 | 162 | |
| 132 | try test__floattisf(1, 1.0); | |
| 133 | try test__floattisf(2, 2.0); | |
| 134 | try test__floattisf(-1, -1.0); | |
| 135 | try test__floattisf(-2, -2.0); | |
| 163 | try test_f32_floatFromInt_i128(1, 1.0); | |
| 164 | try test_f32_floatFromInt_i128(2, 2.0); | |
| 165 | try test_f32_floatFromInt_i128(-1, -1.0); | |
| 166 | try test_f32_floatFromInt_i128(-2, -2.0); | |
| 136 | 167 | |
| 137 | try test__floattisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 138 | try test__floattisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 168 | try test_f32_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 169 | try test_f32_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 139 | 170 | |
| 140 | try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000008000000000), -0x1.FFFFFEp+62); | |
| 141 | try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000010000000000), -0x1.FFFFFCp+62); | |
| 171 | try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000008000000000), -0x1.FFFFFEp+62); | |
| 172 | try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000010000000000), -0x1.FFFFFCp+62); | |
| 142 | 173 | |
| 143 | try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000000), -0x1.000000p+63); | |
| 144 | try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000001), -0x1.000000p+63); | |
| 174 | try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000000), -0x1.000000p+63); | |
| 175 | try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000001), -0x1.000000p+63); | |
| 145 | 176 | |
| 146 | try test__floattisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 177 | try test_f32_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 147 | 178 | |
| 148 | try test__floattisf(0x0007FB72EA000000, 0x1.FEDCBAp+50); | |
| 149 | try test__floattisf(0x0007FB72EB000000, 0x1.FEDCBAp+50); | |
| 150 | try test__floattisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); | |
| 151 | try test__floattisf(0x0007FB72EC000000, 0x1.FEDCBCp+50); | |
| 152 | try test__floattisf(0x0007FB72E8000001, 0x1.FEDCBAp+50); | |
| 179 | try test_f32_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBAp+50); | |
| 180 | try test_f32_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBAp+50); | |
| 181 | try test_f32_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); | |
| 182 | try test_f32_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBCp+50); | |
| 183 | try test_f32_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBAp+50); | |
| 153 | 184 | |
| 154 | try test__floattisf(0x0007FB72E6000000, 0x1.FEDCBAp+50); | |
| 155 | try test__floattisf(0x0007FB72E7000000, 0x1.FEDCBAp+50); | |
| 156 | try test__floattisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); | |
| 157 | try test__floattisf(0x0007FB72E4000001, 0x1.FEDCBAp+50); | |
| 158 | try test__floattisf(0x0007FB72E4000000, 0x1.FEDCB8p+50); | |
| 185 | try test_f32_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCBAp+50); | |
| 186 | try test_f32_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCBAp+50); | |
| 187 | try test_f32_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); | |
| 188 | try test_f32_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCBAp+50); | |
| 189 | try test_f32_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB8p+50); | |
| 159 | 190 | |
| 160 | try test__floattisf(make_ti(0x0007FB72E8000000, 0), 0x1.FEDCBAp+114); | |
| 191 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72E8000000, 0), 0x1.FEDCBAp+114); | |
| 161 | 192 | |
| 162 | try test__floattisf(make_ti(0x0007FB72EA000000, 0), 0x1.FEDCBAp+114); | |
| 163 | try test__floattisf(make_ti(0x0007FB72EB000000, 0), 0x1.FEDCBAp+114); | |
| 164 | try test__floattisf(make_ti(0x0007FB72EBFFFFFF, 0), 0x1.FEDCBAp+114); | |
| 165 | try test__floattisf(make_ti(0x0007FB72EC000000, 0), 0x1.FEDCBCp+114); | |
| 166 | try test__floattisf(make_ti(0x0007FB72E8000001, 0), 0x1.FEDCBAp+114); | |
| 193 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72EA000000, 0), 0x1.FEDCBAp+114); | |
| 194 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72EB000000, 0), 0x1.FEDCBAp+114); | |
| 195 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72EBFFFFFF, 0), 0x1.FEDCBAp+114); | |
| 196 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72EC000000, 0), 0x1.FEDCBCp+114); | |
| 197 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72E8000001, 0), 0x1.FEDCBAp+114); | |
| 167 | 198 | |
| 168 | try test__floattisf(make_ti(0x0007FB72E6000000, 0), 0x1.FEDCBAp+114); | |
| 169 | try test__floattisf(make_ti(0x0007FB72E7000000, 0), 0x1.FEDCBAp+114); | |
| 170 | try test__floattisf(make_ti(0x0007FB72E7FFFFFF, 0), 0x1.FEDCBAp+114); | |
| 171 | try test__floattisf(make_ti(0x0007FB72E4000001, 0), 0x1.FEDCBAp+114); | |
| 172 | try test__floattisf(make_ti(0x0007FB72E4000000, 0), 0x1.FEDCB8p+114); | |
| 199 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72E6000000, 0), 0x1.FEDCBAp+114); | |
| 200 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72E7000000, 0), 0x1.FEDCBAp+114); | |
| 201 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72E7FFFFFF, 0), 0x1.FEDCBAp+114); | |
| 202 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72E4000001, 0), 0x1.FEDCBAp+114); | |
| 203 | try test_f32_floatFromInt_i128(make_ti(0x0007FB72E4000000, 0), 0x1.FEDCB8p+114); | |
| 173 | 204 | } |
| 174 | 205 | |
| 175 | test "floatuntisf" { | |
| 176 | try test__floatuntisf(0, 0.0); | |
| 206 | test f32_floatFromInt_u128 { | |
| 207 | try test_f32_floatFromInt_u128(0, 0.0); | |
| 177 | 208 | |
| 178 | try test__floatuntisf(1, 1.0); | |
| 179 | try test__floatuntisf(2, 2.0); | |
| 180 | try test__floatuntisf(20, 20.0); | |
| 209 | try test_f32_floatFromInt_u128(1, 1.0); | |
| 210 | try test_f32_floatFromInt_u128(2, 2.0); | |
| 211 | try test_f32_floatFromInt_u128(20, 20.0); | |
| 181 | 212 | |
| 182 | try test__floatuntisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 183 | try test__floatuntisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 213 | try test_f32_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 214 | try test_f32_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 184 | 215 | |
| 185 | try test__floatuntisf(make_uti(0x8000008000000000, 0), 0x1.000001p+127); | |
| 186 | try test__floatuntisf(make_uti(0x8000000000000800, 0), 0x1.0p+127); | |
| 187 | try test__floatuntisf(make_uti(0x8000010000000000, 0), 0x1.000002p+127); | |
| 216 | try test_f32_floatFromInt_u128(make_uti(0x8000008000000000, 0), 0x1.000001p+127); | |
| 217 | try test_f32_floatFromInt_u128(make_uti(0x8000000000000800, 0), 0x1.0p+127); | |
| 218 | try test_f32_floatFromInt_u128(make_uti(0x8000010000000000, 0), 0x1.000002p+127); | |
| 188 | 219 | |
| 189 | try test__floatuntisf(make_uti(0x8000000000000000, 0), 0x1.000000p+127); | |
| 220 | try test_f32_floatFromInt_u128(make_uti(0x8000000000000000, 0), 0x1.000000p+127); | |
| 190 | 221 | |
| 191 | try test__floatuntisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 222 | try test_f32_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 192 | 223 | |
| 193 | try test__floatuntisf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | |
| 194 | try test__floatuntisf(0x0007FB72EB000000, 0x1.FEDCBACp+50); | |
| 224 | try test_f32_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | |
| 225 | try test_f32_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50); | |
| 195 | 226 | |
| 196 | try test__floatuntisf(0x0007FB72EC000000, 0x1.FEDCBBp+50); | |
| 227 | try test_f32_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50); | |
| 197 | 228 | |
| 198 | try test__floatuntisf(0x0007FB72E6000000, 0x1.FEDCB98p+50); | |
| 199 | try test__floatuntisf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | |
| 200 | try test__floatuntisf(0x0007FB72E4000000, 0x1.FEDCB9p+50); | |
| 229 | try test_f32_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50); | |
| 230 | try test_f32_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | |
| 231 | try test_f32_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50); | |
| 201 | 232 | |
| 202 | try test__floatuntisf(0xFFFFFFFFFFFFFFFE, 0x1p+64); | |
| 203 | try test__floatuntisf(0xFFFFFFFFFFFFFFFF, 0x1p+64); | |
| 233 | try test_f32_floatFromInt_u128(0xFFFFFFFFFFFFFFFE, 0x1p+64); | |
| 234 | try test_f32_floatFromInt_u128(0xFFFFFFFFFFFFFFFF, 0x1p+64); | |
| 204 | 235 | |
| 205 | try test__floatuntisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 236 | try test_f32_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 206 | 237 | |
| 207 | try test__floatuntisf(0x0007FB72EA000000, 0x1.FEDCBAp+50); | |
| 208 | try test__floatuntisf(0x0007FB72EB000000, 0x1.FEDCBAp+50); | |
| 209 | try test__floatuntisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); | |
| 210 | try test__floatuntisf(0x0007FB72EC000000, 0x1.FEDCBCp+50); | |
| 211 | try test__floatuntisf(0x0007FB72E8000001, 0x1.FEDCBAp+50); | |
| 238 | try test_f32_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBAp+50); | |
| 239 | try test_f32_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBAp+50); | |
| 240 | try test_f32_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); | |
| 241 | try test_f32_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBCp+50); | |
| 242 | try test_f32_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBAp+50); | |
| 212 | 243 | |
| 213 | try test__floatuntisf(0x0007FB72E6000000, 0x1.FEDCBAp+50); | |
| 214 | try test__floatuntisf(0x0007FB72E7000000, 0x1.FEDCBAp+50); | |
| 215 | try test__floatuntisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); | |
| 216 | try test__floatuntisf(0x0007FB72E4000001, 0x1.FEDCBAp+50); | |
| 217 | try test__floatuntisf(0x0007FB72E4000000, 0x1.FEDCB8p+50); | |
| 244 | try test_f32_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCBAp+50); | |
| 245 | try test_f32_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCBAp+50); | |
| 246 | try test_f32_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); | |
| 247 | try test_f32_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCBAp+50); | |
| 248 | try test_f32_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB8p+50); | |
| 218 | 249 | |
| 219 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCB90000000000001), 0x1.FEDCBAp+76); | |
| 220 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBA0000000000000), 0x1.FEDCBAp+76); | |
| 221 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBAFFFFFFFFFFFFF), 0x1.FEDCBAp+76); | |
| 222 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBB0000000000000), 0x1.FEDCBCp+76); | |
| 223 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBB0000000000001), 0x1.FEDCBCp+76); | |
| 224 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBBFFFFFFFFFFFFF), 0x1.FEDCBCp+76); | |
| 225 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBC0000000000000), 0x1.FEDCBCp+76); | |
| 226 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBC0000000000001), 0x1.FEDCBCp+76); | |
| 227 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBD0000000000000), 0x1.FEDCBCp+76); | |
| 228 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBD0000000000001), 0x1.FEDCBEp+76); | |
| 229 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBDFFFFFFFFFFFFF), 0x1.FEDCBEp+76); | |
| 230 | try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBE0000000000000), 0x1.FEDCBEp+76); | |
| 250 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCB90000000000001), 0x1.FEDCBAp+76); | |
| 251 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBA0000000000000), 0x1.FEDCBAp+76); | |
| 252 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBAFFFFFFFFFFFFF), 0x1.FEDCBAp+76); | |
| 253 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBB0000000000000), 0x1.FEDCBCp+76); | |
| 254 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBB0000000000001), 0x1.FEDCBCp+76); | |
| 255 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBBFFFFFFFFFFFFF), 0x1.FEDCBCp+76); | |
| 256 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBC0000000000000), 0x1.FEDCBCp+76); | |
| 257 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBC0000000000001), 0x1.FEDCBCp+76); | |
| 258 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBD0000000000000), 0x1.FEDCBCp+76); | |
| 259 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBD0000000000001), 0x1.FEDCBEp+76); | |
| 260 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBDFFFFFFFFFFFFF), 0x1.FEDCBEp+76); | |
| 261 | try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBE0000000000000), 0x1.FEDCBEp+76); | |
| 231 | 262 | |
| 232 | 263 | // Test overflow to infinity |
| 233 | try test__floatuntisf(math.maxInt(u128), @bitCast(math.inf(f32))); | |
| 264 | try test_f32_floatFromInt_u128(math.maxInt(u128), @bitCast(math.inf(f32))); | |
| 234 | 265 | } |
| 235 | 266 | |
| 236 | fn test_floateisf(expected: u32, comptime T: type, a: T) !void { | |
| 267 | fn test_f32_floatFromInt(expected: u32, comptime T: type, a: T) !void { | |
| 237 | 268 | const int = @typeInfo(T).int; |
| 238 | 269 | const r = switch (int.signedness) { |
| 239 | .signed => __floateisf, | |
| 240 | .unsigned => __floatuneisf, | |
| 241 | }(@ptrCast(&a), int.bits); | |
| 270 | .signed => f32_floatFromInt_signed, | |
| 271 | .unsigned => f32_floatFromInt_unsigned, | |
| 272 | }(@ptrCast(&a)); | |
| 242 | 273 | try testing.expect(expected == @as(u32, @bitCast(r))); |
| 243 | 274 | } |
| 244 | 275 | |
| 245 | test "floateisf" { | |
| 246 | try test_floateisf(0xFF000000, i256, -1 << 127); | |
| 247 | try test_floateisf(0xFF000000, i256, -math.maxInt(u127)); | |
| 248 | try test_floateisf(0xDF012347, i256, -0x8123468100000000); | |
| 249 | try test_floateisf(0xDF012347, i256, -0x8123468000000001); | |
| 250 | try test_floateisf(0xDF012346, i256, -0x8123468000000000); | |
| 251 | try test_floateisf(0xDF012346, i256, -0x8123458100000000); | |
| 252 | try test_floateisf(0xDF012346, i256, -0x8123458000000001); | |
| 253 | try test_floateisf(0xDF012346, i256, -0x8123458000000000); | |
| 254 | try test_floateisf(0xDF012345, i256, -0x8123456789ABCDEF); | |
| 255 | try test_floateisf(0xBF800000, i256, -1); | |
| 256 | try test_floateisf(0x00000000, i256, 0); | |
| 257 | try test_floateisf(0x5F012345, i256, 0x8123456789ABCDEF); | |
| 258 | try test_floateisf(0x5F012346, i256, 0x8123458000000000); | |
| 259 | try test_floateisf(0x5F012346, i256, 0x8123458000000001); | |
| 260 | try test_floateisf(0x5F012346, i256, 0x8123458100000000); | |
| 261 | try test_floateisf(0x5F012346, i256, 0x8123468000000000); | |
| 262 | try test_floateisf(0x5F012347, i256, 0x8123468000000001); | |
| 263 | try test_floateisf(0x5F012347, i256, 0x8123468100000000); | |
| 264 | try test_floateisf(0x7F000000, i256, math.maxInt(u127)); | |
| 265 | try test_floateisf(0x7F000000, i256, 1 << 127); | |
| 266 | } | |
| 267 | ||
| 268 | test "floatuneisf" { | |
| 269 | try test_floateisf(0x00000000, u256, 0); | |
| 270 | try test_floateisf(0x5F012345, u256, 0x8123456789ABCDEF); | |
| 271 | try test_floateisf(0x5F012346, u256, 0x8123458000000000); | |
| 272 | try test_floateisf(0x5F012346, u256, 0x8123458000000001); | |
| 273 | try test_floateisf(0x5F012346, u256, 0x8123458080000000); | |
| 274 | try test_floateisf(0x5F012346, u256, 0x8123468000000000); | |
| 275 | try test_floateisf(0x5F012347, u256, 0x8123468000000001); | |
| 276 | try test_floateisf(0x5F012347, u256, 0x8123468080000000); | |
| 277 | try test_floateisf(0x7F000000, u256, math.maxInt(u127)); | |
| 278 | try test_floateisf(0x7F000000, u256, 1 << 127); | |
| 279 | try test_floateisf(0x7F800000, u256, math.maxInt(u256)); | |
| 280 | } | |
| 281 | ||
| 282 | fn test_one_floatsidf(a: i32, expected: u64) !void { | |
| 283 | const r = __floatsidf(a); | |
| 276 | test f32_floatFromInt_signed { | |
| 277 | try test_f32_floatFromInt(0xFF000000, i256, -1 << 127); | |
| 278 | try test_f32_floatFromInt(0xFF000000, i256, -math.maxInt(u127)); | |
| 279 | try test_f32_floatFromInt(0xDF012347, i256, -0x8123468100000000); | |
| 280 | try test_f32_floatFromInt(0xDF012347, i256, -0x8123468000000001); | |
| 281 | try test_f32_floatFromInt(0xDF012346, i256, -0x8123468000000000); | |
| 282 | try test_f32_floatFromInt(0xDF012346, i256, -0x8123458100000000); | |
| 283 | try test_f32_floatFromInt(0xDF012346, i256, -0x8123458000000001); | |
| 284 | try test_f32_floatFromInt(0xDF012346, i256, -0x8123458000000000); | |
| 285 | try test_f32_floatFromInt(0xDF012345, i256, -0x8123456789ABCDEF); | |
| 286 | try test_f32_floatFromInt(0xBF800000, i256, -1); | |
| 287 | try test_f32_floatFromInt(0x00000000, i256, 0); | |
| 288 | try test_f32_floatFromInt(0x5F012345, i256, 0x8123456789ABCDEF); | |
| 289 | try test_f32_floatFromInt(0x5F012346, i256, 0x8123458000000000); | |
| 290 | try test_f32_floatFromInt(0x5F012346, i256, 0x8123458000000001); | |
| 291 | try test_f32_floatFromInt(0x5F012346, i256, 0x8123458100000000); | |
| 292 | try test_f32_floatFromInt(0x5F012346, i256, 0x8123468000000000); | |
| 293 | try test_f32_floatFromInt(0x5F012347, i256, 0x8123468000000001); | |
| 294 | try test_f32_floatFromInt(0x5F012347, i256, 0x8123468100000000); | |
| 295 | try test_f32_floatFromInt(0x7F000000, i256, math.maxInt(u127)); | |
| 296 | try test_f32_floatFromInt(0x7F000000, i256, 1 << 127); | |
| 297 | } | |
| 298 | ||
| 299 | test f32_floatFromInt_unsigned { | |
| 300 | try test_f32_floatFromInt(0x00000000, u256, 0); | |
| 301 | try test_f32_floatFromInt(0x5F012345, u256, 0x8123456789ABCDEF); | |
| 302 | try test_f32_floatFromInt(0x5F012346, u256, 0x8123458000000000); | |
| 303 | try test_f32_floatFromInt(0x5F012346, u256, 0x8123458000000001); | |
| 304 | try test_f32_floatFromInt(0x5F012346, u256, 0x8123458080000000); | |
| 305 | try test_f32_floatFromInt(0x5F012346, u256, 0x8123468000000000); | |
| 306 | try test_f32_floatFromInt(0x5F012347, u256, 0x8123468000000001); | |
| 307 | try test_f32_floatFromInt(0x5F012347, u256, 0x8123468080000000); | |
| 308 | try test_f32_floatFromInt(0x7F000000, u256, math.maxInt(u127)); | |
| 309 | try test_f32_floatFromInt(0x7F000000, u256, 1 << 127); | |
| 310 | try test_f32_floatFromInt(0x7F800000, u256, math.maxInt(u256)); | |
| 311 | } | |
| 312 | ||
| 313 | fn test_f64_floatFromInt_i32(a: i32, expected: u64) !void { | |
| 314 | const r = f64_floatFromInt_i32(a); | |
| 284 | 315 | try std.testing.expect(@as(u64, @bitCast(r)) == expected); |
| 285 | 316 | } |
| 286 | 317 | |
| 287 | fn test_one_floatunsidf(a: u32, expected: u64) !void { | |
| 288 | const r = __floatunsidf(a); | |
| 318 | fn test_f64_floatFromInt_u32(a: u32, expected: u64) !void { | |
| 319 | const r = f64_floatFromInt_u32(a); | |
| 289 | 320 | try std.testing.expect(@as(u64, @bitCast(r)) == expected); |
| 290 | 321 | } |
| 291 | 322 | |
| 292 | test "floatsidf" { | |
| 293 | try test_one_floatsidf(0, 0x0000000000000000); | |
| 294 | try test_one_floatsidf(1, 0x3ff0000000000000); | |
| 295 | try test_one_floatsidf(-1, 0xbff0000000000000); | |
| 296 | try test_one_floatsidf(0x7FFFFFFF, 0x41dfffffffc00000); | |
| 297 | try test_one_floatsidf(@bitCast(@as(u32, @intCast(0x80000000))), 0xc1e0000000000000); | |
| 323 | test f64_floatFromInt_i32 { | |
| 324 | try test_f64_floatFromInt_i32(0, 0x0000000000000000); | |
| 325 | try test_f64_floatFromInt_i32(1, 0x3ff0000000000000); | |
| 326 | try test_f64_floatFromInt_i32(-1, 0xbff0000000000000); | |
| 327 | try test_f64_floatFromInt_i32(0x7FFFFFFF, 0x41dfffffffc00000); | |
| 328 | try test_f64_floatFromInt_i32(@bitCast(@as(u32, @intCast(0x80000000))), 0xc1e0000000000000); | |
| 298 | 329 | } |
| 299 | 330 | |
| 300 | test "floatunsidf" { | |
| 301 | try test_one_floatunsidf(0, 0x0000000000000000); | |
| 302 | try test_one_floatunsidf(1, 0x3ff0000000000000); | |
| 303 | try test_one_floatunsidf(0x7FFFFFFF, 0x41dfffffffc00000); | |
| 304 | try test_one_floatunsidf(@intCast(0x80000000), 0x41e0000000000000); | |
| 305 | try test_one_floatunsidf(@intCast(0xFFFFFFFF), 0x41efffffffe00000); | |
| 331 | test f64_floatFromInt_u32 { | |
| 332 | try test_f64_floatFromInt_u32(0, 0x0000000000000000); | |
| 333 | try test_f64_floatFromInt_u32(1, 0x3ff0000000000000); | |
| 334 | try test_f64_floatFromInt_u32(0x7FFFFFFF, 0x41dfffffffc00000); | |
| 335 | try test_f64_floatFromInt_u32(@intCast(0x80000000), 0x41e0000000000000); | |
| 336 | try test_f64_floatFromInt_u32(@intCast(0xFFFFFFFF), 0x41efffffffe00000); | |
| 306 | 337 | } |
| 307 | 338 | |
| 308 | fn test__floatdidf(a: i64, expected: f64) !void { | |
| 309 | const r = __floatdidf(a); | |
| 339 | fn test_f64_floatFromInt_i64(a: i64, expected: f64) !void { | |
| 340 | const r = f64_floatFromInt_i64(a); | |
| 310 | 341 | try testing.expect(r == expected); |
| 311 | 342 | } |
| 312 | 343 | |
| 313 | fn test__floatundidf(a: u64, expected: f64) !void { | |
| 314 | const r = __floatundidf(a); | |
| 344 | fn test_f64_floatFromInt_u64(a: u64, expected: f64) !void { | |
| 345 | const r = f64_floatFromInt_u64(a); | |
| 315 | 346 | try testing.expect(r == expected); |
| 316 | 347 | } |
| 317 | 348 | |
| 318 | test "floatdidf" { | |
| 319 | try test__floatdidf(0, 0.0); | |
| 320 | try test__floatdidf(1, 1.0); | |
| 321 | try test__floatdidf(2, 2.0); | |
| 322 | try test__floatdidf(20, 20.0); | |
| 323 | try test__floatdidf(-1, -1.0); | |
| 324 | try test__floatdidf(-2, -2.0); | |
| 325 | try test__floatdidf(-20, -20.0); | |
| 326 | try test__floatdidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 327 | try test__floatdidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | |
| 328 | try test__floatdidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 329 | try test__floatdidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | |
| 330 | try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000008000000000))), -0x1.FFFFFEp+62); | |
| 331 | try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000800))), -0x1.FFFFFFFFFFFFEp+62); | |
| 332 | try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000010000000000))), -0x1.FFFFFCp+62); | |
| 333 | try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000001000))), -0x1.FFFFFFFFFFFFCp+62); | |
| 334 | try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000000))), -0x1.000000p+63); | |
| 335 | try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000001))), -0x1.000000p+63); // 0x8000000000000001 | |
| 336 | try test__floatdidf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 337 | try test__floatdidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | |
| 338 | try test__floatdidf(0x0007FB72EB000000, 0x1.FEDCBACp+50); | |
| 339 | try test__floatdidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | |
| 340 | try test__floatdidf(0x0007FB72EC000000, 0x1.FEDCBBp+50); | |
| 341 | try test__floatdidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | |
| 342 | try test__floatdidf(0x0007FB72E6000000, 0x1.FEDCB98p+50); | |
| 343 | try test__floatdidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | |
| 344 | try test__floatdidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | |
| 345 | try test__floatdidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | |
| 346 | try test__floatdidf(0x0007FB72E4000000, 0x1.FEDCB9p+50); | |
| 347 | try test__floatdidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | |
| 348 | try test__floatdidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); | |
| 349 | try test__floatdidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); | |
| 350 | try test__floatdidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); | |
| 351 | try test__floatdidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); | |
| 352 | try test__floatdidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); | |
| 353 | try test__floatdidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); | |
| 354 | try test__floatdidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); | |
| 355 | try test__floatdidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); | |
| 356 | try test__floatdidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); | |
| 357 | try test__floatdidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); | |
| 358 | try test__floatdidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); | |
| 359 | try test__floatdidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); | |
| 360 | try test__floatdidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); | |
| 361 | try test__floatdidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | |
| 362 | } | |
| 363 | ||
| 364 | test "floatundidf" { | |
| 365 | try test__floatundidf(0, 0.0); | |
| 366 | try test__floatundidf(1, 1.0); | |
| 367 | try test__floatundidf(2, 2.0); | |
| 368 | try test__floatundidf(20, 20.0); | |
| 369 | try test__floatundidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 370 | try test__floatundidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | |
| 371 | try test__floatundidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 372 | try test__floatundidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | |
| 373 | try test__floatundidf(0x8000008000000000, 0x1.000001p+63); | |
| 374 | try test__floatundidf(0x8000000000000800, 0x1.0000000000001p+63); | |
| 375 | try test__floatundidf(0x8000010000000000, 0x1.000002p+63); | |
| 376 | try test__floatundidf(0x8000000000001000, 0x1.0000000000002p+63); | |
| 377 | try test__floatundidf(0x8000000000000000, 0x1p+63); | |
| 378 | try test__floatundidf(0x8000000000000001, 0x1p+63); | |
| 379 | try test__floatundidf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 380 | try test__floatundidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | |
| 381 | try test__floatundidf(0x0007FB72EB000000, 0x1.FEDCBACp+50); | |
| 382 | try test__floatundidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | |
| 383 | try test__floatundidf(0x0007FB72EC000000, 0x1.FEDCBBp+50); | |
| 384 | try test__floatundidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | |
| 385 | try test__floatundidf(0x0007FB72E6000000, 0x1.FEDCB98p+50); | |
| 386 | try test__floatundidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | |
| 387 | try test__floatundidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | |
| 388 | try test__floatundidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | |
| 389 | try test__floatundidf(0x0007FB72E4000000, 0x1.FEDCB9p+50); | |
| 390 | try test__floatundidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | |
| 391 | try test__floatundidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); | |
| 392 | try test__floatundidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); | |
| 393 | try test__floatundidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); | |
| 394 | try test__floatundidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); | |
| 395 | try test__floatundidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); | |
| 396 | try test__floatundidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); | |
| 397 | try test__floatundidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); | |
| 398 | try test__floatundidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); | |
| 399 | try test__floatundidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); | |
| 400 | try test__floatundidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); | |
| 401 | try test__floatundidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); | |
| 402 | try test__floatundidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); | |
| 403 | try test__floatundidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); | |
| 404 | try test__floatundidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | |
| 405 | } | |
| 406 | ||
| 407 | fn test__floattidf(a: i128, expected: f64) !void { | |
| 408 | const x = __floattidf(a); | |
| 349 | test f64_floatFromInt_i64 { | |
| 350 | try test_f64_floatFromInt_i64(0, 0.0); | |
| 351 | try test_f64_floatFromInt_i64(1, 1.0); | |
| 352 | try test_f64_floatFromInt_i64(2, 2.0); | |
| 353 | try test_f64_floatFromInt_i64(20, 20.0); | |
| 354 | try test_f64_floatFromInt_i64(-1, -1.0); | |
| 355 | try test_f64_floatFromInt_i64(-2, -2.0); | |
| 356 | try test_f64_floatFromInt_i64(-20, -20.0); | |
| 357 | try test_f64_floatFromInt_i64(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 358 | try test_f64_floatFromInt_i64(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | |
| 359 | try test_f64_floatFromInt_i64(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 360 | try test_f64_floatFromInt_i64(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | |
| 361 | try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000008000000000))), -0x1.FFFFFEp+62); | |
| 362 | try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000800))), -0x1.FFFFFFFFFFFFEp+62); | |
| 363 | try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000010000000000))), -0x1.FFFFFCp+62); | |
| 364 | try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000001000))), -0x1.FFFFFFFFFFFFCp+62); | |
| 365 | try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000000))), -0x1.000000p+63); | |
| 366 | try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000001))), -0x1.000000p+63); // 0x8000000000000001 | |
| 367 | try test_f64_floatFromInt_i64(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 368 | try test_f64_floatFromInt_i64(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | |
| 369 | try test_f64_floatFromInt_i64(0x0007FB72EB000000, 0x1.FEDCBACp+50); | |
| 370 | try test_f64_floatFromInt_i64(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | |
| 371 | try test_f64_floatFromInt_i64(0x0007FB72EC000000, 0x1.FEDCBBp+50); | |
| 372 | try test_f64_floatFromInt_i64(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | |
| 373 | try test_f64_floatFromInt_i64(0x0007FB72E6000000, 0x1.FEDCB98p+50); | |
| 374 | try test_f64_floatFromInt_i64(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | |
| 375 | try test_f64_floatFromInt_i64(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | |
| 376 | try test_f64_floatFromInt_i64(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | |
| 377 | try test_f64_floatFromInt_i64(0x0007FB72E4000000, 0x1.FEDCB9p+50); | |
| 378 | try test_f64_floatFromInt_i64(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | |
| 379 | try test_f64_floatFromInt_i64(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); | |
| 380 | try test_f64_floatFromInt_i64(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); | |
| 381 | try test_f64_floatFromInt_i64(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); | |
| 382 | try test_f64_floatFromInt_i64(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); | |
| 383 | try test_f64_floatFromInt_i64(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); | |
| 384 | try test_f64_floatFromInt_i64(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); | |
| 385 | try test_f64_floatFromInt_i64(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); | |
| 386 | try test_f64_floatFromInt_i64(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); | |
| 387 | try test_f64_floatFromInt_i64(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); | |
| 388 | try test_f64_floatFromInt_i64(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); | |
| 389 | try test_f64_floatFromInt_i64(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); | |
| 390 | try test_f64_floatFromInt_i64(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); | |
| 391 | try test_f64_floatFromInt_i64(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); | |
| 392 | try test_f64_floatFromInt_i64(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | |
| 393 | } | |
| 394 | ||
| 395 | test f64_floatFromInt_u64 { | |
| 396 | try test_f64_floatFromInt_u64(0, 0.0); | |
| 397 | try test_f64_floatFromInt_u64(1, 1.0); | |
| 398 | try test_f64_floatFromInt_u64(2, 2.0); | |
| 399 | try test_f64_floatFromInt_u64(20, 20.0); | |
| 400 | try test_f64_floatFromInt_u64(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 401 | try test_f64_floatFromInt_u64(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | |
| 402 | try test_f64_floatFromInt_u64(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 403 | try test_f64_floatFromInt_u64(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | |
| 404 | try test_f64_floatFromInt_u64(0x8000008000000000, 0x1.000001p+63); | |
| 405 | try test_f64_floatFromInt_u64(0x8000000000000800, 0x1.0000000000001p+63); | |
| 406 | try test_f64_floatFromInt_u64(0x8000010000000000, 0x1.000002p+63); | |
| 407 | try test_f64_floatFromInt_u64(0x8000000000001000, 0x1.0000000000002p+63); | |
| 408 | try test_f64_floatFromInt_u64(0x8000000000000000, 0x1p+63); | |
| 409 | try test_f64_floatFromInt_u64(0x8000000000000001, 0x1p+63); | |
| 410 | try test_f64_floatFromInt_u64(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 411 | try test_f64_floatFromInt_u64(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | |
| 412 | try test_f64_floatFromInt_u64(0x0007FB72EB000000, 0x1.FEDCBACp+50); | |
| 413 | try test_f64_floatFromInt_u64(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | |
| 414 | try test_f64_floatFromInt_u64(0x0007FB72EC000000, 0x1.FEDCBBp+50); | |
| 415 | try test_f64_floatFromInt_u64(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | |
| 416 | try test_f64_floatFromInt_u64(0x0007FB72E6000000, 0x1.FEDCB98p+50); | |
| 417 | try test_f64_floatFromInt_u64(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | |
| 418 | try test_f64_floatFromInt_u64(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | |
| 419 | try test_f64_floatFromInt_u64(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | |
| 420 | try test_f64_floatFromInt_u64(0x0007FB72E4000000, 0x1.FEDCB9p+50); | |
| 421 | try test_f64_floatFromInt_u64(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | |
| 422 | try test_f64_floatFromInt_u64(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); | |
| 423 | try test_f64_floatFromInt_u64(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); | |
| 424 | try test_f64_floatFromInt_u64(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); | |
| 425 | try test_f64_floatFromInt_u64(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); | |
| 426 | try test_f64_floatFromInt_u64(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); | |
| 427 | try test_f64_floatFromInt_u64(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); | |
| 428 | try test_f64_floatFromInt_u64(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); | |
| 429 | try test_f64_floatFromInt_u64(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); | |
| 430 | try test_f64_floatFromInt_u64(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); | |
| 431 | try test_f64_floatFromInt_u64(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); | |
| 432 | try test_f64_floatFromInt_u64(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); | |
| 433 | try test_f64_floatFromInt_u64(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); | |
| 434 | try test_f64_floatFromInt_u64(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); | |
| 435 | try test_f64_floatFromInt_u64(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | |
| 436 | } | |
| 437 | ||
| 438 | fn test_f64_floatFromInt_i128(a: i128, expected: f64) !void { | |
| 439 | const x = f64_floatFromInt_i128(a); | |
| 409 | 440 | try testing.expect(x == expected); |
| 410 | 441 | } |
| 411 | 442 | |
| 412 | fn test__floatuntidf(a: u128, expected: f64) !void { | |
| 413 | const x = __floatuntidf(a); | |
| 443 | fn test_f64_floatFromInt_u128(a: u128, expected: f64) !void { | |
| 444 | const x = f64_floatFromInt_u128(a); | |
| 414 | 445 | try testing.expect(x == expected); |
| 415 | 446 | } |
| 416 | 447 | |
| 417 | test "floattidf" { | |
| 418 | try test__floattidf(0, 0.0); | |
| 419 | ||
| 420 | try test__floattidf(1, 1.0); | |
| 421 | try test__floattidf(2, 2.0); | |
| 422 | try test__floattidf(20, 20.0); | |
| 423 | try test__floattidf(-1, -1.0); | |
| 424 | try test__floattidf(-2, -2.0); | |
| 425 | try test__floattidf(-20, -20.0); | |
| 426 | ||
| 427 | try test__floattidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 428 | try test__floattidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | |
| 429 | try test__floattidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 430 | try test__floattidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | |
| 431 | ||
| 432 | try test__floattidf(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126); | |
| 433 | try test__floattidf(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126); | |
| 434 | try test__floattidf(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126); | |
| 435 | try test__floattidf(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126); | |
| 436 | ||
| 437 | try test__floattidf(make_ti(0x8000000000000000, 0), -0x1.000000p+127); | |
| 438 | try test__floattidf(make_ti(0x8000000000000001, 0), -0x1.000000p+127); | |
| 439 | ||
| 440 | try test__floattidf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 441 | ||
| 442 | try test__floattidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | |
| 443 | try test__floattidf(0x0007FB72EB000000, 0x1.FEDCBACp+50); | |
| 444 | try test__floattidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | |
| 445 | try test__floattidf(0x0007FB72EC000000, 0x1.FEDCBBp+50); | |
| 446 | try test__floattidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | |
| 447 | ||
| 448 | try test__floattidf(0x0007FB72E6000000, 0x1.FEDCB98p+50); | |
| 449 | try test__floattidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | |
| 450 | try test__floattidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | |
| 451 | try test__floattidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | |
| 452 | try test__floattidf(0x0007FB72E4000000, 0x1.FEDCB9p+50); | |
| 453 | ||
| 454 | try test__floattidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | |
| 455 | try test__floattidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); | |
| 456 | try test__floattidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); | |
| 457 | try test__floattidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); | |
| 458 | try test__floattidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); | |
| 459 | try test__floattidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); | |
| 460 | try test__floattidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); | |
| 461 | try test__floattidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); | |
| 462 | try test__floattidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); | |
| 463 | try test__floattidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); | |
| 464 | try test__floattidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); | |
| 465 | try test__floattidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); | |
| 466 | try test__floattidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); | |
| 467 | try test__floattidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); | |
| 468 | try test__floattidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | |
| 469 | ||
| 470 | try test__floattidf(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); | |
| 471 | try test__floattidf(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121); | |
| 472 | try test__floattidf(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121); | |
| 473 | try test__floattidf(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121); | |
| 474 | try test__floattidf(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121); | |
| 475 | try test__floattidf(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121); | |
| 476 | try test__floattidf(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121); | |
| 477 | try test__floattidf(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121); | |
| 478 | try test__floattidf(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121); | |
| 479 | try test__floattidf(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121); | |
| 480 | try test__floattidf(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121); | |
| 481 | try test__floattidf(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121); | |
| 482 | try test__floattidf(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121); | |
| 483 | try test__floattidf(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121); | |
| 484 | try test__floattidf(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); | |
| 485 | } | |
| 486 | ||
| 487 | test "floatuntidf" { | |
| 488 | try test__floatuntidf(0, 0.0); | |
| 489 | ||
| 490 | try test__floatuntidf(1, 1.0); | |
| 491 | try test__floatuntidf(2, 2.0); | |
| 492 | try test__floatuntidf(20, 20.0); | |
| 493 | ||
| 494 | try test__floatuntidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 495 | try test__floatuntidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | |
| 496 | try test__floatuntidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 497 | try test__floatuntidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | |
| 498 | ||
| 499 | try test__floatuntidf(make_uti(0x8000008000000000, 0), 0x1.000001p+127); | |
| 500 | try test__floatuntidf(make_uti(0x8000000000000800, 0), 0x1.0000000000001p+127); | |
| 501 | try test__floatuntidf(make_uti(0x8000010000000000, 0), 0x1.000002p+127); | |
| 502 | try test__floatuntidf(make_uti(0x8000000000001000, 0), 0x1.0000000000002p+127); | |
| 503 | ||
| 504 | try test__floatuntidf(make_uti(0x8000000000000000, 0), 0x1.000000p+127); | |
| 505 | try test__floatuntidf(make_uti(0x8000000000000001, 0), 0x1.0000000000000002p+127); | |
| 506 | ||
| 507 | try test__floatuntidf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 508 | ||
| 509 | try test__floatuntidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | |
| 510 | try test__floatuntidf(0x0007FB72EB000000, 0x1.FEDCBACp+50); | |
| 511 | try test__floatuntidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | |
| 512 | try test__floatuntidf(0x0007FB72EC000000, 0x1.FEDCBBp+50); | |
| 513 | try test__floatuntidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | |
| 514 | ||
| 515 | try test__floatuntidf(0x0007FB72E6000000, 0x1.FEDCB98p+50); | |
| 516 | try test__floatuntidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | |
| 517 | try test__floatuntidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | |
| 518 | try test__floatuntidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | |
| 519 | try test__floatuntidf(0x0007FB72E4000000, 0x1.FEDCB9p+50); | |
| 520 | ||
| 521 | try test__floatuntidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | |
| 522 | try test__floatuntidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); | |
| 523 | try test__floatuntidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); | |
| 524 | try test__floatuntidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); | |
| 525 | try test__floatuntidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); | |
| 526 | try test__floatuntidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); | |
| 527 | try test__floatuntidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); | |
| 528 | try test__floatuntidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); | |
| 529 | try test__floatuntidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); | |
| 530 | try test__floatuntidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); | |
| 531 | try test__floatuntidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); | |
| 532 | try test__floatuntidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); | |
| 533 | try test__floatuntidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); | |
| 534 | try test__floatuntidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); | |
| 535 | try test__floatuntidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | |
| 536 | ||
| 537 | try test__floatuntidf(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); | |
| 538 | try test__floatuntidf(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121); | |
| 539 | try test__floatuntidf(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121); | |
| 540 | try test__floatuntidf(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121); | |
| 541 | try test__floatuntidf(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121); | |
| 542 | try test__floatuntidf(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121); | |
| 543 | try test__floatuntidf(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121); | |
| 544 | try test__floatuntidf(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121); | |
| 545 | try test__floatuntidf(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121); | |
| 546 | try test__floatuntidf(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121); | |
| 547 | try test__floatuntidf(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121); | |
| 548 | try test__floatuntidf(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121); | |
| 549 | try test__floatuntidf(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121); | |
| 550 | try test__floatuntidf(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121); | |
| 551 | try test__floatuntidf(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); | |
| 552 | } | |
| 553 | ||
| 554 | fn test__floatsitf(a: i32, expected: u128) !void { | |
| 555 | const r = __floatsitf(a); | |
| 448 | test f64_floatFromInt_i128 { | |
| 449 | try test_f64_floatFromInt_i128(0, 0.0); | |
| 450 | ||
| 451 | try test_f64_floatFromInt_i128(1, 1.0); | |
| 452 | try test_f64_floatFromInt_i128(2, 2.0); | |
| 453 | try test_f64_floatFromInt_i128(20, 20.0); | |
| 454 | try test_f64_floatFromInt_i128(-1, -1.0); | |
| 455 | try test_f64_floatFromInt_i128(-2, -2.0); | |
| 456 | try test_f64_floatFromInt_i128(-20, -20.0); | |
| 457 | ||
| 458 | try test_f64_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 459 | try test_f64_floatFromInt_i128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | |
| 460 | try test_f64_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 461 | try test_f64_floatFromInt_i128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | |
| 462 | ||
| 463 | try test_f64_floatFromInt_i128(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126); | |
| 464 | try test_f64_floatFromInt_i128(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126); | |
| 465 | try test_f64_floatFromInt_i128(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126); | |
| 466 | try test_f64_floatFromInt_i128(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126); | |
| 467 | ||
| 468 | try test_f64_floatFromInt_i128(make_ti(0x8000000000000000, 0), -0x1.000000p+127); | |
| 469 | try test_f64_floatFromInt_i128(make_ti(0x8000000000000001, 0), -0x1.000000p+127); | |
| 470 | ||
| 471 | try test_f64_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 472 | ||
| 473 | try test_f64_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | |
| 474 | try test_f64_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBACp+50); | |
| 475 | try test_f64_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | |
| 476 | try test_f64_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBBp+50); | |
| 477 | try test_f64_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | |
| 478 | ||
| 479 | try test_f64_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCB98p+50); | |
| 480 | try test_f64_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | |
| 481 | try test_f64_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | |
| 482 | try test_f64_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | |
| 483 | try test_f64_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB9p+50); | |
| 484 | ||
| 485 | try test_f64_floatFromInt_i128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | |
| 486 | try test_f64_floatFromInt_i128(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); | |
| 487 | try test_f64_floatFromInt_i128(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); | |
| 488 | try test_f64_floatFromInt_i128(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); | |
| 489 | try test_f64_floatFromInt_i128(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); | |
| 490 | try test_f64_floatFromInt_i128(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); | |
| 491 | try test_f64_floatFromInt_i128(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); | |
| 492 | try test_f64_floatFromInt_i128(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); | |
| 493 | try test_f64_floatFromInt_i128(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); | |
| 494 | try test_f64_floatFromInt_i128(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); | |
| 495 | try test_f64_floatFromInt_i128(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); | |
| 496 | try test_f64_floatFromInt_i128(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); | |
| 497 | try test_f64_floatFromInt_i128(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); | |
| 498 | try test_f64_floatFromInt_i128(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); | |
| 499 | try test_f64_floatFromInt_i128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | |
| 500 | ||
| 501 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); | |
| 502 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121); | |
| 503 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121); | |
| 504 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121); | |
| 505 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121); | |
| 506 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121); | |
| 507 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121); | |
| 508 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121); | |
| 509 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121); | |
| 510 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121); | |
| 511 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121); | |
| 512 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121); | |
| 513 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121); | |
| 514 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121); | |
| 515 | try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); | |
| 516 | } | |
| 517 | ||
| 518 | test f64_floatFromInt_u128 { | |
| 519 | try test_f64_floatFromInt_u128(0, 0.0); | |
| 520 | ||
| 521 | try test_f64_floatFromInt_u128(1, 1.0); | |
| 522 | try test_f64_floatFromInt_u128(2, 2.0); | |
| 523 | try test_f64_floatFromInt_u128(20, 20.0); | |
| 524 | ||
| 525 | try test_f64_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 526 | try test_f64_floatFromInt_u128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | |
| 527 | try test_f64_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 528 | try test_f64_floatFromInt_u128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | |
| 529 | ||
| 530 | try test_f64_floatFromInt_u128(make_uti(0x8000008000000000, 0), 0x1.000001p+127); | |
| 531 | try test_f64_floatFromInt_u128(make_uti(0x8000000000000800, 0), 0x1.0000000000001p+127); | |
| 532 | try test_f64_floatFromInt_u128(make_uti(0x8000010000000000, 0), 0x1.000002p+127); | |
| 533 | try test_f64_floatFromInt_u128(make_uti(0x8000000000001000, 0), 0x1.0000000000002p+127); | |
| 534 | ||
| 535 | try test_f64_floatFromInt_u128(make_uti(0x8000000000000000, 0), 0x1.000000p+127); | |
| 536 | try test_f64_floatFromInt_u128(make_uti(0x8000000000000001, 0), 0x1.0000000000000002p+127); | |
| 537 | ||
| 538 | try test_f64_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 539 | ||
| 540 | try test_f64_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | |
| 541 | try test_f64_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50); | |
| 542 | try test_f64_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | |
| 543 | try test_f64_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50); | |
| 544 | try test_f64_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | |
| 545 | ||
| 546 | try test_f64_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50); | |
| 547 | try test_f64_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | |
| 548 | try test_f64_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | |
| 549 | try test_f64_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | |
| 550 | try test_f64_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50); | |
| 551 | ||
| 552 | try test_f64_floatFromInt_u128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | |
| 553 | try test_f64_floatFromInt_u128(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); | |
| 554 | try test_f64_floatFromInt_u128(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); | |
| 555 | try test_f64_floatFromInt_u128(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); | |
| 556 | try test_f64_floatFromInt_u128(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); | |
| 557 | try test_f64_floatFromInt_u128(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); | |
| 558 | try test_f64_floatFromInt_u128(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); | |
| 559 | try test_f64_floatFromInt_u128(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); | |
| 560 | try test_f64_floatFromInt_u128(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); | |
| 561 | try test_f64_floatFromInt_u128(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); | |
| 562 | try test_f64_floatFromInt_u128(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); | |
| 563 | try test_f64_floatFromInt_u128(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); | |
| 564 | try test_f64_floatFromInt_u128(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); | |
| 565 | try test_f64_floatFromInt_u128(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); | |
| 566 | try test_f64_floatFromInt_u128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | |
| 567 | ||
| 568 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); | |
| 569 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121); | |
| 570 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121); | |
| 571 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121); | |
| 572 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121); | |
| 573 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121); | |
| 574 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121); | |
| 575 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121); | |
| 576 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121); | |
| 577 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121); | |
| 578 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121); | |
| 579 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121); | |
| 580 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121); | |
| 581 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121); | |
| 582 | try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); | |
| 583 | } | |
| 584 | ||
| 585 | fn test_f128_floatFromInt_i32(a: i32, expected: u128) !void { | |
| 586 | const r = f128_floatFromInt_i32(a); | |
| 556 | 587 | try std.testing.expect(@as(u128, @bitCast(r)) == expected); |
| 557 | 588 | } |
| 558 | 589 | |
| 559 | test "floatsitf" { | |
| 560 | try test__floatsitf(0, 0); | |
| 561 | try test__floatsitf(0x7FFFFFFF, 0x401dfffffffc00000000000000000000); | |
| 562 | try test__floatsitf(0x12345678, 0x401b2345678000000000000000000000); | |
| 563 | try test__floatsitf(-0x12345678, 0xc01b2345678000000000000000000000); | |
| 564 | try test__floatsitf(@bitCast(@as(u32, @intCast(0xffffffff))), 0xbfff0000000000000000000000000000); | |
| 565 | try test__floatsitf(@bitCast(@as(u32, @intCast(0x80000000))), 0xc01e0000000000000000000000000000); | |
| 566 | } | |
| 567 | ||
| 568 | fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void { | |
| 569 | const x = __floatunsitf(a); | |
| 590 | fn test_f128_floatFromInt_u32(a: u32, expected_hi: u64, expected_lo: u64) !void { | |
| 591 | const x = f128_floatFromInt_u32(a); | |
| 570 | 592 | |
| 571 | 593 | const x_repr: u128 = @bitCast(x); |
| 572 | 594 | const x_hi: u64 = @intCast(x_repr >> 64); |
| ... | ... | @@ -581,24 +603,32 @@ fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void { |
| 581 | 603 | return; |
| 582 | 604 | } |
| 583 | 605 | } |
| 606 | return error.TestFailure; | |
| 607 | } | |
| 584 | 608 | |
| 585 | @panic("__floatunsitf test failure"); | |
| 609 | test f128_floatFromInt_i32 { | |
| 610 | try test_f128_floatFromInt_i32(0, 0); | |
| 611 | try test_f128_floatFromInt_i32(0x7FFFFFFF, 0x401dfffffffc00000000000000000000); | |
| 612 | try test_f128_floatFromInt_i32(0x12345678, 0x401b2345678000000000000000000000); | |
| 613 | try test_f128_floatFromInt_i32(-0x12345678, 0xc01b2345678000000000000000000000); | |
| 614 | try test_f128_floatFromInt_i32(@bitCast(@as(u32, @intCast(0xffffffff))), 0xbfff0000000000000000000000000000); | |
| 615 | try test_f128_floatFromInt_i32(@bitCast(@as(u32, @intCast(0x80000000))), 0xc01e0000000000000000000000000000); | |
| 586 | 616 | } |
| 587 | 617 | |
| 588 | test "floatunsitf" { | |
| 589 | try test__floatunsitf(0x7fffffff, 0x401dfffffffc0000, 0x0); | |
| 590 | try test__floatunsitf(0, 0x0, 0x0); | |
| 591 | try test__floatunsitf(0xffffffff, 0x401efffffffe0000, 0x0); | |
| 592 | try test__floatunsitf(0x12345678, 0x401b234567800000, 0x0); | |
| 618 | test f128_floatFromInt_u32 { | |
| 619 | try test_f128_floatFromInt_u32(0x7fffffff, 0x401dfffffffc0000, 0x0); | |
| 620 | try test_f128_floatFromInt_u32(0, 0x0, 0x0); | |
| 621 | try test_f128_floatFromInt_u32(0xffffffff, 0x401efffffffe0000, 0x0); | |
| 622 | try test_f128_floatFromInt_u32(0x12345678, 0x401b234567800000, 0x0); | |
| 593 | 623 | } |
| 594 | 624 | |
| 595 | fn test__floatditf(a: i64, expected: f128) !void { | |
| 596 | const x = __floatditf(a); | |
| 625 | fn test_f128_floatFromInt_i64(a: i64, expected: f128) !void { | |
| 626 | const x = f128_floatFromInt_i64(a); | |
| 597 | 627 | try testing.expect(x == expected); |
| 598 | 628 | } |
| 599 | 629 | |
| 600 | fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void { | |
| 601 | const x = __floatunditf(a); | |
| 630 | fn test_f128_floatFromInt_u64(a: u64, expected_hi: u64, expected_lo: u64) !void { | |
| 631 | const x = f128_floatFromInt_u64(a); | |
| 602 | 632 | |
| 603 | 633 | const x_repr: u128 = @bitCast(x); |
| 604 | 634 | const x_hi: u64 = @intCast(x_repr >> 64); |
| ... | ... | @@ -613,208 +643,207 @@ fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void { |
| 613 | 643 | return; |
| 614 | 644 | } |
| 615 | 645 | } |
| 616 | ||
| 617 | @panic("__floatunditf test failure"); | |
| 618 | } | |
| 619 | ||
| 620 | test "floatditf" { | |
| 621 | try test__floatditf(0x7fffffffffffffff, make_tf(0x403dffffffffffff, 0xfffc000000000000)); | |
| 622 | try test__floatditf(0x123456789abcdef1, make_tf(0x403b23456789abcd, 0xef10000000000000)); | |
| 623 | try test__floatditf(0x2, make_tf(0x4000000000000000, 0x0)); | |
| 624 | try test__floatditf(0x1, make_tf(0x3fff000000000000, 0x0)); | |
| 625 | try test__floatditf(0x0, make_tf(0x0, 0x0)); | |
| 626 | try test__floatditf(@bitCast(@as(u64, 0xffffffffffffffff)), make_tf(0xbfff000000000000, 0x0)); | |
| 627 | try test__floatditf(@bitCast(@as(u64, 0xfffffffffffffffe)), make_tf(0xc000000000000000, 0x0)); | |
| 628 | try test__floatditf(-0x123456789abcdef1, make_tf(0xc03b23456789abcd, 0xef10000000000000)); | |
| 629 | try test__floatditf(@bitCast(@as(u64, 0x8000000000000000)), make_tf(0xc03e000000000000, 0x0)); | |
| 630 | } | |
| 631 | ||
| 632 | test "floatunditf" { | |
| 633 | try test__floatunditf(0xffffffffffffffff, 0x403effffffffffff, 0xfffe000000000000); | |
| 634 | try test__floatunditf(0xfffffffffffffffe, 0x403effffffffffff, 0xfffc000000000000); | |
| 635 | try test__floatunditf(0x8000000000000000, 0x403e000000000000, 0x0); | |
| 636 | try test__floatunditf(0x7fffffffffffffff, 0x403dffffffffffff, 0xfffc000000000000); | |
| 637 | try test__floatunditf(0x123456789abcdef1, 0x403b23456789abcd, 0xef10000000000000); | |
| 638 | try test__floatunditf(0x2, 0x4000000000000000, 0x0); | |
| 639 | try test__floatunditf(0x1, 0x3fff000000000000, 0x0); | |
| 640 | try test__floatunditf(0x0, 0x0, 0x0); | |
| 641 | } | |
| 642 | ||
| 643 | fn test__floattitf(a: i128, expected: f128) !void { | |
| 644 | const x = __floattitf(a); | |
| 646 | return error.TestFailure; | |
| 647 | } | |
| 648 | ||
| 649 | test f128_floatFromInt_i64 { | |
| 650 | try test_f128_floatFromInt_i64(0x7fffffffffffffff, make_tf(0x403dffffffffffff, 0xfffc000000000000)); | |
| 651 | try test_f128_floatFromInt_i64(0x123456789abcdef1, make_tf(0x403b23456789abcd, 0xef10000000000000)); | |
| 652 | try test_f128_floatFromInt_i64(0x2, make_tf(0x4000000000000000, 0x0)); | |
| 653 | try test_f128_floatFromInt_i64(0x1, make_tf(0x3fff000000000000, 0x0)); | |
| 654 | try test_f128_floatFromInt_i64(0x0, make_tf(0x0, 0x0)); | |
| 655 | try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0xffffffffffffffff)), make_tf(0xbfff000000000000, 0x0)); | |
| 656 | try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0xfffffffffffffffe)), make_tf(0xc000000000000000, 0x0)); | |
| 657 | try test_f128_floatFromInt_i64(-0x123456789abcdef1, make_tf(0xc03b23456789abcd, 0xef10000000000000)); | |
| 658 | try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000000)), make_tf(0xc03e000000000000, 0x0)); | |
| 659 | } | |
| 660 | ||
| 661 | test f128_floatFromInt_u64 { | |
| 662 | try test_f128_floatFromInt_u64(0xffffffffffffffff, 0x403effffffffffff, 0xfffe000000000000); | |
| 663 | try test_f128_floatFromInt_u64(0xfffffffffffffffe, 0x403effffffffffff, 0xfffc000000000000); | |
| 664 | try test_f128_floatFromInt_u64(0x8000000000000000, 0x403e000000000000, 0x0); | |
| 665 | try test_f128_floatFromInt_u64(0x7fffffffffffffff, 0x403dffffffffffff, 0xfffc000000000000); | |
| 666 | try test_f128_floatFromInt_u64(0x123456789abcdef1, 0x403b23456789abcd, 0xef10000000000000); | |
| 667 | try test_f128_floatFromInt_u64(0x2, 0x4000000000000000, 0x0); | |
| 668 | try test_f128_floatFromInt_u64(0x1, 0x3fff000000000000, 0x0); | |
| 669 | try test_f128_floatFromInt_u64(0x0, 0x0, 0x0); | |
| 670 | } | |
| 671 | ||
| 672 | fn test_f128_floatFromInt_i128(a: i128, expected: f128) !void { | |
| 673 | const x = f128_floatFromInt_i128(a); | |
| 645 | 674 | try testing.expect(x == expected); |
| 646 | 675 | } |
| 647 | 676 | |
| 648 | fn test__floatuntitf(a: u128, expected: f128) !void { | |
| 649 | const x = __floatuntitf(a); | |
| 677 | fn test_f128_floatFromInt_u128(a: u128, expected: f128) !void { | |
| 678 | const x = f128_floatFromInt_u128(a); | |
| 650 | 679 | try testing.expect(x == expected); |
| 651 | 680 | } |
| 652 | 681 | |
| 653 | test "floattitf" { | |
| 654 | try test__floattitf(0, 0.0); | |
| 655 | ||
| 656 | try test__floattitf(1, 1.0); | |
| 657 | try test__floattitf(2, 2.0); | |
| 658 | try test__floattitf(20, 20.0); | |
| 659 | try test__floattitf(-1, -1.0); | |
| 660 | try test__floattitf(-2, -2.0); | |
| 661 | try test__floattitf(-20, -20.0); | |
| 662 | ||
| 663 | try test__floattitf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 664 | try test__floattitf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | |
| 665 | try test__floattitf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 666 | try test__floattitf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | |
| 667 | ||
| 668 | try test__floattitf(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126); | |
| 669 | try test__floattitf(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126); | |
| 670 | try test__floattitf(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126); | |
| 671 | try test__floattitf(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126); | |
| 672 | ||
| 673 | try test__floattitf(make_ti(0x8000000000000000, 0), -0x1.000000p+127); | |
| 674 | try test__floattitf(make_ti(0x8000000000000001, 0), -0x1.FFFFFFFFFFFFFFFCp+126); | |
| 675 | ||
| 676 | try test__floattitf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 677 | ||
| 678 | try test__floattitf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | |
| 679 | try test__floattitf(0x0007FB72EB000000, 0x1.FEDCBACp+50); | |
| 680 | try test__floattitf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | |
| 681 | try test__floattitf(0x0007FB72EC000000, 0x1.FEDCBBp+50); | |
| 682 | try test__floattitf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | |
| 683 | ||
| 684 | try test__floattitf(0x0007FB72E6000000, 0x1.FEDCB98p+50); | |
| 685 | try test__floattitf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | |
| 686 | try test__floattitf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | |
| 687 | try test__floattitf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | |
| 688 | try test__floattitf(0x0007FB72E4000000, 0x1.FEDCB9p+50); | |
| 689 | ||
| 690 | try test__floattitf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | |
| 691 | try test__floattitf(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57); | |
| 692 | try test__floattitf(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57); | |
| 693 | try test__floattitf(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57); | |
| 694 | try test__floattitf(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57); | |
| 695 | try test__floattitf(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57); | |
| 696 | try test__floattitf(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57); | |
| 697 | try test__floattitf(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57); | |
| 698 | try test__floattitf(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57); | |
| 699 | try test__floattitf(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57); | |
| 700 | try test__floattitf(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57); | |
| 701 | try test__floattitf(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57); | |
| 702 | try test__floattitf(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57); | |
| 703 | try test__floattitf(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57); | |
| 704 | try test__floattitf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | |
| 705 | ||
| 706 | try test__floattitf(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); | |
| 707 | try test__floattitf(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121); | |
| 708 | try test__floattitf(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121); | |
| 709 | try test__floattitf(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121); | |
| 710 | try test__floattitf(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121); | |
| 711 | try test__floattitf(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121); | |
| 712 | try test__floattitf(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121); | |
| 713 | try test__floattitf(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121); | |
| 714 | try test__floattitf(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121); | |
| 715 | try test__floattitf(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121); | |
| 716 | try test__floattitf(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121); | |
| 717 | try test__floattitf(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121); | |
| 718 | try test__floattitf(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121); | |
| 719 | try test__floattitf(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121); | |
| 720 | try test__floattitf(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); | |
| 721 | ||
| 722 | try test__floattitf(make_ti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63); | |
| 723 | ||
| 724 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124); | |
| 725 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124); | |
| 726 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124); | |
| 727 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124); | |
| 728 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124); | |
| 729 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124); | |
| 730 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124); | |
| 731 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124); | |
| 732 | try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124); | |
| 733 | } | |
| 734 | ||
| 735 | test "floatuntitf" { | |
| 736 | try test__floatuntitf(0, 0.0); | |
| 737 | ||
| 738 | try test__floatuntitf(1, 1.0); | |
| 739 | try test__floatuntitf(2, 2.0); | |
| 740 | try test__floatuntitf(20, 20.0); | |
| 741 | ||
| 742 | try test__floatuntitf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 743 | try test__floatuntitf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | |
| 744 | try test__floatuntitf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 745 | try test__floatuntitf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | |
| 746 | try test__floatuntitf(0x7FFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFEp+59); | |
| 747 | try test__floatuntitf(0xFFFFFFFFFFFFFFFE, 0xF.FFFFFFFFFFFFFFEp+60); | |
| 748 | try test__floatuntitf(0xFFFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFFp+60); | |
| 749 | ||
| 750 | try test__floatuntitf(0x8000008000000000, 0x8.000008p+60); | |
| 751 | try test__floatuntitf(0x8000000000000800, 0x8.0000000000008p+60); | |
| 752 | try test__floatuntitf(0x8000010000000000, 0x8.00001p+60); | |
| 753 | try test__floatuntitf(0x8000000000001000, 0x8.000000000001p+60); | |
| 754 | ||
| 755 | try test__floatuntitf(0x8000000000000000, 0x8p+60); | |
| 756 | try test__floatuntitf(0x8000000000000001, 0x8.000000000000001p+60); | |
| 757 | ||
| 758 | try test__floatuntitf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 759 | ||
| 760 | try test__floatuntitf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | |
| 761 | try test__floatuntitf(0x0007FB72EB000000, 0x1.FEDCBACp+50); | |
| 762 | try test__floatuntitf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | |
| 763 | try test__floatuntitf(0x0007FB72EC000000, 0x1.FEDCBBp+50); | |
| 764 | try test__floatuntitf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | |
| 765 | ||
| 766 | try test__floatuntitf(0x0007FB72E6000000, 0x1.FEDCB98p+50); | |
| 767 | try test__floatuntitf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | |
| 768 | try test__floatuntitf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | |
| 769 | try test__floatuntitf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | |
| 770 | try test__floatuntitf(0x0007FB72E4000000, 0x1.FEDCB9p+50); | |
| 771 | ||
| 772 | try test__floatuntitf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | |
| 773 | try test__floatuntitf(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57); | |
| 774 | try test__floatuntitf(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57); | |
| 775 | try test__floatuntitf(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57); | |
| 776 | try test__floatuntitf(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57); | |
| 777 | try test__floatuntitf(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57); | |
| 778 | try test__floatuntitf(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57); | |
| 779 | try test__floatuntitf(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57); | |
| 780 | try test__floatuntitf(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57); | |
| 781 | try test__floatuntitf(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57); | |
| 782 | try test__floatuntitf(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57); | |
| 783 | try test__floatuntitf(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57); | |
| 784 | try test__floatuntitf(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57); | |
| 785 | try test__floatuntitf(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57); | |
| 786 | try test__floatuntitf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | |
| 787 | ||
| 788 | try test__floatuntitf(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); | |
| 789 | try test__floatuntitf(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121); | |
| 790 | try test__floatuntitf(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121); | |
| 791 | try test__floatuntitf(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121); | |
| 792 | try test__floatuntitf(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121); | |
| 793 | try test__floatuntitf(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121); | |
| 794 | try test__floatuntitf(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121); | |
| 795 | try test__floatuntitf(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121); | |
| 796 | try test__floatuntitf(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121); | |
| 797 | try test__floatuntitf(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121); | |
| 798 | try test__floatuntitf(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121); | |
| 799 | try test__floatuntitf(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121); | |
| 800 | try test__floatuntitf(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121); | |
| 801 | try test__floatuntitf(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121); | |
| 802 | try test__floatuntitf(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); | |
| 803 | ||
| 804 | try test__floatuntitf(make_uti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63); | |
| 805 | ||
| 806 | try test__floatuntitf(make_uti(0xFFFFFFFFFFFFFFFF, 0x0000000000000000), 0x1.FFFFFFFFFFFFFFFEp+127); | |
| 807 | try test__floatuntitf(make_uti(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0x1.0000000000000000p+128); | |
| 808 | ||
| 809 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124); | |
| 810 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124); | |
| 811 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124); | |
| 812 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124); | |
| 813 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124); | |
| 814 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124); | |
| 815 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124); | |
| 816 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124); | |
| 817 | try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124); | |
| 682 | test f128_floatFromInt_i128 { | |
| 683 | try test_f128_floatFromInt_i128(0, 0.0); | |
| 684 | ||
| 685 | try test_f128_floatFromInt_i128(1, 1.0); | |
| 686 | try test_f128_floatFromInt_i128(2, 2.0); | |
| 687 | try test_f128_floatFromInt_i128(20, 20.0); | |
| 688 | try test_f128_floatFromInt_i128(-1, -1.0); | |
| 689 | try test_f128_floatFromInt_i128(-2, -2.0); | |
| 690 | try test_f128_floatFromInt_i128(-20, -20.0); | |
| 691 | ||
| 692 | try test_f128_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 693 | try test_f128_floatFromInt_i128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | |
| 694 | try test_f128_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 695 | try test_f128_floatFromInt_i128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | |
| 696 | ||
| 697 | try test_f128_floatFromInt_i128(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126); | |
| 698 | try test_f128_floatFromInt_i128(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126); | |
| 699 | try test_f128_floatFromInt_i128(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126); | |
| 700 | try test_f128_floatFromInt_i128(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126); | |
| 701 | ||
| 702 | try test_f128_floatFromInt_i128(make_ti(0x8000000000000000, 0), -0x1.000000p+127); | |
| 703 | try test_f128_floatFromInt_i128(make_ti(0x8000000000000001, 0), -0x1.FFFFFFFFFFFFFFFCp+126); | |
| 704 | ||
| 705 | try test_f128_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 706 | ||
| 707 | try test_f128_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | |
| 708 | try test_f128_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBACp+50); | |
| 709 | try test_f128_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | |
| 710 | try test_f128_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBBp+50); | |
| 711 | try test_f128_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | |
| 712 | ||
| 713 | try test_f128_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCB98p+50); | |
| 714 | try test_f128_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | |
| 715 | try test_f128_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | |
| 716 | try test_f128_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | |
| 717 | try test_f128_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB9p+50); | |
| 718 | ||
| 719 | try test_f128_floatFromInt_i128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | |
| 720 | try test_f128_floatFromInt_i128(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57); | |
| 721 | try test_f128_floatFromInt_i128(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57); | |
| 722 | try test_f128_floatFromInt_i128(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57); | |
| 723 | try test_f128_floatFromInt_i128(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57); | |
| 724 | try test_f128_floatFromInt_i128(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57); | |
| 725 | try test_f128_floatFromInt_i128(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57); | |
| 726 | try test_f128_floatFromInt_i128(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57); | |
| 727 | try test_f128_floatFromInt_i128(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57); | |
| 728 | try test_f128_floatFromInt_i128(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57); | |
| 729 | try test_f128_floatFromInt_i128(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57); | |
| 730 | try test_f128_floatFromInt_i128(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57); | |
| 731 | try test_f128_floatFromInt_i128(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57); | |
| 732 | try test_f128_floatFromInt_i128(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57); | |
| 733 | try test_f128_floatFromInt_i128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | |
| 734 | ||
| 735 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); | |
| 736 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121); | |
| 737 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121); | |
| 738 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121); | |
| 739 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121); | |
| 740 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121); | |
| 741 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121); | |
| 742 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121); | |
| 743 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121); | |
| 744 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121); | |
| 745 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121); | |
| 746 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121); | |
| 747 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121); | |
| 748 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121); | |
| 749 | try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); | |
| 750 | ||
| 751 | try test_f128_floatFromInt_i128(make_ti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63); | |
| 752 | ||
| 753 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124); | |
| 754 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124); | |
| 755 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124); | |
| 756 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124); | |
| 757 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124); | |
| 758 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124); | |
| 759 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124); | |
| 760 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124); | |
| 761 | try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124); | |
| 762 | } | |
| 763 | ||
| 764 | test f128_floatFromInt_u128 { | |
| 765 | try test_f128_floatFromInt_u128(0, 0.0); | |
| 766 | ||
| 767 | try test_f128_floatFromInt_u128(1, 1.0); | |
| 768 | try test_f128_floatFromInt_u128(2, 2.0); | |
| 769 | try test_f128_floatFromInt_u128(20, 20.0); | |
| 770 | ||
| 771 | try test_f128_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | |
| 772 | try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); | |
| 773 | try test_f128_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | |
| 774 | try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); | |
| 775 | try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFEp+59); | |
| 776 | try test_f128_floatFromInt_u128(0xFFFFFFFFFFFFFFFE, 0xF.FFFFFFFFFFFFFFEp+60); | |
| 777 | try test_f128_floatFromInt_u128(0xFFFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFFp+60); | |
| 778 | ||
| 779 | try test_f128_floatFromInt_u128(0x8000008000000000, 0x8.000008p+60); | |
| 780 | try test_f128_floatFromInt_u128(0x8000000000000800, 0x8.0000000000008p+60); | |
| 781 | try test_f128_floatFromInt_u128(0x8000010000000000, 0x8.00001p+60); | |
| 782 | try test_f128_floatFromInt_u128(0x8000000000001000, 0x8.000000000001p+60); | |
| 783 | ||
| 784 | try test_f128_floatFromInt_u128(0x8000000000000000, 0x8p+60); | |
| 785 | try test_f128_floatFromInt_u128(0x8000000000000001, 0x8.000000000000001p+60); | |
| 786 | ||
| 787 | try test_f128_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50); | |
| 788 | ||
| 789 | try test_f128_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50); | |
| 790 | try test_f128_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50); | |
| 791 | try test_f128_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); | |
| 792 | try test_f128_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50); | |
| 793 | try test_f128_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); | |
| 794 | ||
| 795 | try test_f128_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50); | |
| 796 | try test_f128_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); | |
| 797 | try test_f128_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); | |
| 798 | try test_f128_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); | |
| 799 | try test_f128_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50); | |
| 800 | ||
| 801 | try test_f128_floatFromInt_u128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); | |
| 802 | try test_f128_floatFromInt_u128(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57); | |
| 803 | try test_f128_floatFromInt_u128(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57); | |
| 804 | try test_f128_floatFromInt_u128(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57); | |
| 805 | try test_f128_floatFromInt_u128(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57); | |
| 806 | try test_f128_floatFromInt_u128(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57); | |
| 807 | try test_f128_floatFromInt_u128(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57); | |
| 808 | try test_f128_floatFromInt_u128(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57); | |
| 809 | try test_f128_floatFromInt_u128(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57); | |
| 810 | try test_f128_floatFromInt_u128(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57); | |
| 811 | try test_f128_floatFromInt_u128(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57); | |
| 812 | try test_f128_floatFromInt_u128(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57); | |
| 813 | try test_f128_floatFromInt_u128(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57); | |
| 814 | try test_f128_floatFromInt_u128(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57); | |
| 815 | try test_f128_floatFromInt_u128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); | |
| 816 | ||
| 817 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); | |
| 818 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121); | |
| 819 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121); | |
| 820 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121); | |
| 821 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121); | |
| 822 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121); | |
| 823 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121); | |
| 824 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121); | |
| 825 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121); | |
| 826 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121); | |
| 827 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121); | |
| 828 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121); | |
| 829 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121); | |
| 830 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121); | |
| 831 | try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); | |
| 832 | ||
| 833 | try test_f128_floatFromInt_u128(make_uti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63); | |
| 834 | ||
| 835 | try test_f128_floatFromInt_u128(make_uti(0xFFFFFFFFFFFFFFFF, 0x0000000000000000), 0x1.FFFFFFFFFFFFFFFEp+127); | |
| 836 | try test_f128_floatFromInt_u128(make_uti(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0x1.0000000000000000p+128); | |
| 837 | ||
| 838 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124); | |
| 839 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124); | |
| 840 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124); | |
| 841 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124); | |
| 842 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124); | |
| 843 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124); | |
| 844 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124); | |
| 845 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124); | |
| 846 | try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124); | |
| 818 | 847 | } |
| 819 | 848 | |
| 820 | 849 | fn make_ti(high: u64, low: u64) i128 { |
| ... | ... | @@ -838,45 +867,40 @@ fn make_tf(high: u64, low: u64) f128 { |
| 838 | 867 | return @bitCast(result); |
| 839 | 868 | } |
| 840 | 869 | |
| 841 | test "conversion to f16" { | |
| 842 | try testing.expect(__floatunsihf(@as(u32, 0)) == 0.0); | |
| 843 | try testing.expect(__floatunsihf(@as(u32, 1)) == 1.0); | |
| 844 | try testing.expect(__floatunsihf(@as(u32, 65504)) == 65504); | |
| 845 | try testing.expect(__floatunsihf(@as(u32, 65504 + (1 << 4))) == math.inf(f16)); | |
| 846 | } | |
| 847 | ||
| 848 | test "conversion to f32" { | |
| 849 | try testing.expect(__floatunsisf(@as(u32, 0)) == 0.0); | |
| 850 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u32))) != 1.0); | |
| 851 | try testing.expect(__floatsisf(@as(i32, math.minInt(i32))) != 1.0); | |
| 852 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24))) == math.maxInt(u24)); | |
| 853 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 1) == math.maxInt(u24) + 1); // 0x100_0000 - Exact | |
| 854 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 2) == math.maxInt(u24) + 1); // 0x100_0001 - Tie: Rounds down to even | |
| 855 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 3) == math.maxInt(u24) + 3); // 0x100_0002 - Exact | |
| 856 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 4) == math.maxInt(u24) + 5); // 0x100_0003 - Tie: Rounds up to even | |
| 857 | try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 5) == math.maxInt(u24) + 5); // 0x100_0004 - Exact | |
| 858 | } | |
| 859 | ||
| 860 | test "conversion to f80" { | |
| 861 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 862 | ||
| 863 | try testing.expect(floatFromInt(f80, @as(i80, -12)) == -12); | |
| 864 | try testing.expect(@as(u80, @intFromFloat(floatFromInt(f80, @as(u64, math.maxInt(u64)) + 0))) == math.maxInt(u64) + 0); | |
| 865 | try testing.expect(@as(u80, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1))) == math.maxInt(u64) + 1); | |
| 866 | ||
| 867 | try testing.expect(floatFromInt(f80, @as(u32, 0)) == 0.0); | |
| 868 | try testing.expect(floatFromInt(f80, @as(u32, 1)) == 1.0); | |
| 869 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u32, math.maxInt(u24)) + 0))) == math.maxInt(u24)); | |
| 870 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 0))) == math.maxInt(u64)); | |
| 871 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1))) == math.maxInt(u64) + 1); // Exact | |
| 872 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 2))) == math.maxInt(u64) + 1); // Rounds down | |
| 873 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 3))) == math.maxInt(u64) + 3); // Tie - Exact | |
| 874 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 4))) == math.maxInt(u64) + 5); // Rounds up | |
| 875 | ||
| 876 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 0))) == math.maxInt(u65) + 1); // Rounds up | |
| 877 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 1))) == math.maxInt(u65) + 1); // Exact | |
| 878 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 2))) == math.maxInt(u65) + 1); // Rounds down | |
| 879 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 3))) == math.maxInt(u65) + 1); // Tie - Rounds down | |
| 880 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 4))) == math.maxInt(u65) + 5); // Rounds up | |
| 881 | try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 5))) == math.maxInt(u65) + 5); // Exact | |
| 870 | test f16_floatFromInt_u32 { | |
| 871 | try testing.expect(f16_floatFromInt_u32(0) == 0.0); | |
| 872 | try testing.expect(f16_floatFromInt_u32(1) == 1.0); | |
| 873 | try testing.expect(f16_floatFromInt_u32(65504) == 65504); | |
| 874 | try testing.expect(f16_floatFromInt_u32(65504 + (1 << 4)) == math.inf(f16)); | |
| 875 | } | |
| 876 | ||
| 877 | test f80_floatFromInt_u32 { | |
| 878 | try testing.expect(f80_floatFromInt_u32(0) == 0.0); | |
| 879 | try testing.expect(f80_floatFromInt_u32(1) == 1.0); | |
| 880 | try testing.expect(f80_floatFromInt_u32(math.maxInt(u24) + 0) == math.maxInt(u24)); | |
| 881 | } | |
| 882 | ||
| 883 | test f80_floatFromInt_u64 { | |
| 884 | try testing.expect(f80_floatFromInt_u64(math.maxInt(u64) + 0) == math.maxInt(u64) + 0); | |
| 885 | } | |
| 886 | ||
| 887 | test f80_floatFromInt_i128 { | |
| 888 | try testing.expect(f80_floatFromInt_i128(-12) == -12); | |
| 889 | } | |
| 890 | ||
| 891 | test f80_floatFromInt_u128 { | |
| 892 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 1) == math.maxInt(u64) + 1); | |
| 893 | ||
| 894 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 0) == math.maxInt(u64)); | |
| 895 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 1) == math.maxInt(u64) + 1); // Exact | |
| 896 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 2) == math.maxInt(u64) + 1); // Rounds down | |
| 897 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 3) == math.maxInt(u64) + 3); // Tie - Exact | |
| 898 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 4) == math.maxInt(u64) + 5); // Rounds up | |
| 899 | ||
| 900 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 0) == math.maxInt(u65) + 1); // Rounds up | |
| 901 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 1) == math.maxInt(u65) + 1); // Exact | |
| 902 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 2) == math.maxInt(u65) + 1); // Rounds down | |
| 903 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 3) == math.maxInt(u65) + 1); // Tie - Rounds down | |
| 904 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 4) == math.maxInt(u65) + 5); // Rounds up | |
| 905 | try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 5) == math.maxInt(u65) + 5); // Exact | |
| 882 | 906 | } |
lib/compiler_rt/floatdidf.zig deleted-23| ... | ... | @@ -1,23 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 3 | const symbol = compiler_rt.symbol; | |
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 5 | ||
| 6 | comptime { | |
| 7 | if (compiler_rt.want_aeabi) { | |
| 8 | symbol(&__aeabi_l2d, "__aeabi_l2d"); | |
| 9 | } else { | |
| 10 | if (compiler_rt.want_windows_arm_abi) { | |
| 11 | symbol(&__floatdidf, "__i64tod"); | |
| 12 | } | |
| 13 | symbol(&__floatdidf, "__floatdidf"); | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | pub fn __floatdidf(a: i64) callconv(.c) f64 { | |
| 18 | return floatFromInt(f64, a); | |
| 19 | } | |
| 20 | ||
| 21 | fn __aeabi_l2d(a: i64) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 22 | return floatFromInt(f64, a); | |
| 23 | } |
lib/compiler_rt/floatdihf.zig deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 3 | ||
| 4 | comptime { | |
| 5 | symbol(&__floatdihf, "__floatdihf"); | |
| 6 | } | |
| 7 | ||
| 8 | fn __floatdihf(a: i64) callconv(.c) f16 { | |
| 9 | return floatFromInt(f16, a); | |
| 10 | } |
lib/compiler_rt/floatdisf.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_l2f, "__aeabi_l2f"); | |
| 8 | } else { | |
| 9 | if (compiler_rt.want_windows_arm_abi) { | |
| 10 | symbol(&__floatdisf, "__i64tos"); | |
| 11 | } | |
| 12 | symbol(&__floatdisf, "__floatdisf"); | |
| 13 | } | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __floatdisf(a: i64) callconv(.c) f32 { | |
| 17 | return floatFromInt(f32, a); | |
| 18 | } | |
| 19 | ||
| 20 | fn __aeabi_l2f(a: i64) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 21 | return floatFromInt(f32, a); | |
| 22 | } |
lib/compiler_rt/floatditf.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) { | |
| 7 | symbol(&__floatditf, "__floatdikf"); | |
| 8 | } else if (compiler_rt.want_sparc64_abi) { | |
| 9 | symbol(&_Qp_xtoq, "_Qp_xtoq"); | |
| 10 | } else if (compiler_rt.want_sparc32_abi) { | |
| 11 | symbol(&__floatditf, "_Q_lltoq"); | |
| 12 | } | |
| 13 | symbol(&__floatditf, "__floatditf"); | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __floatditf(a: i64) callconv(.c) f128 { | |
| 17 | return floatFromInt(f128, a); | |
| 18 | } | |
| 19 | ||
| 20 | fn _Qp_xtoq(c: *f128, a: i64) callconv(.c) void { | |
| 21 | c.* = floatFromInt(f128, a); | |
| 22 | } |
lib/compiler_rt/floatdixf.zig deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 3 | ||
| 4 | comptime { | |
| 5 | symbol(&__floatdixf, "__floatdixf"); | |
| 6 | } | |
| 7 | ||
| 8 | fn __floatdixf(a: i64) callconv(.c) f80 { | |
| 9 | return floatFromInt(f80, a); | |
| 10 | } |
lib/compiler_rt/floateidf.zig deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | ||
| 3 | const std = @import("std"); | |
| 4 | ||
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | |
| 6 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 7 | ||
| 8 | comptime { | |
| 9 | symbol(&__floateidf, "__floateidf"); | |
| 10 | } | |
| 11 | ||
| 12 | pub fn __floateidf(a: [*]const u8, bits: usize) callconv(.c) f64 { | |
| 13 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 14 | return floatFromBigInt(f64, .signed, @ptrCast(@alignCast(a[0..byte_size]))); | |
| 15 | } |
lib/compiler_rt/floateihf.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | |
| 6 | ||
| 7 | comptime { | |
| 8 | symbol(&__floateihf, "__floateihf"); | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __floateihf(a: [*]const u8, bits: usize) callconv(.c) f16 { | |
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 13 | return floatFromBigInt(f16, .signed, @ptrCast(@alignCast(a[0..byte_size]))); | |
| 14 | } |
lib/compiler_rt/floateisf.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | |
| 6 | ||
| 7 | comptime { | |
| 8 | symbol(&__floateisf, "__floateisf"); | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __floateisf(a: [*]const u8, bits: usize) callconv(.c) f32 { | |
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 13 | return floatFromBigInt(f32, .signed, @ptrCast(@alignCast(a[0..byte_size]))); | |
| 14 | } |
lib/compiler_rt/floateitf.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | |
| 6 | ||
| 7 | comptime { | |
| 8 | symbol(&__floateitf, "__floateitf"); | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __floateitf(a: [*]const u8, bits: usize) callconv(.c) f128 { | |
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 13 | return floatFromBigInt(f128, .signed, @ptrCast(@alignCast(a[0..byte_size]))); | |
| 14 | } |
lib/compiler_rt/floateixf.zig deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | ||
| 3 | const std = @import("std"); | |
| 4 | ||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 6 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | |
| 7 | ||
| 8 | comptime { | |
| 9 | symbol(&__floateixf, "__floateixf"); | |
| 10 | } | |
| 11 | ||
| 12 | pub fn __floateixf(a: [*]const u8, bits: usize) callconv(.c) f80 { | |
| 13 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 14 | return floatFromBigInt(f80, .signed, @ptrCast(@alignCast(a[0..byte_size]))); | |
| 15 | } |
lib/compiler_rt/floatsidf.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_i2d, "__aeabi_i2d"); | |
| 8 | } else { | |
| 9 | symbol(&__floatsidf, "__floatsidf"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | pub fn __floatsidf(a: i32) callconv(.c) f64 { | |
| 14 | return floatFromInt(f64, a); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_i2d(a: i32) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 18 | return floatFromInt(f64, a); | |
| 19 | } |
lib/compiler_rt/floatsihf.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__floatsihf, "__floatsihf"); | |
| 7 | } | |
| 8 | ||
| 9 | fn __floatsihf(a: i32) callconv(.c) f16 { | |
| 10 | return floatFromInt(f16, a); | |
| 11 | } |
lib/compiler_rt/floatsisf.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_i2f, "__aeabi_i2f"); | |
| 8 | } else { | |
| 9 | symbol(&__floatsisf, "__floatsisf"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | pub fn __floatsisf(a: i32) callconv(.c) f32 { | |
| 14 | return floatFromInt(f32, a); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_i2f(a: i32) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 18 | return floatFromInt(f32, a); | |
| 19 | } |
lib/compiler_rt/floatsitf.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) { | |
| 7 | symbol(&__floatsitf, "__floatsikf"); | |
| 8 | } else if (compiler_rt.want_sparc64_abi) { | |
| 9 | symbol(&_Qp_itoq, "_Qp_itoq"); | |
| 10 | } else if (compiler_rt.want_sparc32_abi) { | |
| 11 | symbol(&__floatsitf, "_Q_itoq"); | |
| 12 | } | |
| 13 | symbol(&__floatsitf, "__floatsitf"); | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __floatsitf(a: i32) callconv(.c) f128 { | |
| 17 | return floatFromInt(f128, a); | |
| 18 | } | |
| 19 | ||
| 20 | fn _Qp_itoq(c: *f128, a: i32) callconv(.c) void { | |
| 21 | c.* = floatFromInt(f128, a); | |
| 22 | } |
lib/compiler_rt/floatsixf.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__floatsixf, "__floatsixf"); | |
| 7 | } | |
| 8 | ||
| 9 | fn __floatsixf(a: i32) callconv(.c) f80 { | |
| 10 | return floatFromInt(f80, a); | |
| 11 | } |
lib/compiler_rt/floattidf.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__floattidf, "__floattidf"); | |
| 7 | } | |
| 8 | ||
| 9 | pub fn __floattidf(a: i128) callconv(.c) f64 { | |
| 10 | return floatFromInt(f64, a); | |
| 11 | } |
lib/compiler_rt/floattihf.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 3 | const symbol = compiler_rt.symbol; | |
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 5 | ||
| 6 | comptime { | |
| 7 | symbol(&__floattihf, "__floattihf"); | |
| 8 | } | |
| 9 | ||
| 10 | pub fn __floattihf(a: i128) callconv(.c) f16 { | |
| 11 | return floatFromInt(f16, a); | |
| 12 | } |
lib/compiler_rt/floattisf.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__floattisf, "__floattisf"); | |
| 7 | } | |
| 8 | ||
| 9 | pub fn __floattisf(a: i128) callconv(.c) f32 { | |
| 10 | return floatFromInt(f32, a); | |
| 11 | } |
lib/compiler_rt/floattitf.zig deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) | |
| 7 | symbol(&__floattitf, "__floattikf"); | |
| 8 | symbol(&__floattitf, "__floattitf"); | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __floattitf(a: i128) callconv(.c) f128 { | |
| 12 | return floatFromInt(f128, a); | |
| 13 | } |
lib/compiler_rt/floattixf.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 3 | const symbol = compiler_rt.symbol; | |
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 5 | ||
| 6 | comptime { | |
| 7 | symbol(&__floattixf, "__floattixf"); | |
| 8 | } | |
| 9 | ||
| 10 | pub fn __floattixf(a: i128) callconv(.c) f80 { | |
| 11 | return floatFromInt(f80, a); | |
| 12 | } |
lib/compiler_rt/floatundidf.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_ul2d, "__aeabi_ul2d"); | |
| 8 | } else { | |
| 9 | if (compiler_rt.want_windows_arm_abi) { | |
| 10 | symbol(&__floatundidf, "__u64tod"); | |
| 11 | } | |
| 12 | symbol(&__floatundidf, "__floatundidf"); | |
| 13 | } | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __floatundidf(a: u64) callconv(.c) f64 { | |
| 17 | return floatFromInt(f64, a); | |
| 18 | } | |
| 19 | ||
| 20 | fn __aeabi_ul2d(a: u64) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 21 | return floatFromInt(f64, a); | |
| 22 | } |
lib/compiler_rt/floatundihf.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__floatundihf, "__floatundihf"); | |
| 7 | } | |
| 8 | ||
| 9 | fn __floatundihf(a: u64) callconv(.c) f16 { | |
| 10 | return floatFromInt(f16, a); | |
| 11 | } |
lib/compiler_rt/floatundisf.zig deleted-23| ... | ... | @@ -1,23 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 3 | const symbol = compiler_rt.symbol; | |
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 5 | ||
| 6 | comptime { | |
| 7 | if (compiler_rt.want_aeabi) { | |
| 8 | symbol(&__aeabi_ul2f, "__aeabi_ul2f"); | |
| 9 | } else { | |
| 10 | if (compiler_rt.want_windows_arm_abi) { | |
| 11 | symbol(&__floatundisf, "__u64tos"); | |
| 12 | } | |
| 13 | symbol(&__floatundisf, "__floatundisf"); | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | pub fn __floatundisf(a: u64) callconv(.c) f32 { | |
| 18 | return floatFromInt(f32, a); | |
| 19 | } | |
| 20 | ||
| 21 | fn __aeabi_ul2f(a: u64) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 22 | return floatFromInt(f32, a); | |
| 23 | } |
lib/compiler_rt/floatunditf.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) { | |
| 7 | symbol(&__floatunditf, "__floatundikf"); | |
| 8 | } else if (compiler_rt.want_sparc64_abi) { | |
| 9 | symbol(&_Qp_uxtoq, "_Qp_uxtoq"); | |
| 10 | } else if (compiler_rt.want_sparc32_abi) { | |
| 11 | @export(&__floatunditf, "_Q_ulltoq"); | |
| 12 | } | |
| 13 | symbol(&__floatunditf, "__floatunditf"); | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __floatunditf(a: u64) callconv(.c) f128 { | |
| 17 | return floatFromInt(f128, a); | |
| 18 | } | |
| 19 | ||
| 20 | fn _Qp_uxtoq(c: *f128, a: u64) callconv(.c) void { | |
| 21 | c.* = floatFromInt(f128, a); | |
| 22 | } |
lib/compiler_rt/floatundixf.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__floatundixf, "__floatundixf"); | |
| 7 | } | |
| 8 | ||
| 9 | fn __floatundixf(a: u64) callconv(.c) f80 { | |
| 10 | return floatFromInt(f80, a); | |
| 11 | } |
lib/compiler_rt/floatuneidf.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | |
| 6 | ||
| 7 | comptime { | |
| 8 | symbol(&__floatuneidf, "__floatuneidf"); | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __floatuneidf(a: [*]const u8, bits: usize) callconv(.c) f64 { | |
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 13 | return floatFromBigInt(f64, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); | |
| 14 | } |
lib/compiler_rt/floatuneihf.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | |
| 6 | ||
| 7 | comptime { | |
| 8 | symbol(&__floatuneihf, "__floatuneihf"); | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __floatuneihf(a: [*]const u8, bits: usize) callconv(.c) f16 { | |
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 13 | return floatFromBigInt(f16, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); | |
| 14 | } |
lib/compiler_rt/floatuneisf.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | |
| 6 | ||
| 7 | comptime { | |
| 8 | symbol(&__floatuneisf, "__floatuneisf"); | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __floatuneisf(a: [*]const u8, bits: usize) callconv(.c) f32 { | |
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 13 | return floatFromBigInt(f32, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); | |
| 14 | } |
lib/compiler_rt/floatuneitf.zig deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | ||
| 3 | const std = @import("std"); | |
| 4 | ||
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 6 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | |
| 7 | ||
| 8 | comptime { | |
| 9 | symbol(&__floatuneitf, "__floatuneitf"); | |
| 10 | } | |
| 11 | ||
| 12 | pub fn __floatuneitf(a: [*]const u8, bits: usize) callconv(.c) f128 { | |
| 13 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 14 | return floatFromBigInt(f128, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); | |
| 15 | } |
lib/compiler_rt/floatuneixf.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; | |
| 6 | ||
| 7 | comptime { | |
| 8 | symbol(&__floatuneixf, "__floatuneixf"); | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __floatuneixf(a: [*]const u8, bits: usize) callconv(.c) f80 { | |
| 12 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 13 | return floatFromBigInt(f80, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); | |
| 14 | } |
lib/compiler_rt/floatunsidf.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_ui2d, "__aeabi_ui2d"); | |
| 8 | } else { | |
| 9 | symbol(&__floatunsidf, "__floatunsidf"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | pub fn __floatunsidf(a: u32) callconv(.c) f64 { | |
| 14 | return floatFromInt(f64, a); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_ui2d(a: u32) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 18 | return floatFromInt(f64, a); | |
| 19 | } |
lib/compiler_rt/floatunsihf.zig deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 3 | ||
| 4 | comptime { | |
| 5 | symbol(&__floatunsihf, "__floatunsihf"); | |
| 6 | } | |
| 7 | ||
| 8 | pub fn __floatunsihf(a: u32) callconv(.c) f16 { | |
| 9 | return floatFromInt(f16, a); | |
| 10 | } |
lib/compiler_rt/floatunsisf.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_ui2f, "__aeabi_ui2f"); | |
| 8 | } else { | |
| 9 | symbol(&__floatunsisf, "__floatunsisf"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | pub fn __floatunsisf(a: u32) callconv(.c) f32 { | |
| 14 | return floatFromInt(f32, a); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_ui2f(a: u32) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 18 | return floatFromInt(f32, a); | |
| 19 | } |
lib/compiler_rt/floatunsitf.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) { | |
| 7 | symbol(&__floatunsitf, "__floatunsikf"); | |
| 8 | } else if (compiler_rt.want_sparc64_abi) { | |
| 9 | symbol(&_Qp_uitoq, "_Qp_uitoq"); | |
| 10 | } else if (compiler_rt.want_sparc32_abi) { | |
| 11 | symbol(&__floatunsitf, "_Q_utoq"); | |
| 12 | } | |
| 13 | symbol(&__floatunsitf, "__floatunsitf"); | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __floatunsitf(a: u32) callconv(.c) f128 { | |
| 17 | return floatFromInt(f128, a); | |
| 18 | } | |
| 19 | ||
| 20 | fn _Qp_uitoq(c: *f128, a: u32) callconv(.c) void { | |
| 21 | c.* = floatFromInt(f128, a); | |
| 22 | } |
lib/compiler_rt/floatunsixf.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__floatunsixf, "__floatunsixf"); | |
| 7 | } | |
| 8 | ||
| 9 | fn __floatunsixf(a: u32) callconv(.c) f80 { | |
| 10 | return floatFromInt(f80, a); | |
| 11 | } |
lib/compiler_rt/floatuntidf.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__floatuntidf, "__floatuntidf"); | |
| 7 | } | |
| 8 | ||
| 9 | pub fn __floatuntidf(a: u128) callconv(.c) f64 { | |
| 10 | return floatFromInt(f64, a); | |
| 11 | } |
lib/compiler_rt/floatuntihf.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__floatuntihf, "__floatuntihf"); | |
| 7 | } | |
| 8 | ||
| 9 | pub fn __floatuntihf(a: u128) callconv(.c) f16 { | |
| 10 | return floatFromInt(f16, a); | |
| 11 | } |
lib/compiler_rt/floatuntisf.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 3 | const symbol = compiler_rt.symbol; | |
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 5 | ||
| 6 | comptime { | |
| 7 | symbol(&__floatuntisf, "__floatuntisf"); | |
| 8 | } | |
| 9 | ||
| 10 | pub fn __floatuntisf(a: u128) callconv(.c) f32 { | |
| 11 | return floatFromInt(f32, a); | |
| 12 | } |
lib/compiler_rt/floatuntitf.zig deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) | |
| 7 | symbol(&__floatuntitf, "__floatuntikf"); | |
| 8 | symbol(&__floatuntitf, "__floatuntitf"); | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __floatuntitf(a: u128) callconv(.c) f128 { | |
| 12 | return floatFromInt(f128, a); | |
| 13 | } |
lib/compiler_rt/floatuntixf.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 3 | const symbol = compiler_rt.symbol; | |
| 4 | const floatFromInt = @import("./float_from_int.zig").floatFromInt; | |
| 5 | ||
| 6 | comptime { | |
| 7 | symbol(&__floatuntixf, "__floatuntixf"); | |
| 8 | } | |
| 9 | ||
| 10 | pub fn __floatuntixf(a: u128) callconv(.c) f80 { | |
| 11 | return floatFromInt(f80, a); | |
| 12 | } |
lib/compiler_rt/floor_ceil.zig+171-151| ... | ... | @@ -15,7 +15,7 @@ const mem = std.mem; |
| 15 | 15 | const expect = std.testing.expect; |
| 16 | 16 | |
| 17 | 17 | const compiler_rt = @import("../compiler_rt.zig"); |
| 18 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 18 | const symbol = compiler_rt.symbol; | |
| 19 | 19 | |
| 20 | 20 | comptime { |
| 21 | 21 | // floor |
| ... | ... | @@ -41,52 +41,92 @@ comptime { |
| 41 | 41 | symbol(&ceill, "ceill"); |
| 42 | 42 | } |
| 43 | 43 | |
| 44 | pub fn __floorh(x: f16) callconv(.c) f16 { | |
| 44 | fn __floorh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 45 | return compiler_rt.f16.toAbi(floor_f16(compiler_rt.f16.fromAbi(x))); | |
| 46 | } | |
| 47 | pub fn floor_f16(x: f16) f16 { | |
| 45 | 48 | return impl(f16, .floor, x); |
| 46 | 49 | } |
| 47 | 50 | |
| 48 | pub fn floorf(x: f32) callconv(.c) f32 { | |
| 51 | fn floorf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 52 | return compiler_rt.f32.toAbi(floor_f32(compiler_rt.f32.fromAbi(x))); | |
| 53 | } | |
| 54 | pub fn floor_f32(x: f32) f32 { | |
| 49 | 55 | return impl(f32, .floor, x); |
| 50 | 56 | } |
| 51 | 57 | |
| 52 | pub fn floor(x: f64) callconv(.c) f64 { | |
| 58 | fn floor(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 59 | return compiler_rt.f64.toAbi(floor_f64(compiler_rt.f64.fromAbi(x))); | |
| 60 | } | |
| 61 | pub fn floor_f64(x: f64) f64 { | |
| 53 | 62 | return impl(f64, .floor, x); |
| 54 | 63 | } |
| 55 | 64 | |
| 56 | pub fn __floorx(x: f80) callconv(.c) f80 { | |
| 65 | fn __floorx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 66 | return compiler_rt.f80.toAbi(floor_f80(compiler_rt.f80.fromAbi(x))); | |
| 67 | } | |
| 68 | pub fn floor_f80(x: f80) f80 { | |
| 57 | 69 | return impl(f80, .floor, x); |
| 58 | 70 | } |
| 59 | 71 | |
| 60 | pub fn floorq(x: f128) callconv(.c) f128 { | |
| 72 | fn floorq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 73 | return compiler_rt.f128.toAbi(floor_f128(compiler_rt.f128.fromAbi(x))); | |
| 74 | } | |
| 75 | pub fn floor_f128(x: f128) f128 { | |
| 61 | 76 | return impl(f128, .floor, x); |
| 62 | 77 | } |
| 63 | 78 | |
| 64 | 79 | pub fn floorl(x: c_longdouble) callconv(.c) c_longdouble { |
| 65 | return impl(std.meta.Float(@bitSizeOf(c_longdouble)), .floor, x); | |
| 80 | switch (@typeInfo(c_longdouble).float.bits) { | |
| 81 | 64 => return floor_f64(x), | |
| 82 | 80 => return floor_f80(x), | |
| 83 | 128 => return floor_f128(x), | |
| 84 | else => comptime unreachable, | |
| 85 | } | |
| 66 | 86 | } |
| 67 | 87 | |
| 68 | pub fn __ceilh(x: f16) callconv(.c) f16 { | |
| 88 | fn __ceilh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 89 | return compiler_rt.f16.toAbi(ceil_f16(compiler_rt.f16.fromAbi(x))); | |
| 90 | } | |
| 91 | pub fn ceil_f16(x: f16) f16 { | |
| 69 | 92 | return impl(f16, .ceil, x); |
| 70 | 93 | } |
| 71 | 94 | |
| 72 | pub fn ceilf(x: f32) callconv(.c) f32 { | |
| 95 | fn ceilf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 96 | return compiler_rt.f32.toAbi(ceil_f32(compiler_rt.f32.fromAbi(x))); | |
| 97 | } | |
| 98 | pub fn ceil_f32(x: f32) f32 { | |
| 73 | 99 | return impl(f32, .ceil, x); |
| 74 | 100 | } |
| 75 | 101 | |
| 76 | pub fn ceil(x: f64) callconv(.c) f64 { | |
| 102 | fn ceil(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 103 | return compiler_rt.f64.toAbi(ceil_f64(compiler_rt.f64.fromAbi(x))); | |
| 104 | } | |
| 105 | pub fn ceil_f64(x: f64) f64 { | |
| 77 | 106 | return impl(f64, .ceil, x); |
| 78 | 107 | } |
| 79 | 108 | |
| 80 | pub fn __ceilx(x: f80) callconv(.c) f80 { | |
| 109 | fn __ceilx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 110 | return compiler_rt.f80.toAbi(ceil_f80(compiler_rt.f80.fromAbi(x))); | |
| 111 | } | |
| 112 | pub fn ceil_f80(x: f80) f80 { | |
| 81 | 113 | return impl(f80, .ceil, x); |
| 82 | 114 | } |
| 83 | 115 | |
| 84 | pub fn ceilq(x: f128) callconv(.c) f128 { | |
| 116 | fn ceilq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 117 | return compiler_rt.f128.toAbi(ceil_f128(compiler_rt.f128.fromAbi(x))); | |
| 118 | } | |
| 119 | pub fn ceil_f128(x: f128) f128 { | |
| 85 | 120 | return impl(f128, .ceil, x); |
| 86 | 121 | } |
| 87 | 122 | |
| 88 | 123 | pub fn ceill(x: c_longdouble) callconv(.c) c_longdouble { |
| 89 | return impl(std.meta.Float(@bitSizeOf(c_longdouble)), .ceil, x); | |
| 124 | switch (@typeInfo(c_longdouble).float.bits) { | |
| 125 | 64 => return ceil_f64(x), | |
| 126 | 80 => return ceil_f80(x), | |
| 127 | 128 => return ceil_f128(x), | |
| 128 | else => comptime unreachable, | |
| 129 | } | |
| 90 | 130 | } |
| 91 | 131 | |
| 92 | 132 | inline fn impl(comptime T: type, comptime op: enum { floor, ceil }, x: T) T { |
| ... | ... | @@ -144,142 +184,122 @@ inline fn impl(comptime T: type, comptime op: enum { floor, ceil }, x: T) T { |
| 144 | 184 | } |
| 145 | 185 | } |
| 146 | 186 | |
| 147 | test "floor16" { | |
| 148 | try expect(__floorh(1.3) == 1.0); | |
| 149 | try expect(__floorh(-1.3) == -2.0); | |
| 150 | try expect(__floorh(0.2) == 0.0); | |
| 151 | } | |
| 152 | ||
| 153 | test "floor32" { | |
| 154 | try expect(floorf(1.3) == 1.0); | |
| 155 | try expect(floorf(-1.3) == -2.0); | |
| 156 | try expect(floorf(0.2) == 0.0); | |
| 157 | } | |
| 158 | ||
| 159 | test "floor64" { | |
| 160 | try expect(floor(1.3) == 1.0); | |
| 161 | try expect(floor(-1.3) == -2.0); | |
| 162 | try expect(floor(0.2) == 0.0); | |
| 163 | } | |
| 164 | ||
| 165 | test "floor80" { | |
| 166 | try expect(__floorx(1.3) == 1.0); | |
| 167 | try expect(__floorx(-1.3) == -2.0); | |
| 168 | try expect(__floorx(0.2) == 0.0); | |
| 169 | } | |
| 170 | ||
| 171 | test "floor128" { | |
| 172 | try expect(floorq(1.3) == 1.0); | |
| 173 | try expect(floorq(-1.3) == -2.0); | |
| 174 | try expect(floorq(0.2) == 0.0); | |
| 175 | } | |
| 176 | ||
| 177 | test "floor16.special" { | |
| 178 | try expect(__floorh(0.0) == 0.0); | |
| 179 | try expect(__floorh(-0.0) == -0.0); | |
| 180 | try expect(math.isPositiveInf(__floorh(math.inf(f16)))); | |
| 181 | try expect(math.isNegativeInf(__floorh(-math.inf(f16)))); | |
| 182 | try expect(math.isNan(__floorh(math.nan(f16)))); | |
| 183 | } | |
| 184 | ||
| 185 | test "floor32.special" { | |
| 186 | try expect(floorf(0.0) == 0.0); | |
| 187 | try expect(floorf(-0.0) == -0.0); | |
| 188 | try expect(math.isPositiveInf(floorf(math.inf(f32)))); | |
| 189 | try expect(math.isNegativeInf(floorf(-math.inf(f32)))); | |
| 190 | try expect(math.isNan(floorf(math.nan(f32)))); | |
| 191 | } | |
| 192 | ||
| 193 | test "floor64.special" { | |
| 194 | try expect(floor(0.0) == 0.0); | |
| 195 | try expect(floor(-0.0) == -0.0); | |
| 196 | try expect(math.isPositiveInf(floor(math.inf(f64)))); | |
| 197 | try expect(math.isNegativeInf(floor(-math.inf(f64)))); | |
| 198 | try expect(math.isNan(floor(math.nan(f64)))); | |
| 199 | } | |
| 200 | ||
| 201 | test "floor80.special" { | |
| 202 | try expect(__floorx(0.0) == 0.0); | |
| 203 | try expect(__floorx(-0.0) == -0.0); | |
| 204 | try expect(math.isPositiveInf(__floorx(math.inf(f80)))); | |
| 205 | try expect(math.isNegativeInf(__floorx(-math.inf(f80)))); | |
| 206 | try expect(math.isNan(__floorx(math.nan(f80)))); | |
| 207 | } | |
| 208 | ||
| 209 | test "floor128.special" { | |
| 210 | try expect(floorq(0.0) == 0.0); | |
| 211 | try expect(floorq(-0.0) == -0.0); | |
| 212 | try expect(math.isPositiveInf(floorq(math.inf(f128)))); | |
| 213 | try expect(math.isNegativeInf(floorq(-math.inf(f128)))); | |
| 214 | try expect(math.isNan(floorq(math.nan(f128)))); | |
| 215 | } | |
| 216 | ||
| 217 | test "ceil16" { | |
| 218 | try expect(__ceilh(1.3) == 2.0); | |
| 219 | try expect(__ceilh(-1.3) == -1.0); | |
| 220 | try expect(__ceilh(0.2) == 1.0); | |
| 221 | } | |
| 222 | ||
| 223 | test "ceil32" { | |
| 224 | try expect(ceilf(1.3) == 2.0); | |
| 225 | try expect(ceilf(-1.3) == -1.0); | |
| 226 | try expect(ceilf(0.2) == 1.0); | |
| 227 | } | |
| 228 | ||
| 229 | test "ceil64" { | |
| 230 | try expect(ceil(1.3) == 2.0); | |
| 231 | try expect(ceil(-1.3) == -1.0); | |
| 232 | try expect(ceil(0.2) == 1.0); | |
| 233 | } | |
| 234 | ||
| 235 | test "ceil80" { | |
| 236 | try expect(__ceilx(1.3) == 2.0); | |
| 237 | try expect(__ceilx(-1.3) == -1.0); | |
| 238 | try expect(__ceilx(0.2) == 1.0); | |
| 239 | } | |
| 240 | ||
| 241 | test "ceil128" { | |
| 242 | try expect(ceilq(1.3) == 2.0); | |
| 243 | try expect(ceilq(-1.3) == -1.0); | |
| 244 | try expect(ceilq(0.2) == 1.0); | |
| 245 | } | |
| 246 | ||
| 247 | test "ceil16.special" { | |
| 248 | try expect(__ceilh(0.0) == 0.0); | |
| 249 | try expect(__ceilh(-0.0) == -0.0); | |
| 250 | try expect(math.isPositiveInf(__ceilh(math.inf(f16)))); | |
| 251 | try expect(math.isNegativeInf(__ceilh(-math.inf(f16)))); | |
| 252 | try expect(math.isNan(__ceilh(math.nan(f16)))); | |
| 253 | } | |
| 254 | ||
| 255 | test "ceil32.special" { | |
| 256 | try expect(ceilf(0.0) == 0.0); | |
| 257 | try expect(ceilf(-0.0) == -0.0); | |
| 258 | try expect(math.isPositiveInf(ceilf(math.inf(f32)))); | |
| 259 | try expect(math.isNegativeInf(ceilf(-math.inf(f32)))); | |
| 260 | try expect(math.isNan(ceilf(math.nan(f32)))); | |
| 261 | } | |
| 262 | ||
| 263 | test "ceil64.special" { | |
| 264 | try expect(ceil(0.0) == 0.0); | |
| 265 | try expect(ceil(-0.0) == -0.0); | |
| 266 | try expect(math.isPositiveInf(ceil(math.inf(f64)))); | |
| 267 | try expect(math.isNegativeInf(ceil(-math.inf(f64)))); | |
| 268 | try expect(math.isNan(ceil(math.nan(f64)))); | |
| 269 | } | |
| 270 | ||
| 271 | test "ceil80.special" { | |
| 272 | try expect(__ceilx(0.0) == 0.0); | |
| 273 | try expect(__ceilx(-0.0) == -0.0); | |
| 274 | try expect(math.isPositiveInf(__ceilx(math.inf(f80)))); | |
| 275 | try expect(math.isNegativeInf(__ceilx(-math.inf(f80)))); | |
| 276 | try expect(math.isNan(__ceilx(math.nan(f80)))); | |
| 277 | } | |
| 278 | ||
| 279 | test "ceil128.special" { | |
| 280 | try expect(ceilq(0.0) == 0.0); | |
| 281 | try expect(ceilq(-0.0) == -0.0); | |
| 282 | try expect(math.isPositiveInf(ceilq(math.inf(f128)))); | |
| 283 | try expect(math.isNegativeInf(ceilq(-math.inf(f128)))); | |
| 284 | try expect(math.isNan(ceilq(math.nan(f128)))); | |
| 187 | test floor_f16 { | |
| 188 | try expect(floor_f16(1.3) == 1.0); | |
| 189 | try expect(floor_f16(-1.3) == -2.0); | |
| 190 | try expect(floor_f16(-0.2) == -1.0); | |
| 191 | try expect(math.isPositiveZero(floor_f16(0.2))); | |
| 192 | try expect(math.isPositiveZero(floor_f16(0.0))); | |
| 193 | try expect(math.isNegativeZero(floor_f16(-0.0))); | |
| 194 | try expect(math.isPositiveInf(floor_f16(math.inf(f16)))); | |
| 195 | try expect(math.isNegativeInf(floor_f16(-math.inf(f16)))); | |
| 196 | try expect(math.isNan(floor_f16(math.nan(f16)))); | |
| 197 | } | |
| 198 | ||
| 199 | test floor_f32 { | |
| 200 | try expect(floor_f32(1.3) == 1.0); | |
| 201 | try expect(floor_f32(-1.3) == -2.0); | |
| 202 | try expect(floor_f32(-0.2) == -1.0); | |
| 203 | try expect(math.isPositiveZero(floor_f32(0.2))); | |
| 204 | try expect(math.isPositiveZero(floor_f32(0.0))); | |
| 205 | try expect(math.isNegativeZero(floor_f32(-0.0))); | |
| 206 | try expect(math.isPositiveInf(floor_f32(math.inf(f32)))); | |
| 207 | try expect(math.isNegativeInf(floor_f32(-math.inf(f32)))); | |
| 208 | try expect(math.isNan(floor_f32(math.nan(f32)))); | |
| 209 | } | |
| 210 | ||
| 211 | test floor_f64 { | |
| 212 | try expect(floor_f64(1.3) == 1.0); | |
| 213 | try expect(floor_f64(-1.3) == -2.0); | |
| 214 | try expect(floor_f64(-0.2) == -1.0); | |
| 215 | try expect(math.isPositiveZero(floor_f64(0.2))); | |
| 216 | try expect(math.isPositiveZero(floor_f64(0.0))); | |
| 217 | try expect(math.isNegativeZero(floor_f64(-0.0))); | |
| 218 | try expect(math.isPositiveInf(floor_f64(math.inf(f64)))); | |
| 219 | try expect(math.isNegativeInf(floor_f64(-math.inf(f64)))); | |
| 220 | try expect(math.isNan(floor_f64(math.nan(f64)))); | |
| 221 | } | |
| 222 | ||
| 223 | test floor_f80 { | |
| 224 | try expect(floor_f80(1.3) == 1.0); | |
| 225 | try expect(floor_f80(-1.3) == -2.0); | |
| 226 | try expect(floor_f80(-0.2) == -1.0); | |
| 227 | try expect(math.isPositiveZero(floor_f80(0.2))); | |
| 228 | try expect(math.isPositiveZero(floor_f80(0.0))); | |
| 229 | try expect(math.isNegativeZero(floor_f80(-0.0))); | |
| 230 | try expect(math.isPositiveInf(floor_f80(math.inf(f80)))); | |
| 231 | try expect(math.isNegativeInf(floor_f80(-math.inf(f80)))); | |
| 232 | try expect(math.isNan(floor_f80(math.nan(f80)))); | |
| 233 | } | |
| 234 | ||
| 235 | test floor_f128 { | |
| 236 | try expect(floor_f128(1.3) == 1.0); | |
| 237 | try expect(floor_f128(-1.3) == -2.0); | |
| 238 | try expect(floor_f128(-0.2) == -1.0); | |
| 239 | try expect(math.isPositiveZero(floor_f128(0.2))); | |
| 240 | try expect(math.isPositiveZero(floor_f128(0.0))); | |
| 241 | try expect(math.isNegativeZero(floor_f128(-0.0))); | |
| 242 | try expect(math.isPositiveInf(floor_f128(math.inf(f128)))); | |
| 243 | try expect(math.isNegativeInf(floor_f128(-math.inf(f128)))); | |
| 244 | try expect(math.isNan(floor_f128(math.nan(f128)))); | |
| 245 | } | |
| 246 | ||
| 247 | test ceil_f16 { | |
| 248 | try expect(ceil_f16(1.3) == 2.0); | |
| 249 | try expect(ceil_f16(-1.3) == -1.0); | |
| 250 | try expect(ceil_f16(0.2) == 1.0); | |
| 251 | try expect(math.isNegativeZero(ceil_f16(-0.2))); | |
| 252 | try expect(math.isPositiveZero(ceil_f16(0.0))); | |
| 253 | try expect(math.isNegativeZero(ceil_f16(-0.0))); | |
| 254 | try expect(math.isPositiveInf(ceil_f16(math.inf(f16)))); | |
| 255 | try expect(math.isNegativeInf(ceil_f16(-math.inf(f16)))); | |
| 256 | try expect(math.isNan(ceil_f16(math.nan(f16)))); | |
| 257 | } | |
| 258 | ||
| 259 | test ceil_f32 { | |
| 260 | try expect(ceil_f32(1.3) == 2.0); | |
| 261 | try expect(ceil_f32(-1.3) == -1.0); | |
| 262 | try expect(ceil_f32(0.2) == 1.0); | |
| 263 | try expect(math.isNegativeZero(ceil_f32(-0.2))); | |
| 264 | try expect(math.isPositiveZero(ceil_f32(0.0))); | |
| 265 | try expect(math.isNegativeZero(ceil_f32(-0.0))); | |
| 266 | try expect(math.isPositiveInf(ceil_f32(math.inf(f32)))); | |
| 267 | try expect(math.isNegativeInf(ceil_f32(-math.inf(f32)))); | |
| 268 | try expect(math.isNan(ceil_f32(math.nan(f32)))); | |
| 269 | } | |
| 270 | ||
| 271 | test ceil_f64 { | |
| 272 | try expect(ceil_f64(1.3) == 2.0); | |
| 273 | try expect(ceil_f64(-1.3) == -1.0); | |
| 274 | try expect(ceil_f64(0.2) == 1.0); | |
| 275 | try expect(math.isNegativeZero(ceil_f64(-0.2))); | |
| 276 | try expect(math.isPositiveZero(ceil_f64(0.0))); | |
| 277 | try expect(math.isNegativeZero(ceil_f64(-0.0))); | |
| 278 | try expect(math.isPositiveInf(ceil_f64(math.inf(f64)))); | |
| 279 | try expect(math.isNegativeInf(ceil_f64(-math.inf(f64)))); | |
| 280 | try expect(math.isNan(ceil_f64(math.nan(f64)))); | |
| 281 | } | |
| 282 | ||
| 283 | test ceil_f80 { | |
| 284 | try expect(ceil_f80(1.3) == 2.0); | |
| 285 | try expect(ceil_f80(-1.3) == -1.0); | |
| 286 | try expect(ceil_f80(0.2) == 1.0); | |
| 287 | try expect(math.isNegativeZero(ceil_f80(-0.2))); | |
| 288 | try expect(math.isPositiveZero(ceil_f80(0.0))); | |
| 289 | try expect(math.isNegativeZero(ceil_f80(-0.0))); | |
| 290 | try expect(math.isPositiveInf(ceil_f80(math.inf(f80)))); | |
| 291 | try expect(math.isNegativeInf(ceil_f80(-math.inf(f80)))); | |
| 292 | try expect(math.isNan(ceil_f80(math.nan(f80)))); | |
| 293 | } | |
| 294 | ||
| 295 | test ceil_f128 { | |
| 296 | try expect(ceil_f128(1.3) == 2.0); | |
| 297 | try expect(ceil_f128(-1.3) == -1.0); | |
| 298 | try expect(ceil_f128(0.2) == 1.0); | |
| 299 | try expect(math.isNegativeZero(ceil_f128(-0.2))); | |
| 300 | try expect(math.isPositiveZero(ceil_f128(0.0))); | |
| 301 | try expect(math.isNegativeZero(ceil_f128(-0.0))); | |
| 302 | try expect(math.isPositiveInf(ceil_f128(math.inf(f128)))); | |
| 303 | try expect(math.isNegativeInf(ceil_f128(-math.inf(f128)))); | |
| 304 | try expect(math.isNan(ceil_f128(math.nan(f128)))); | |
| 285 | 305 | } |
lib/compiler_rt/fma.zig+47-32| ... | ... | @@ -23,12 +23,18 @@ comptime { |
| 23 | 23 | symbol(&fmal, "fmal"); |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | pub fn __fmah(x: f16, y: f16, z: f16) callconv(.c) f16 { | |
| 26 | fn __fmah(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi, z: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 27 | return compiler_rt.f16.toAbi(fma_f16(compiler_rt.f16.fromAbi(x), compiler_rt.f16.fromAbi(y), compiler_rt.f16.fromAbi(z))); | |
| 28 | } | |
| 29 | pub fn fma_f16(x: f16, y: f16, z: f16) f16 { | |
| 27 | 30 | // TODO: more efficient implementation |
| 28 | return @floatCast(fmaf(x, y, z)); | |
| 31 | return @floatCast(fma_f32(x, y, z)); | |
| 29 | 32 | } |
| 30 | 33 | |
| 31 | pub fn fmaf(x: f32, y: f32, z: f32) callconv(.c) f32 { | |
| 34 | fn fmaf(x: compiler_rt.f32.Abi, y: compiler_rt.f32.Abi, z: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 35 | return compiler_rt.f32.toAbi(fma_f32(compiler_rt.f32.fromAbi(x), compiler_rt.f32.fromAbi(y), compiler_rt.f32.fromAbi(z))); | |
| 36 | } | |
| 37 | pub fn fma_f32(x: f32, y: f32, z: f32) f32 { | |
| 32 | 38 | const xy = @as(f64, x) * y; |
| 33 | 39 | const xy_z = xy + z; |
| 34 | 40 | const u = @as(u64, @bitCast(xy_z)); |
| ... | ... | @@ -42,8 +48,11 @@ pub fn fmaf(x: f32, y: f32, z: f32) callconv(.c) f32 { |
| 42 | 48 | } |
| 43 | 49 | } |
| 44 | 50 | |
| 51 | fn fma(x: compiler_rt.f64.Abi, y: compiler_rt.f64.Abi, z: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 52 | return compiler_rt.f64.toAbi(fma_f64(compiler_rt.f64.fromAbi(x), compiler_rt.f64.fromAbi(y), compiler_rt.f64.fromAbi(z))); | |
| 53 | } | |
| 45 | 54 | /// NOTE: Upstream fma.c has been rewritten completely to raise fp exceptions more accurately. |
| 46 | pub fn fma(x: f64, y: f64, z: f64) callconv(.c) f64 { | |
| 55 | pub fn fma_f64(x: f64, y: f64, z: f64) f64 { | |
| 47 | 56 | if (!math.isFinite(x) or !math.isFinite(y)) { |
| 48 | 57 | return x * y + z; |
| 49 | 58 | } |
| ... | ... | @@ -90,11 +99,17 @@ pub fn fma(x: f64, y: f64, z: f64) callconv(.c) f64 { |
| 90 | 99 | } |
| 91 | 100 | } |
| 92 | 101 | |
| 93 | pub fn __fmax(a: f80, b: f80, c: f80) callconv(.c) f80 { | |
| 102 | fn __fmax(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi, c: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 103 | return compiler_rt.f80.toAbi(fma_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b), compiler_rt.f80.fromAbi(c))); | |
| 104 | } | |
| 105 | pub fn fma_f80(a: f80, b: f80, c: f80) f80 { | |
| 94 | 106 | // TODO: more efficient implementation |
| 95 | return @floatCast(fmaq(a, b, c)); | |
| 107 | return @floatCast(fma_f128(a, b, c)); | |
| 96 | 108 | } |
| 97 | 109 | |
| 110 | fn fmaq(x: compiler_rt.f128.Abi, y: compiler_rt.f128.Abi, z: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 111 | return compiler_rt.f128.toAbi(fma_f128(compiler_rt.f128.fromAbi(x), compiler_rt.f128.fromAbi(y), compiler_rt.f128.fromAbi(z))); | |
| 112 | } | |
| 98 | 113 | /// Fused multiply-add: Compute x * y + z with a single rounding error. |
| 99 | 114 | /// |
| 100 | 115 | /// We use scaling to avoid overflow/underflow, along with the |
| ... | ... | @@ -102,7 +117,7 @@ pub fn __fmax(a: f80, b: f80, c: f80) callconv(.c) f80 { |
| 102 | 117 | /// |
| 103 | 118 | /// Dekker, T. A Floating-Point Technique for Extending the |
| 104 | 119 | /// Available Precision. Numer. Math. 18, 224-242 (1971). |
| 105 | pub fn fmaq(x: f128, y: f128, z: f128) callconv(.c) f128 { | |
| 120 | pub fn fma_f128(x: f128, y: f128, z: f128) f128 { | |
| 106 | 121 | if (!math.isFinite(x) or !math.isFinite(y)) { |
| 107 | 122 | return x * y + z; |
| 108 | 123 | } |
| ... | ... | @@ -151,10 +166,10 @@ pub fn fmaq(x: f128, y: f128, z: f128) callconv(.c) f128 { |
| 151 | 166 | |
| 152 | 167 | pub fn fmal(x: c_longdouble, y: c_longdouble, z: c_longdouble) callconv(.c) c_longdouble { |
| 153 | 168 | switch (@typeInfo(c_longdouble).float.bits) { |
| 154 | 64 => return fma(x, y, z), | |
| 155 | 80 => return __fmax(x, y, z), | |
| 156 | 128 => return fmaq(x, y, z), | |
| 157 | else => @compileError("unreachable"), | |
| 169 | 64 => return fma_f64(x, y, z), | |
| 170 | 80 => return fma_f80(x, y, z), | |
| 171 | 128 => return fma_f128(x, y, z), | |
| 172 | else => comptime unreachable, | |
| 158 | 173 | } |
| 159 | 174 | } |
| 160 | 175 | |
| ... | ... | @@ -316,35 +331,35 @@ fn dd_mul128(a: f128, b: f128) dd128 { |
| 316 | 331 | test "32" { |
| 317 | 332 | const epsilon = 0.000001; |
| 318 | 333 | |
| 319 | try expect(math.approxEqAbs(f32, fmaf(0.0, 5.0, 9.124), 9.124, epsilon)); | |
| 320 | try expect(math.approxEqAbs(f32, fmaf(0.2, 5.0, 9.124), 10.124, epsilon)); | |
| 321 | try expect(math.approxEqAbs(f32, fmaf(0.8923, 5.0, 9.124), 13.5855, epsilon)); | |
| 322 | try expect(math.approxEqAbs(f32, fmaf(1.5, 5.0, 9.124), 16.624, epsilon)); | |
| 323 | try expect(math.approxEqAbs(f32, fmaf(37.45, 5.0, 9.124), 196.374004, epsilon)); | |
| 324 | try expect(math.approxEqAbs(f32, fmaf(89.123, 5.0, 9.124), 454.739005, epsilon)); | |
| 325 | try expect(math.approxEqAbs(f32, fmaf(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); | |
| 334 | try expect(math.approxEqAbs(f32, fma_f32(0.0, 5.0, 9.124), 9.124, epsilon)); | |
| 335 | try expect(math.approxEqAbs(f32, fma_f32(0.2, 5.0, 9.124), 10.124, epsilon)); | |
| 336 | try expect(math.approxEqAbs(f32, fma_f32(0.8923, 5.0, 9.124), 13.5855, epsilon)); | |
| 337 | try expect(math.approxEqAbs(f32, fma_f32(1.5, 5.0, 9.124), 16.624, epsilon)); | |
| 338 | try expect(math.approxEqAbs(f32, fma_f32(37.45, 5.0, 9.124), 196.374004, epsilon)); | |
| 339 | try expect(math.approxEqAbs(f32, fma_f32(89.123, 5.0, 9.124), 454.739005, epsilon)); | |
| 340 | try expect(math.approxEqAbs(f32, fma_f32(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); | |
| 326 | 341 | } |
| 327 | 342 | |
| 328 | 343 | test "64" { |
| 329 | 344 | const epsilon = 0.000001; |
| 330 | 345 | |
| 331 | try expect(math.approxEqAbs(f64, fma(0.0, 5.0, 9.124), 9.124, epsilon)); | |
| 332 | try expect(math.approxEqAbs(f64, fma(0.2, 5.0, 9.124), 10.124, epsilon)); | |
| 333 | try expect(math.approxEqAbs(f64, fma(0.8923, 5.0, 9.124), 13.5855, epsilon)); | |
| 334 | try expect(math.approxEqAbs(f64, fma(1.5, 5.0, 9.124), 16.624, epsilon)); | |
| 335 | try expect(math.approxEqAbs(f64, fma(37.45, 5.0, 9.124), 196.374, epsilon)); | |
| 336 | try expect(math.approxEqAbs(f64, fma(89.123, 5.0, 9.124), 454.739, epsilon)); | |
| 337 | try expect(math.approxEqAbs(f64, fma(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); | |
| 346 | try expect(math.approxEqAbs(f64, fma_f64(0.0, 5.0, 9.124), 9.124, epsilon)); | |
| 347 | try expect(math.approxEqAbs(f64, fma_f64(0.2, 5.0, 9.124), 10.124, epsilon)); | |
| 348 | try expect(math.approxEqAbs(f64, fma_f64(0.8923, 5.0, 9.124), 13.5855, epsilon)); | |
| 349 | try expect(math.approxEqAbs(f64, fma_f64(1.5, 5.0, 9.124), 16.624, epsilon)); | |
| 350 | try expect(math.approxEqAbs(f64, fma_f64(37.45, 5.0, 9.124), 196.374, epsilon)); | |
| 351 | try expect(math.approxEqAbs(f64, fma_f64(89.123, 5.0, 9.124), 454.739, epsilon)); | |
| 352 | try expect(math.approxEqAbs(f64, fma_f64(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); | |
| 338 | 353 | } |
| 339 | 354 | |
| 340 | 355 | test "128" { |
| 341 | 356 | const epsilon = 0.000001; |
| 342 | 357 | |
| 343 | try expect(math.approxEqAbs(f128, fmaq(0.0, 5.0, 9.124), 9.124, epsilon)); | |
| 344 | try expect(math.approxEqAbs(f128, fmaq(0.2, 5.0, 9.124), 10.124, epsilon)); | |
| 345 | try expect(math.approxEqAbs(f128, fmaq(0.8923, 5.0, 9.124), 13.5855, epsilon)); | |
| 346 | try expect(math.approxEqAbs(f128, fmaq(1.5, 5.0, 9.124), 16.624, epsilon)); | |
| 347 | try expect(math.approxEqAbs(f128, fmaq(37.45, 5.0, 9.124), 196.374, epsilon)); | |
| 348 | try expect(math.approxEqAbs(f128, fmaq(89.123, 5.0, 9.124), 454.739, epsilon)); | |
| 349 | try expect(math.approxEqAbs(f128, fmaq(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); | |
| 358 | try expect(math.approxEqAbs(f128, fma_f128(0.0, 5.0, 9.124), 9.124, epsilon)); | |
| 359 | try expect(math.approxEqAbs(f128, fma_f128(0.2, 5.0, 9.124), 10.124, epsilon)); | |
| 360 | try expect(math.approxEqAbs(f128, fma_f128(0.8923, 5.0, 9.124), 13.5855, epsilon)); | |
| 361 | try expect(math.approxEqAbs(f128, fma_f128(1.5, 5.0, 9.124), 16.624, epsilon)); | |
| 362 | try expect(math.approxEqAbs(f128, fma_f128(37.45, 5.0, 9.124), 196.374, epsilon)); | |
| 363 | try expect(math.approxEqAbs(f128, fma_f128(89.123, 5.0, 9.124), 454.739, epsilon)); | |
| 364 | try expect(math.approxEqAbs(f128, fma_f128(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); | |
| 350 | 365 | } |
lib/compiler_rt/fmax.zig+24-9| ... | ... | @@ -17,32 +17,47 @@ comptime { |
| 17 | 17 | symbol(&fmaxl, "fmaxl"); |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | pub fn __fmaxh(x: f16, y: f16) callconv(.c) f16 { | |
| 20 | fn __fmaxh(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 21 | return compiler_rt.f16.toAbi(fmax_f16(compiler_rt.f16.fromAbi(x), compiler_rt.f16.fromAbi(y))); | |
| 22 | } | |
| 23 | pub fn fmax_f16(x: f16, y: f16) f16 { | |
| 21 | 24 | return generic_fmax(f16, x, y); |
| 22 | 25 | } |
| 23 | 26 | |
| 24 | pub fn fmaxf(x: f32, y: f32) callconv(.c) f32 { | |
| 27 | fn fmaxf(x: compiler_rt.f32.Abi, y: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 28 | return compiler_rt.f32.toAbi(fmax_f32(compiler_rt.f32.fromAbi(x), compiler_rt.f32.fromAbi(y))); | |
| 29 | } | |
| 30 | pub fn fmax_f32(x: f32, y: f32) f32 { | |
| 25 | 31 | return generic_fmax(f32, x, y); |
| 26 | 32 | } |
| 27 | 33 | |
| 28 | pub fn fmax(x: f64, y: f64) callconv(.c) f64 { | |
| 34 | fn fmax(x: compiler_rt.f64.Abi, y: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 35 | return compiler_rt.f64.toAbi(fmax_f64(compiler_rt.f64.fromAbi(x), compiler_rt.f64.fromAbi(y))); | |
| 36 | } | |
| 37 | pub fn fmax_f64(x: f64, y: f64) f64 { | |
| 29 | 38 | return generic_fmax(f64, x, y); |
| 30 | 39 | } |
| 31 | 40 | |
| 32 | pub fn __fmaxx(x: f80, y: f80) callconv(.c) f80 { | |
| 41 | fn __fmaxx(x: compiler_rt.f80.Abi, y: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 42 | return compiler_rt.f80.toAbi(fmax_f80(compiler_rt.f80.fromAbi(x), compiler_rt.f80.fromAbi(y))); | |
| 43 | } | |
| 44 | pub fn fmax_f80(x: f80, y: f80) f80 { | |
| 33 | 45 | return generic_fmax(f80, x, y); |
| 34 | 46 | } |
| 35 | 47 | |
| 36 | pub fn fmaxq(x: f128, y: f128) callconv(.c) f128 { | |
| 48 | fn fmaxq(x: compiler_rt.f128.Abi, y: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 49 | return compiler_rt.f128.toAbi(fmax_f128(compiler_rt.f128.fromAbi(x), compiler_rt.f128.fromAbi(y))); | |
| 50 | } | |
| 51 | pub fn fmax_f128(x: f128, y: f128) f128 { | |
| 37 | 52 | return generic_fmax(f128, x, y); |
| 38 | 53 | } |
| 39 | 54 | |
| 40 | 55 | pub fn fmaxl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble { |
| 41 | 56 | switch (@typeInfo(c_longdouble).float.bits) { |
| 42 | 64 => return fmax(x, y), | |
| 43 | 80 => return __fmaxx(x, y), | |
| 44 | 128 => return fmaxq(x, y), | |
| 45 | else => @compileError("unreachable"), | |
| 57 | 64 => return fmax_f64(x, y), | |
| 58 | 80 => return fmax_f80(x, y), | |
| 59 | 128 => return fmax_f128(x, y), | |
| 60 | else => comptime unreachable, | |
| 46 | 61 | } |
| 47 | 62 | } |
| 48 | 63 |
lib/compiler_rt/fmin.zig+24-9| ... | ... | @@ -17,32 +17,47 @@ comptime { |
| 17 | 17 | symbol(&fminl, "fminl"); |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | pub fn __fminh(x: f16, y: f16) callconv(.c) f16 { | |
| 20 | fn __fminh(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 21 | return compiler_rt.f16.toAbi(fmin_f16(compiler_rt.f16.fromAbi(x), compiler_rt.f16.fromAbi(y))); | |
| 22 | } | |
| 23 | pub fn fmin_f16(x: f16, y: f16) f16 { | |
| 21 | 24 | return generic_fmin(f16, x, y); |
| 22 | 25 | } |
| 23 | 26 | |
| 24 | pub fn fminf(x: f32, y: f32) callconv(.c) f32 { | |
| 27 | fn fminf(x: compiler_rt.f32.Abi, y: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 28 | return compiler_rt.f32.toAbi(fmin_f32(compiler_rt.f32.fromAbi(x), compiler_rt.f32.fromAbi(y))); | |
| 29 | } | |
| 30 | pub fn fmin_f32(x: f32, y: f32) f32 { | |
| 25 | 31 | return generic_fmin(f32, x, y); |
| 26 | 32 | } |
| 27 | 33 | |
| 28 | pub fn fmin(x: f64, y: f64) callconv(.c) f64 { | |
| 34 | fn fmin(x: compiler_rt.f64.Abi, y: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 35 | return compiler_rt.f64.toAbi(fmin_f64(compiler_rt.f64.fromAbi(x), compiler_rt.f64.fromAbi(y))); | |
| 36 | } | |
| 37 | pub fn fmin_f64(x: f64, y: f64) f64 { | |
| 29 | 38 | return generic_fmin(f64, x, y); |
| 30 | 39 | } |
| 31 | 40 | |
| 32 | pub fn __fminx(x: f80, y: f80) callconv(.c) f80 { | |
| 41 | fn __fminx(x: compiler_rt.f80.Abi, y: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 42 | return compiler_rt.f80.toAbi(fmin_f80(compiler_rt.f80.fromAbi(x), compiler_rt.f80.fromAbi(y))); | |
| 43 | } | |
| 44 | pub fn fmin_f80(x: f80, y: f80) f80 { | |
| 33 | 45 | return generic_fmin(f80, x, y); |
| 34 | 46 | } |
| 35 | 47 | |
| 36 | pub fn fminq(x: f128, y: f128) callconv(.c) f128 { | |
| 48 | fn fminq(x: compiler_rt.f128.Abi, y: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 49 | return compiler_rt.f128.toAbi(fmin_f128(compiler_rt.f128.fromAbi(x), compiler_rt.f128.fromAbi(y))); | |
| 50 | } | |
| 51 | pub fn fmin_f128(x: f128, y: f128) f128 { | |
| 37 | 52 | return generic_fmin(f128, x, y); |
| 38 | 53 | } |
| 39 | 54 | |
| 40 | 55 | pub fn fminl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble { |
| 41 | 56 | switch (@typeInfo(c_longdouble).float.bits) { |
| 42 | 64 => return fmin(x, y), | |
| 43 | 80 => return __fminx(x, y), | |
| 44 | 128 => return fminq(x, y), | |
| 45 | else => @compileError("unreachable"), | |
| 57 | 64 => return fmin_f64(x, y), | |
| 58 | 80 => return fmin_f80(x, y), | |
| 59 | 128 => return fmin_f128(x, y), | |
| 60 | else => comptime unreachable, | |
| 46 | 61 | } |
| 47 | 62 | } |
| 48 | 63 |
lib/compiler_rt/fmod.zig+49-34| ... | ... | @@ -19,22 +19,34 @@ comptime { |
| 19 | 19 | symbol(&fmodl, "fmodl"); |
| 20 | 20 | } |
| 21 | 21 | |
| 22 | pub fn __fmodh(x: f16, y: f16) callconv(.c) f16 { | |
| 22 | fn __fmodh(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 23 | return compiler_rt.f16.toAbi(fmod_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); | |
| 24 | } | |
| 25 | pub fn fmod_f16(x: f16, y: f16) f16 { | |
| 23 | 26 | // TODO: more efficient implementation |
| 24 | return @floatCast(fmodf(x, y)); | |
| 27 | return @floatCast(fmod_f32(x, y)); | |
| 25 | 28 | } |
| 26 | 29 | |
| 27 | pub fn fmodf(x: f32, y: f32) callconv(.c) f32 { | |
| 30 | fn fmodf(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 31 | return compiler_rt.f32.toAbi(fmod_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); | |
| 32 | } | |
| 33 | pub fn fmod_f32(x: f32, y: f32) f32 { | |
| 28 | 34 | return generic_fmod(f32, x, y); |
| 29 | 35 | } |
| 30 | 36 | |
| 31 | pub fn fmod(x: f64, y: f64) callconv(.c) f64 { | |
| 37 | fn fmod(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 38 | return compiler_rt.f64.toAbi(fmod_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); | |
| 39 | } | |
| 40 | pub fn fmod_f64(x: f64, y: f64) f64 { | |
| 32 | 41 | return generic_fmod(f64, x, y); |
| 33 | 42 | } |
| 34 | 43 | |
| 44 | fn __fmodx(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 45 | return compiler_rt.f80.toAbi(fmod_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); | |
| 46 | } | |
| 35 | 47 | /// fmodx - floating modulo large, returns the remainder of division for f80 types |
| 36 | 48 | /// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits |
| 37 | pub fn __fmodx(a: f80, b: f80) callconv(.c) f80 { | |
| 49 | pub fn fmod_f80(a: f80, b: f80) f80 { | |
| 38 | 50 | const T = f80; |
| 39 | 51 | const Z = @Int(.unsigned, @bitSizeOf(T)); |
| 40 | 52 | |
| ... | ... | @@ -130,9 +142,12 @@ pub fn __fmodx(a: f80, b: f80) callconv(.c) f80 { |
| 130 | 142 | } |
| 131 | 143 | } |
| 132 | 144 | |
| 145 | fn fmodq(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 146 | return compiler_rt.f128.toAbi(fmod_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); | |
| 147 | } | |
| 133 | 148 | /// fmodq - floating modulo large, returns the remainder of division for f128 types |
| 134 | 149 | /// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits |
| 135 | pub fn fmodq(a: f128, b: f128) callconv(.c) f128 { | |
| 150 | pub fn fmod_f128(a: f128, b: f128) f128 { | |
| 136 | 151 | var amod = a; |
| 137 | 152 | var bmod = b; |
| 138 | 153 | const aPtr_u64: [*]u64 = @ptrCast(&amod); |
| ... | ... | @@ -251,10 +266,10 @@ pub fn fmodq(a: f128, b: f128) callconv(.c) f128 { |
| 251 | 266 | |
| 252 | 267 | pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.c) c_longdouble { |
| 253 | 268 | switch (@typeInfo(c_longdouble).float.bits) { |
| 254 | 64 => return fmod(a, b), | |
| 255 | 80 => return __fmodx(a, b), | |
| 256 | 128 => return fmodq(a, b), | |
| 257 | else => @compileError("unreachable"), | |
| 269 | 64 => return fmod_f64(a, b), | |
| 270 | 80 => return fmod_f80(a, b), | |
| 271 | 128 => return fmod_f128(a, b), | |
| 272 | else => comptime unreachable, | |
| 258 | 273 | } |
| 259 | 274 | } |
| 260 | 275 | |
| ... | ... | @@ -342,42 +357,42 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T { |
| 342 | 357 | return @bitCast(ux); |
| 343 | 358 | } |
| 344 | 359 | |
| 345 | test "fmodf" { | |
| 360 | test fmod_f32 { | |
| 346 | 361 | const nan_val = math.nan(f32); |
| 347 | 362 | const inf_val = math.inf(f32); |
| 348 | 363 | |
| 349 | try std.testing.expect(math.isNan(fmodf(nan_val, 1.0))); | |
| 350 | try std.testing.expect(math.isNan(fmodf(1.0, nan_val))); | |
| 351 | try std.testing.expect(math.isNan(fmodf(inf_val, 1.0))); | |
| 352 | try std.testing.expect(math.isNan(fmodf(0.0, 0.0))); | |
| 353 | try std.testing.expect(math.isNan(fmodf(1.0, 0.0))); | |
| 364 | try std.testing.expect(math.isNan(fmod_f32(nan_val, 1.0))); | |
| 365 | try std.testing.expect(math.isNan(fmod_f32(1.0, nan_val))); | |
| 366 | try std.testing.expect(math.isNan(fmod_f32(inf_val, 1.0))); | |
| 367 | try std.testing.expect(math.isNan(fmod_f32(0.0, 0.0))); | |
| 368 | try std.testing.expect(math.isNan(fmod_f32(1.0, 0.0))); | |
| 354 | 369 | |
| 355 | try std.testing.expectEqual(@as(f32, 0.0), fmodf(0.0, 2.0)); | |
| 356 | try std.testing.expectEqual(@as(f32, -0.0), fmodf(-0.0, 2.0)); | |
| 370 | try std.testing.expectEqual(@as(f32, 0.0), fmod_f32(0.0, 2.0)); | |
| 371 | try std.testing.expectEqual(@as(f32, -0.0), fmod_f32(-0.0, 2.0)); | |
| 357 | 372 | |
| 358 | try std.testing.expectEqual(@as(f32, -2.0), fmodf(-32.0, 10.0)); | |
| 359 | try std.testing.expectEqual(@as(f32, -2.0), fmodf(-32.0, -10.0)); | |
| 360 | try std.testing.expectEqual(@as(f32, 2.0), fmodf(32.0, 10.0)); | |
| 361 | try std.testing.expectEqual(@as(f32, 2.0), fmodf(32.0, -10.0)); | |
| 373 | try std.testing.expectEqual(@as(f32, -2.0), fmod_f32(-32.0, 10.0)); | |
| 374 | try std.testing.expectEqual(@as(f32, -2.0), fmod_f32(-32.0, -10.0)); | |
| 375 | try std.testing.expectEqual(@as(f32, 2.0), fmod_f32(32.0, 10.0)); | |
| 376 | try std.testing.expectEqual(@as(f32, 2.0), fmod_f32(32.0, -10.0)); | |
| 362 | 377 | } |
| 363 | 378 | |
| 364 | test "fmod" { | |
| 379 | test fmod_f64 { | |
| 365 | 380 | const nan_val = math.nan(f64); |
| 366 | 381 | const inf_val = math.inf(f64); |
| 367 | 382 | |
| 368 | try std.testing.expect(math.isNan(fmod(nan_val, 1.0))); | |
| 369 | try std.testing.expect(math.isNan(fmod(1.0, nan_val))); | |
| 370 | try std.testing.expect(math.isNan(fmod(inf_val, 1.0))); | |
| 371 | try std.testing.expect(math.isNan(fmod(0.0, 0.0))); | |
| 372 | try std.testing.expect(math.isNan(fmod(1.0, 0.0))); | |
| 383 | try std.testing.expect(math.isNan(fmod_f64(nan_val, 1.0))); | |
| 384 | try std.testing.expect(math.isNan(fmod_f64(1.0, nan_val))); | |
| 385 | try std.testing.expect(math.isNan(fmod_f64(inf_val, 1.0))); | |
| 386 | try std.testing.expect(math.isNan(fmod_f64(0.0, 0.0))); | |
| 387 | try std.testing.expect(math.isNan(fmod_f64(1.0, 0.0))); | |
| 373 | 388 | |
| 374 | try std.testing.expectEqual(@as(f64, 0.0), fmod(0.0, 2.0)); | |
| 375 | try std.testing.expectEqual(@as(f64, -0.0), fmod(-0.0, 2.0)); | |
| 389 | try std.testing.expectEqual(@as(f64, 0.0), fmod_f64(0.0, 2.0)); | |
| 390 | try std.testing.expectEqual(@as(f64, -0.0), fmod_f64(-0.0, 2.0)); | |
| 376 | 391 | |
| 377 | try std.testing.expectEqual(@as(f64, -2.0), fmod(-32.0, 10.0)); | |
| 378 | try std.testing.expectEqual(@as(f64, -2.0), fmod(-32.0, -10.0)); | |
| 379 | try std.testing.expectEqual(@as(f64, 2.0), fmod(32.0, 10.0)); | |
| 380 | try std.testing.expectEqual(@as(f64, 2.0), fmod(32.0, -10.0)); | |
| 392 | try std.testing.expectEqual(@as(f64, -2.0), fmod_f64(-32.0, 10.0)); | |
| 393 | try std.testing.expectEqual(@as(f64, -2.0), fmod_f64(-32.0, -10.0)); | |
| 394 | try std.testing.expectEqual(@as(f64, 2.0), fmod_f64(32.0, 10.0)); | |
| 395 | try std.testing.expectEqual(@as(f64, 2.0), fmod_f64(32.0, -10.0)); | |
| 381 | 396 | } |
| 382 | 397 | |
| 383 | 398 | test { |
lib/compiler_rt/fmodq_test.zig+32-32| ... | ... | @@ -1,52 +1,52 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | const fmod = @import("fmod.zig"); | |
| 2 | const fmod_f128 = @import("fmod.zig").fmod_f128; | |
| 3 | 3 | const testing = std.testing; |
| 4 | 4 | |
| 5 | fn test_fmodq(a: f128, b: f128, exp: f128) !void { | |
| 6 | const res = fmod.fmodq(a, b); | |
| 5 | fn test_fmod_f128(a: f128, b: f128, exp: f128) !void { | |
| 6 | const res = fmod_f128(a, b); | |
| 7 | 7 | try testing.expect(exp == res); |
| 8 | 8 | } |
| 9 | 9 | |
| 10 | fn test_fmodq_nans() !void { | |
| 11 | try testing.expect(std.math.isNan(fmod.fmodq(1.0, std.math.nan(f128)))); | |
| 12 | try testing.expect(std.math.isNan(fmod.fmodq(1.0, -std.math.nan(f128)))); | |
| 13 | try testing.expect(std.math.isNan(fmod.fmodq(std.math.nan(f128), 1.0))); | |
| 14 | try testing.expect(std.math.isNan(fmod.fmodq(-std.math.nan(f128), 1.0))); | |
| 10 | fn test_fmod_f128_nans() !void { | |
| 11 | try testing.expect(std.math.isNan(fmod_f128(1.0, std.math.nan(f128)))); | |
| 12 | try testing.expect(std.math.isNan(fmod_f128(1.0, -std.math.nan(f128)))); | |
| 13 | try testing.expect(std.math.isNan(fmod_f128(std.math.nan(f128), 1.0))); | |
| 14 | try testing.expect(std.math.isNan(fmod_f128(-std.math.nan(f128), 1.0))); | |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | fn test_fmodq_infs() !void { | |
| 18 | try testing.expect(fmod.fmodq(1.0, std.math.inf(f128)) == 1.0); | |
| 19 | try testing.expect(fmod.fmodq(1.0, -std.math.inf(f128)) == 1.0); | |
| 20 | try testing.expect(std.math.isNan(fmod.fmodq(std.math.inf(f128), 1.0))); | |
| 21 | try testing.expect(std.math.isNan(fmod.fmodq(-std.math.inf(f128), 1.0))); | |
| 17 | fn test_fmod_f128_infs() !void { | |
| 18 | try testing.expect(fmod_f128(1.0, std.math.inf(f128)) == 1.0); | |
| 19 | try testing.expect(fmod_f128(1.0, -std.math.inf(f128)) == 1.0); | |
| 20 | try testing.expect(std.math.isNan(fmod_f128(std.math.inf(f128), 1.0))); | |
| 21 | try testing.expect(std.math.isNan(fmod_f128(-std.math.inf(f128), 1.0))); | |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | test "fmodq" { | |
| 25 | try test_fmodq(6.8, 4.0, 2.8); | |
| 26 | try test_fmodq(6.8, -4.0, 2.8); | |
| 27 | try test_fmodq(-6.8, 4.0, -2.8); | |
| 28 | try test_fmodq(-6.8, -4.0, -2.8); | |
| 29 | try test_fmodq(3.0, 2.0, 1.0); | |
| 30 | try test_fmodq(-5.0, 3.0, -2.0); | |
| 31 | try test_fmodq(3.0, 2.0, 1.0); | |
| 32 | try test_fmodq(1.0, 2.0, 1.0); | |
| 33 | try test_fmodq(0.0, 1.0, 0.0); | |
| 34 | try test_fmodq(-0.0, 1.0, -0.0); | |
| 35 | try test_fmodq(7046119.0, 5558362.0, 1487757.0); | |
| 36 | try test_fmodq(9010357.0, 1957236.0, 1181413.0); | |
| 37 | try test_fmodq(5192296858534827628530496329220095, 10.0, 5.0); | |
| 38 | try test_fmodq(5192296858534827628530496329220095, 922337203681230954775807, 220474884073715748246157); | |
| 24 | test fmod_f128 { | |
| 25 | try test_fmod_f128(6.8, 4.0, 2.8); | |
| 26 | try test_fmod_f128(6.8, -4.0, 2.8); | |
| 27 | try test_fmod_f128(-6.8, 4.0, -2.8); | |
| 28 | try test_fmod_f128(-6.8, -4.0, -2.8); | |
| 29 | try test_fmod_f128(3.0, 2.0, 1.0); | |
| 30 | try test_fmod_f128(-5.0, 3.0, -2.0); | |
| 31 | try test_fmod_f128(3.0, 2.0, 1.0); | |
| 32 | try test_fmod_f128(1.0, 2.0, 1.0); | |
| 33 | try test_fmod_f128(0.0, 1.0, 0.0); | |
| 34 | try test_fmod_f128(-0.0, 1.0, -0.0); | |
| 35 | try test_fmod_f128(7046119.0, 5558362.0, 1487757.0); | |
| 36 | try test_fmod_f128(9010357.0, 1957236.0, 1181413.0); | |
| 37 | try test_fmod_f128(5192296858534827628530496329220095, 10.0, 5.0); | |
| 38 | try test_fmod_f128(5192296858534827628530496329220095, 922337203681230954775807, 220474884073715748246157); | |
| 39 | 39 | |
| 40 | 40 | // Denormals |
| 41 | 41 | const a1: f128 = 0xedcb34a235253948765432134674p-16494; |
| 42 | 42 | const b1: f128 = 0x5d2e38791cfbc0737402da5a9518p-16494; |
| 43 | 43 | const exp1: f128 = 0x336ec3affb2db8618e4e7d5e1c44p-16494; |
| 44 | try test_fmodq(a1, b1, exp1); | |
| 44 | try test_fmod_f128(a1, b1, exp1); | |
| 45 | 45 | const a2: f128 = 0x0.7654_3210_fdec_ba98_7654_3210_fdecp-16382; |
| 46 | 46 | const b2: f128 = 0x0.0012_fdac_bdef_1234_fdec_3222_1111p-16382; |
| 47 | 47 | const exp2: f128 = 0x0.0001_aecd_9d66_4a6e_67b7_d7d0_a901p-16382; |
| 48 | try test_fmodq(a2, b2, exp2); | |
| 48 | try test_fmod_f128(a2, b2, exp2); | |
| 49 | 49 | |
| 50 | try test_fmodq_nans(); | |
| 51 | try test_fmodq_infs(); | |
| 50 | try test_fmod_f128_nans(); | |
| 51 | try test_fmod_f128_infs(); | |
| 52 | 52 | } |
lib/compiler_rt/fmodx_test.zig+31-31| ... | ... | @@ -1,52 +1,52 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const fmod = @import("fmod.zig"); | |
| 3 | const fmod_f80 = @import("fmod.zig").fmod_f80; | |
| 4 | 4 | const testing = std.testing; |
| 5 | 5 | |
| 6 | fn test_fmodx(a: f80, b: f80, exp: f80) !void { | |
| 7 | const res = fmod.__fmodx(a, b); | |
| 6 | fn test_fmod_f80(a: f80, b: f80, exp: f80) !void { | |
| 7 | const res = fmod_f80(a, b); | |
| 8 | 8 | try testing.expect(exp == res); |
| 9 | 9 | } |
| 10 | 10 | |
| 11 | fn test_fmodx_nans() !void { | |
| 12 | try testing.expect(std.math.isNan(fmod.__fmodx(1.0, std.math.nan(f80)))); | |
| 13 | try testing.expect(std.math.isNan(fmod.__fmodx(1.0, -std.math.nan(f80)))); | |
| 14 | try testing.expect(std.math.isNan(fmod.__fmodx(std.math.nan(f80), 1.0))); | |
| 15 | try testing.expect(std.math.isNan(fmod.__fmodx(-std.math.nan(f80), 1.0))); | |
| 11 | fn test_fmod_f80_nans() !void { | |
| 12 | try testing.expect(std.math.isNan(fmod_f80(1.0, std.math.nan(f80)))); | |
| 13 | try testing.expect(std.math.isNan(fmod_f80(1.0, -std.math.nan(f80)))); | |
| 14 | try testing.expect(std.math.isNan(fmod_f80(std.math.nan(f80), 1.0))); | |
| 15 | try testing.expect(std.math.isNan(fmod_f80(-std.math.nan(f80), 1.0))); | |
| 16 | 16 | } |
| 17 | 17 | |
| 18 | fn test_fmodx_infs() !void { | |
| 19 | try testing.expect(fmod.__fmodx(1.0, std.math.inf(f80)) == 1.0); | |
| 20 | try testing.expect(fmod.__fmodx(1.0, -std.math.inf(f80)) == 1.0); | |
| 21 | try testing.expect(std.math.isNan(fmod.__fmodx(std.math.inf(f80), 1.0))); | |
| 22 | try testing.expect(std.math.isNan(fmod.__fmodx(-std.math.inf(f80), 1.0))); | |
| 18 | fn test_fmod_f80_infs() !void { | |
| 19 | try testing.expect(fmod_f80(1.0, std.math.inf(f80)) == 1.0); | |
| 20 | try testing.expect(fmod_f80(1.0, -std.math.inf(f80)) == 1.0); | |
| 21 | try testing.expect(std.math.isNan(fmod_f80(std.math.inf(f80), 1.0))); | |
| 22 | try testing.expect(std.math.isNan(fmod_f80(-std.math.inf(f80), 1.0))); | |
| 23 | 23 | } |
| 24 | 24 | |
| 25 | test "fmodx" { | |
| 26 | try test_fmodx(6.4, 4.0, 2.4); | |
| 27 | try test_fmodx(6.4, -4.0, 2.4); | |
| 28 | try test_fmodx(-6.4, 4.0, -2.4); | |
| 29 | try test_fmodx(-6.4, -4.0, -2.4); | |
| 30 | try test_fmodx(3.0, 2.0, 1.0); | |
| 31 | try test_fmodx(-5.0, 3.0, -2.0); | |
| 32 | try test_fmodx(3.0, 2.0, 1.0); | |
| 33 | try test_fmodx(1.0, 2.0, 1.0); | |
| 34 | try test_fmodx(0.0, 1.0, 0.0); | |
| 35 | try test_fmodx(-0.0, 1.0, -0.0); | |
| 36 | try test_fmodx(7046119.0, 5558362.0, 1487757.0); | |
| 37 | try test_fmodx(9010357.0, 1957236.0, 1181413.0); | |
| 38 | try test_fmodx(9223372036854775807, 10.0, 7.0); | |
| 25 | test fmod_f80 { | |
| 26 | try test_fmod_f80(6.4, 4.0, 2.4); | |
| 27 | try test_fmod_f80(6.4, -4.0, 2.4); | |
| 28 | try test_fmod_f80(-6.4, 4.0, -2.4); | |
| 29 | try test_fmod_f80(-6.4, -4.0, -2.4); | |
| 30 | try test_fmod_f80(3.0, 2.0, 1.0); | |
| 31 | try test_fmod_f80(-5.0, 3.0, -2.0); | |
| 32 | try test_fmod_f80(3.0, 2.0, 1.0); | |
| 33 | try test_fmod_f80(1.0, 2.0, 1.0); | |
| 34 | try test_fmod_f80(0.0, 1.0, 0.0); | |
| 35 | try test_fmod_f80(-0.0, 1.0, -0.0); | |
| 36 | try test_fmod_f80(7046119.0, 5558362.0, 1487757.0); | |
| 37 | try test_fmod_f80(9010357.0, 1957236.0, 1181413.0); | |
| 38 | try test_fmod_f80(9223372036854775807, 10.0, 7.0); | |
| 39 | 39 | |
| 40 | 40 | // Denormals |
| 41 | 41 | const a1: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381; |
| 42 | 42 | const b1: f80 = 0x0.2e97_1c3c_8e7d_e03ap-16381; |
| 43 | 43 | const exp1: f80 = 0x0.19b7_61d7_fd96_dc30p-16381; |
| 44 | try test_fmodx(a1, b1, exp1); | |
| 44 | try test_fmod_f80(a1, b1, exp1); | |
| 45 | 45 | const a2: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381; |
| 46 | 46 | const b2: f80 = 0x0.0e97_1c3c_8e7d_e03ap-16381; |
| 47 | 47 | const exp2: f80 = 0x0.022c_b86c_a6a3_9ad4p-16381; |
| 48 | try test_fmodx(a2, b2, exp2); | |
| 48 | try test_fmod_f80(a2, b2, exp2); | |
| 49 | 49 | |
| 50 | try test_fmodx_nans(); | |
| 51 | try test_fmodx_infs(); | |
| 50 | try test_fmod_f80_nans(); | |
| 51 | try test_fmod_f80_infs(); | |
| 52 | 52 | } |
lib/compiler_rt/gedf2.zig deleted-35| ... | ... | @@ -1,35 +0,0 @@ |
| 1 | ///! The quoted behavior definitions are from | |
| 2 | ///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const comparef = @import("./comparef.zig"); | |
| 5 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 6 | ||
| 7 | comptime { | |
| 8 | if (compiler_rt.want_aeabi) { | |
| 9 | symbol(&__aeabi_dcmpge, "__aeabi_dcmpge"); | |
| 10 | symbol(&__aeabi_dcmpgt, "__aeabi_dcmpgt"); | |
| 11 | } else { | |
| 12 | symbol(&__gedf2, "__gedf2"); | |
| 13 | symbol(&__gtdf2, "__gtdf2"); | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | /// "These functions return a value greater than or equal to zero if neither | |
| 18 | /// argument is NaN, and a is greater than or equal to b." | |
| 19 | pub fn __gedf2(a: f64, b: f64) callconv(.c) i32 { | |
| 20 | return @backingInt(comparef.cmpf2(f64, comparef.GE, a, b)); | |
| 21 | } | |
| 22 | ||
| 23 | /// "These functions return a value greater than zero if neither argument is NaN, | |
| 24 | /// and a is strictly greater than b." | |
| 25 | pub fn __gtdf2(a: f64, b: f64) callconv(.c) i32 { | |
| 26 | return __gedf2(a, b); | |
| 27 | } | |
| 28 | ||
| 29 | fn __aeabi_dcmpge(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 30 | return @intFromBool(comparef.cmpf2(f64, comparef.GE, a, b) != .Less); | |
| 31 | } | |
| 32 | ||
| 33 | fn __aeabi_dcmpgt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 34 | return @intFromBool(comparef.cmpf2(f64, comparef.GE, a, b) == .Greater); | |
| 35 | } |
lib/compiler_rt/gehf2.zig deleted-21| ... | ... | @@ -1,21 +0,0 @@ |
| 1 | ///! The quoted behavior definitions are from | |
| 2 | ///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | const comparef = @import("./comparef.zig"); | |
| 5 | ||
| 6 | comptime { | |
| 7 | symbol(&__gehf2, "__gehf2"); | |
| 8 | symbol(&__gthf2, "__gthf2"); | |
| 9 | } | |
| 10 | ||
| 11 | /// "These functions return a value greater than or equal to zero if neither | |
| 12 | /// argument is NaN, and a is greater than or equal to b." | |
| 13 | pub fn __gehf2(a: f16, b: f16) callconv(.c) i32 { | |
| 14 | return @backingInt(comparef.cmpf2(f16, comparef.GE, a, b)); | |
| 15 | } | |
| 16 | ||
| 17 | /// "These functions return a value greater than zero if neither argument is NaN, | |
| 18 | /// and a is strictly greater than b." | |
| 19 | pub fn __gthf2(a: f16, b: f16) callconv(.c) i32 { | |
| 20 | return __gehf2(a, b); | |
| 21 | } |
lib/compiler_rt/gesf2.zig deleted-35| ... | ... | @@ -1,35 +0,0 @@ |
| 1 | ///! The quoted behavior definitions are from | |
| 2 | ///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | const comparef = @import("./comparef.zig"); | |
| 6 | ||
| 7 | comptime { | |
| 8 | if (compiler_rt.want_aeabi) { | |
| 9 | symbol(&__aeabi_fcmpge, "__aeabi_fcmpge"); | |
| 10 | symbol(&__aeabi_fcmpgt, "__aeabi_fcmpgt"); | |
| 11 | } else { | |
| 12 | symbol(&__gesf2, "__gesf2"); | |
| 13 | symbol(&__gtsf2, "__gtsf2"); | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | /// "These functions return a value greater than or equal to zero if neither | |
| 18 | /// argument is NaN, and a is greater than or equal to b." | |
| 19 | pub fn __gesf2(a: f32, b: f32) callconv(.c) i32 { | |
| 20 | return @backingInt(comparef.cmpf2(f32, comparef.GE, a, b)); | |
| 21 | } | |
| 22 | ||
| 23 | /// "These functions return a value greater than zero if neither argument is NaN, | |
| 24 | /// and a is strictly greater than b." | |
| 25 | pub fn __gtsf2(a: f32, b: f32) callconv(.c) i32 { | |
| 26 | return __gesf2(a, b); | |
| 27 | } | |
| 28 | ||
| 29 | fn __aeabi_fcmpge(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 30 | return @intFromBool(comparef.cmpf2(f32, comparef.GE, a, b) != .Less); | |
| 31 | } | |
| 32 | ||
| 33 | fn __aeabi_fcmpgt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 34 | return @intFromBool(comparef.cmpf2(f32, comparef.LE, a, b) == .Greater); | |
| 35 | } |
lib/compiler_rt/getf2.zig deleted-26| ... | ... | @@ -1,26 +0,0 @@ |
| 1 | ///! The quoted behavior definitions are from | |
| 2 | ///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | const comparef = @import("./comparef.zig"); | |
| 6 | ||
| 7 | comptime { | |
| 8 | if (compiler_rt.want_ppc_abi) { | |
| 9 | symbol(&__getf2, "__gekf2"); | |
| 10 | symbol(&__gttf2, "__gtkf2"); | |
| 11 | } | |
| 12 | symbol(&__getf2, "__getf2"); | |
| 13 | symbol(&__gttf2, "__gttf2"); | |
| 14 | } | |
| 15 | ||
| 16 | /// "These functions return a value greater than or equal to zero if neither | |
| 17 | /// argument is NaN, and a is greater than or equal to b." | |
| 18 | fn __getf2(a: f128, b: f128) callconv(.c) i32 { | |
| 19 | return @backingInt(comparef.cmpf2(f128, comparef.GE, a, b)); | |
| 20 | } | |
| 21 | ||
| 22 | /// "These functions return a value greater than zero if neither argument is NaN, | |
| 23 | /// and a is strictly greater than b." | |
| 24 | fn __gttf2(a: f128, b: f128) callconv(.c) i32 { | |
| 25 | return __getf2(a, b); | |
| 26 | } |
lib/compiler_rt/gexf2.zig deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 2 | const comparef = @import("./comparef.zig"); | |
| 3 | ||
| 4 | comptime { | |
| 5 | symbol(&__gexf2, "__gexf2"); | |
| 6 | symbol(&__gtxf2, "__gtxf2"); | |
| 7 | } | |
| 8 | ||
| 9 | fn __gexf2(a: f80, b: f80) callconv(.c) i32 { | |
| 10 | return @backingInt(comparef.cmp_f80(comparef.GE, a, b)); | |
| 11 | } | |
| 12 | ||
| 13 | fn __gtxf2(a: f80, b: f80) callconv(.c) i32 { | |
| 14 | return __gexf2(a, b); | |
| 15 | } |
lib/compiler_rt/int.zig+39-40| ... | ... | @@ -36,7 +36,7 @@ comptime { |
| 36 | 36 | |
| 37 | 37 | pub fn __divmodti4(a: i128, b: i128, rem: *i128) callconv(.c) i128 { |
| 38 | 38 | const d = __divti3(a, b); |
| 39 | rem.* = a -% (d * b); | |
| 39 | rem.* = a - d *% b; | |
| 40 | 40 | return d; |
| 41 | 41 | } |
| 42 | 42 | |
| ... | ... | @@ -69,7 +69,7 @@ fn test_one_divmodti4(a: i128, b: i128, expected_q: i128, expected_r: i128) !voi |
| 69 | 69 | |
| 70 | 70 | pub fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.c) i64 { |
| 71 | 71 | const d = __divdi3(a, b); |
| 72 | rem.* = a -% (d * b); | |
| 72 | rem.* = a - d *% b; | |
| 73 | 73 | return d; |
| 74 | 74 | } |
| 75 | 75 | |
| ... | ... | @@ -79,21 +79,20 @@ fn test_one_divmoddi4(a: i64, b: i64, expected_q: i64, expected_r: i64) !void { |
| 79 | 79 | try testing.expect(q == expected_q and r == expected_r); |
| 80 | 80 | } |
| 81 | 81 | |
| 82 | const cases__divmoddi4 = | |
| 83 | [_][4]i64{ | |
| 84 | [_]i64{ 0, 1, 0, 0 }, | |
| 85 | [_]i64{ 0, -1, 0, 0 }, | |
| 86 | [_]i64{ 2, 1, 2, 0 }, | |
| 87 | [_]i64{ 2, -1, -2, 0 }, | |
| 88 | [_]i64{ -2, 1, -2, 0 }, | |
| 89 | [_]i64{ -2, -1, 2, 0 }, | |
| 90 | [_]i64{ 7, 5, 1, 2 }, | |
| 91 | [_]i64{ -7, 5, -1, -2 }, | |
| 92 | [_]i64{ 19, 5, 3, 4 }, | |
| 93 | [_]i64{ 19, -5, -3, 4 }, | |
| 94 | [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 }, | |
| 95 | [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 }, | |
| 96 | }; | |
| 82 | const cases__divmoddi4 = [_][4]i64{ | |
| 83 | [_]i64{ 0, 1, 0, 0 }, | |
| 84 | [_]i64{ 0, -1, 0, 0 }, | |
| 85 | [_]i64{ 2, 1, 2, 0 }, | |
| 86 | [_]i64{ 2, -1, -2, 0 }, | |
| 87 | [_]i64{ -2, 1, -2, 0 }, | |
| 88 | [_]i64{ -2, -1, 2, 0 }, | |
| 89 | [_]i64{ 7, 5, 1, 2 }, | |
| 90 | [_]i64{ -7, 5, -1, -2 }, | |
| 91 | [_]i64{ 19, 5, 3, 4 }, | |
| 92 | [_]i64{ 19, -5, -3, 4 }, | |
| 93 | [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 }, | |
| 94 | [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 }, | |
| 95 | }; | |
| 97 | 96 | |
| 98 | 97 | test "test_divmoddi4" { |
| 99 | 98 | for (cases__divmoddi4) |case| { |
| ... | ... | @@ -105,10 +104,6 @@ pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.c) u64 { |
| 105 | 104 | return udivmod(u64, a, b, maybe_rem); |
| 106 | 105 | } |
| 107 | 106 | |
| 108 | test "test_udivmoddi4" { | |
| 109 | _ = @import("udivmoddi4_test.zig"); | |
| 110 | } | |
| 111 | ||
| 112 | 107 | pub fn __divdi3(a: i64, b: i64) callconv(.c) i64 { |
| 113 | 108 | // Set aside the sign of the quotient. |
| 114 | 109 | const sign: u64 = @bitCast((a ^ b) >> 63); |
| ... | ... | @@ -209,25 +204,24 @@ fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) !void { |
| 209 | 204 | |
| 210 | 205 | pub fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.c) i32 { |
| 211 | 206 | const d = __divsi3(a, b); |
| 212 | rem.* = a -% (d * b); | |
| 207 | rem.* = a - d *% b; | |
| 213 | 208 | return d; |
| 214 | 209 | } |
| 215 | 210 | |
| 216 | const cases__divmodsi4 = | |
| 217 | [_][4]i32{ | |
| 218 | [_]i32{ 0, 1, 0, 0 }, | |
| 219 | [_]i32{ 0, -1, 0, 0 }, | |
| 220 | [_]i32{ 2, 1, 2, 0 }, | |
| 221 | [_]i32{ 2, -1, -2, 0 }, | |
| 222 | [_]i32{ -2, 1, -2, 0 }, | |
| 223 | [_]i32{ -2, -1, 2, 0 }, | |
| 224 | [_]i32{ 7, 5, 1, 2 }, | |
| 225 | [_]i32{ -7, 5, -1, -2 }, | |
| 226 | [_]i32{ 19, 5, 3, 4 }, | |
| 227 | [_]i32{ 19, -5, -3, 4 }, | |
| 228 | [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 }, | |
| 229 | [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 }, | |
| 230 | }; | |
| 211 | const cases__divmodsi4 = [_][4]i32{ | |
| 212 | [_]i32{ 0, 1, 0, 0 }, | |
| 213 | [_]i32{ 0, -1, 0, 0 }, | |
| 214 | [_]i32{ 2, 1, 2, 0 }, | |
| 215 | [_]i32{ 2, -1, -2, 0 }, | |
| 216 | [_]i32{ -2, 1, -2, 0 }, | |
| 217 | [_]i32{ -2, -1, 2, 0 }, | |
| 218 | [_]i32{ 7, 5, 1, 2 }, | |
| 219 | [_]i32{ -7, 5, -1, -2 }, | |
| 220 | [_]i32{ 19, 5, 3, 4 }, | |
| 221 | [_]i32{ 19, -5, -3, 4 }, | |
| 222 | [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 }, | |
| 223 | [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 }, | |
| 224 | }; | |
| 231 | 225 | |
| 232 | 226 | fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) !void { |
| 233 | 227 | var r: i32 = undefined; |
| ... | ... | @@ -243,7 +237,7 @@ test "test_divmodsi4" { |
| 243 | 237 | |
| 244 | 238 | pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.c) u32 { |
| 245 | 239 | const d = __udivsi3(a, b); |
| 246 | rem.* = @bitCast(@as(i32, @bitCast(a)) -% (@as(i32, @bitCast(d)) * @as(i32, @bitCast(b)))); | |
| 240 | rem.* = a - d * b; | |
| 247 | 241 | return d; |
| 248 | 242 | } |
| 249 | 243 | |
| ... | ... | @@ -486,7 +480,7 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) !void { |
| 486 | 480 | } |
| 487 | 481 | |
| 488 | 482 | pub fn __modsi3(n: i32, d: i32) callconv(.c) i32 { |
| 489 | return n -% __divsi3(n, d) * d; | |
| 483 | return n - __divsi3(n, d) *% d; | |
| 490 | 484 | } |
| 491 | 485 | |
| 492 | 486 | test "test_modsi3" { |
| ... | ... | @@ -515,7 +509,7 @@ fn test_one_modsi3(a: i32, b: i32, expected_r: i32) !void { |
| 515 | 509 | } |
| 516 | 510 | |
| 517 | 511 | pub fn __umodsi3(n: u32, d: u32) callconv(.c) u32 { |
| 518 | return n -% __udivsi3(n, d) * d; | |
| 512 | return n - __udivsi3(n, d) * d; | |
| 519 | 513 | } |
| 520 | 514 | |
| 521 | 515 | test "test_umodsi3" { |
| ... | ... | @@ -663,3 +657,8 @@ fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) !void { |
| 663 | 657 | const r: u32 = __umodsi3(a, b); |
| 664 | 658 | try testing.expect(r == expected_r); |
| 665 | 659 | } |
| 660 | ||
| 661 | test { | |
| 662 | _ = @import("udivmodsi4_test.zig"); | |
| 663 | _ = @import("udivmoddi4_test.zig"); | |
| 664 | } |
lib/compiler_rt/int_from_float.zig+513-9| ... | ... | @@ -1,3 +1,4 @@ |
| 1 | const builtin = @import("builtin"); | |
| 1 | 2 | const std = @import("std"); |
| 2 | 3 | const math = std.math; |
| 3 | 4 | const Log2Int = std.math.Log2Int; |
| ... | ... | @@ -6,29 +7,532 @@ const compiler_rt = @import("../compiler_rt.zig"); |
| 6 | 7 | const symbol = compiler_rt.symbol; |
| 7 | 8 | |
| 8 | 9 | comptime { |
| 9 | symbol(&__fixxfti, "__fixxfti"); | |
| 10 | 10 | symbol(&__fixhfsi, "__fixhfsi"); |
| 11 | 11 | symbol(&__fixhfdi, "__fixhfdi"); |
| 12 | 12 | symbol(&__fixhfti, "__fixhfti"); |
| 13 | symbol(&__fixhfei, "__fixhfei"); | |
| 14 | ||
| 15 | if (compiler_rt.want_aeabi) { | |
| 16 | symbol(&__aeabi_f2iz, "__aeabi_f2iz"); | |
| 17 | symbol(&__aeabi_f2lz, "__aeabi_f2lz"); | |
| 18 | symbol(&__aeabi_fixsfti, "__fixsfti"); | |
| 19 | } else { | |
| 20 | symbol(&__fixsfsi, "__fixsfsi"); | |
| 21 | symbol(&__fixsfdi, "__fixsfdi"); | |
| 22 | if (compiler_rt.want_windows_arm_abi) symbol(&__fixsfdi, "__stoi64"); | |
| 23 | symbol(&__fixsfti, "__fixsfti"); | |
| 24 | } | |
| 25 | symbol(&__fixsfei, "__fixsfei"); | |
| 26 | ||
| 27 | if (compiler_rt.want_aeabi) { | |
| 28 | symbol(&__aeabi_d2iz, "__aeabi_d2iz"); | |
| 29 | symbol(&__aeabi_d2lz, "__aeabi_d2lz"); | |
| 30 | symbol(&__aeabi_fixdfti, "__fixdfti"); | |
| 31 | } else { | |
| 32 | symbol(&__fixdfsi, "__fixdfsi"); | |
| 33 | symbol(&__fixdfdi, "__fixdfdi"); | |
| 34 | if (compiler_rt.want_windows_arm_abi) symbol(&__fixdfdi, "__dtoi64"); | |
| 35 | symbol(&__fixdfti, "__fixdfti"); | |
| 36 | } | |
| 37 | symbol(&__fixdfei, "__fixdfei"); | |
| 38 | ||
| 39 | symbol(&__fixxfsi, "__fixxfsi"); | |
| 40 | symbol(&__fixxfdi, "__fixxfdi"); | |
| 41 | symbol(&__fixxfti, "__fixxfti"); | |
| 42 | symbol(&__fixxfei, "__fixxfei"); | |
| 43 | ||
| 44 | if (compiler_rt.want_ppc_abi) { | |
| 45 | symbol(&__fixtfsi, "__fixkfsi"); | |
| 46 | symbol(&__fixtfdi, "__fixkfdi"); | |
| 47 | } else if (compiler_rt.want_sparc64_abi) { | |
| 48 | symbol(&_Qp_qtoi, "_Qp_qtoi"); | |
| 49 | symbol(&_Qp_qtox, "_Qp_qtox"); | |
| 50 | } else if (compiler_rt.want_sparc32_abi) { | |
| 51 | symbol(&__fixtfsi, "_Q_qtoi"); | |
| 52 | symbol(&__fixtfdi, "_Q_qtoll"); | |
| 53 | } else { | |
| 54 | symbol(&__fixtfsi, "__fixtfsi"); | |
| 55 | symbol(&__fixtfdi, "__fixtfdi"); | |
| 56 | } | |
| 57 | if (compiler_rt.want_ppc_abi) { | |
| 58 | symbol(&__fixtfti, "__fixkfti"); | |
| 59 | symbol(&__fixtfei, "__fixkfei"); | |
| 60 | } else { | |
| 61 | symbol(&__fixtfti, "__fixtfti"); | |
| 62 | symbol(&__fixtfei, "__fixtfei"); | |
| 63 | } | |
| 64 | } | |
| 65 | ||
| 66 | fn __fixhfsi(a: compiler_rt.f16.Abi) callconv(.c) i32 { | |
| 67 | return i32_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | |
| 68 | } | |
| 69 | pub fn i32_intFromFloat_f16(a: f16) i32 { | |
| 70 | return intFromFloat(i32, a); | |
| 71 | } | |
| 72 | ||
| 73 | fn __fixhfdi(a: compiler_rt.f16.Abi) callconv(.c) i64 { | |
| 74 | return i64_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | |
| 75 | } | |
| 76 | pub fn i64_intFromFloat_f16(a: f16) i64 { | |
| 77 | return intFromFloat(i64, a); | |
| 78 | } | |
| 79 | ||
| 80 | fn __fixhfti(a: compiler_rt.f16.Abi) callconv(.c) i128 { | |
| 81 | return i128_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | |
| 82 | } | |
| 83 | pub fn i128_intFromFloat_f16(a: f16) i128 { | |
| 84 | return intFromFloat(i128, a); | |
| 85 | } | |
| 86 | ||
| 87 | fn __fixhfei(r: [*]u8, bits: usize, a: compiler_rt.f16.Abi) callconv(.c) void { | |
| 88 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 89 | return signed_intFromFloat_f16(r[0..byte_size], compiler_rt.f16.fromAbi(a)); | |
| 90 | } | |
| 91 | pub fn signed_intFromFloat_f16(result: []u8, a: f16) void { | |
| 92 | bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); | |
| 93 | } | |
| 94 | ||
| 95 | fn __fixsfsi(a: compiler_rt.f32.Abi) callconv(.c) i32 { | |
| 96 | return i32_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | |
| 97 | } | |
| 98 | fn __aeabi_f2iz(a: f32) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 99 | return i32_intFromFloat_f32(a); | |
| 100 | } | |
| 101 | pub fn i32_intFromFloat_f32(a: f32) i32 { | |
| 102 | return intFromFloat(i32, a); | |
| 103 | } | |
| 104 | ||
| 105 | fn __fixsfdi(a: compiler_rt.f32.Abi) callconv(.c) i64 { | |
| 106 | return i64_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | |
| 107 | } | |
| 108 | fn __aeabi_f2lz(a: f32) callconv(.{ .arm_aapcs = .{} }) i64 { | |
| 109 | return i64_intFromFloat_f32(a); | |
| 110 | } | |
| 111 | pub fn i64_intFromFloat_f32(a: f32) i64 { | |
| 112 | return intFromFloat(i64, a); | |
| 113 | } | |
| 114 | ||
| 115 | fn __fixsfti(a: compiler_rt.f32.Abi) callconv(.c) i128 { | |
| 116 | return i128_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | |
| 117 | } | |
| 118 | fn __aeabi_fixsfti(_: compiler_rt.f32.Abi) callconv(.naked) i128 { | |
| 119 | switch (builtin.abi.float()) { | |
| 120 | .soft => asm volatile ( | |
| 121 | \\ push {r0-r4, lr} | |
| 122 | \\ mov r1, r0 | |
| 123 | \\ mov r0, sp | |
| 124 | \\ bl %[__fixsfti] | |
| 125 | \\ pop {r0-r4, pc} | |
| 126 | : | |
| 127 | : [__fixsfti] "X" (&__fixsfti), | |
| 128 | ), | |
| 129 | .hard => asm volatile ( | |
| 130 | \\ push {r0-r4, lr} | |
| 131 | \\ mov r0, sp | |
| 132 | \\ bl %[__fixsfti] | |
| 133 | \\ pop {r0-r4, pc} | |
| 134 | : | |
| 135 | : [__fixsfti] "X" (&__fixsfti), | |
| 136 | ), | |
| 137 | } | |
| 138 | } | |
| 139 | pub fn i128_intFromFloat_f32(a: f32) i128 { | |
| 140 | return intFromFloat(i128, a); | |
| 141 | } | |
| 142 | ||
| 143 | fn __fixsfei(r: [*]u8, bits: usize, a: compiler_rt.f32.Abi) callconv(.c) void { | |
| 144 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 145 | return signed_intFromFloat_f32(r[0..byte_size], compiler_rt.f32.fromAbi(a)); | |
| 146 | } | |
| 147 | pub fn signed_intFromFloat_f32(result: []u8, a: f32) void { | |
| 148 | bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); | |
| 149 | } | |
| 150 | ||
| 151 | fn __fixdfsi(a: compiler_rt.f64.Abi) callconv(.c) i32 { | |
| 152 | return i32_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | |
| 153 | } | |
| 154 | fn __aeabi_d2iz(a: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 155 | return i32_intFromFloat_f64(a); | |
| 156 | } | |
| 157 | pub fn i32_intFromFloat_f64(a: f64) i32 { | |
| 158 | return intFromFloat(i32, a); | |
| 159 | } | |
| 160 | ||
| 161 | fn __fixdfdi(a: compiler_rt.f64.Abi) callconv(.c) i64 { | |
| 162 | return i64_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | |
| 163 | } | |
| 164 | fn __aeabi_d2lz(a: f64) callconv(.{ .arm_aapcs = .{} }) i64 { | |
| 165 | return i64_intFromFloat_f64(a); | |
| 166 | } | |
| 167 | pub fn i64_intFromFloat_f64(a: f64) i64 { | |
| 168 | return intFromFloat(i64, a); | |
| 13 | 169 | } |
| 14 | 170 | |
| 15 | pub fn __fixhfti(a: f16) callconv(.c) i128 { | |
| 171 | fn __fixdfti(a: compiler_rt.f64.Abi) callconv(.c) i128 { | |
| 172 | return i128_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | |
| 173 | } | |
| 174 | fn __aeabi_fixdfti(_: compiler_rt.f64.Abi) callconv(.naked) i128 { | |
| 175 | switch (builtin.abi.float()) { | |
| 176 | .soft => asm volatile ( | |
| 177 | \\ push {r0-r4, lr} | |
| 178 | \\ mov r3, r1 | |
| 179 | \\ mov r2, r0 | |
| 180 | \\ mov r0, sp | |
| 181 | \\ bl %[__fixdfti] | |
| 182 | \\ pop {r0-r4, pc} | |
| 183 | : | |
| 184 | : [__fixdfti] "X" (&__fixdfti), | |
| 185 | ), | |
| 186 | .hard => asm volatile ( | |
| 187 | \\ push {r0-r4, lr} | |
| 188 | \\ mov r0, sp | |
| 189 | \\ bl %[__fixdfti] | |
| 190 | \\ pop {r0-r4, pc} | |
| 191 | : | |
| 192 | : [__fixdfti] "X" (&__fixdfti), | |
| 193 | ), | |
| 194 | } | |
| 195 | } | |
| 196 | pub fn i128_intFromFloat_f64(a: f64) i128 { | |
| 16 | 197 | return intFromFloat(i128, a); |
| 17 | 198 | } |
| 18 | 199 | |
| 19 | fn __fixhfdi(a: f16) callconv(.c) i64 { | |
| 200 | fn __fixdfei(r: [*]u8, bits: usize, a: compiler_rt.f64.Abi) callconv(.c) void { | |
| 201 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 202 | return signed_intFromFloat_f64(r[0..byte_size], compiler_rt.f64.fromAbi(a)); | |
| 203 | } | |
| 204 | pub fn signed_intFromFloat_f64(result: []u8, a: f64) void { | |
| 205 | bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); | |
| 206 | } | |
| 207 | ||
| 208 | fn __fixxfsi(a: compiler_rt.f80.Abi) callconv(.c) i32 { | |
| 209 | return i32_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | |
| 210 | } | |
| 211 | pub fn i32_intFromFloat_f80(a: f80) i32 { | |
| 212 | return intFromFloat(i32, a); | |
| 213 | } | |
| 214 | ||
| 215 | fn __fixxfdi(a: compiler_rt.f80.Abi) callconv(.c) i64 { | |
| 216 | return i64_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | |
| 217 | } | |
| 218 | pub fn i64_intFromFloat_f80(a: f80) i64 { | |
| 20 | 219 | return intFromFloat(i64, a); |
| 21 | 220 | } |
| 22 | 221 | |
| 23 | fn __fixhfsi(a: f16) callconv(.c) i32 { | |
| 222 | fn __fixxfti(a: compiler_rt.f80.Abi) callconv(.c) i128 { | |
| 223 | return i128_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | |
| 224 | } | |
| 225 | pub fn i128_intFromFloat_f80(a: f80) i128 { | |
| 226 | return intFromFloat(i128, a); | |
| 227 | } | |
| 228 | ||
| 229 | fn __fixxfei(r: [*]u8, bits: usize, a: compiler_rt.f80.Abi) callconv(.c) void { | |
| 230 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 231 | return signed_intFromFloat_f80(r[0..byte_size], compiler_rt.f80.fromAbi(a)); | |
| 232 | } | |
| 233 | pub fn signed_intFromFloat_f80(result: []u8, a: f80) void { | |
| 234 | bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); | |
| 235 | } | |
| 236 | ||
| 237 | fn __fixtfsi(a: compiler_rt.f128.Abi) callconv(.c) i32 { | |
| 238 | return i32_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | |
| 239 | } | |
| 240 | fn _Qp_qtoi(a: *const f128) callconv(.c) i32 { | |
| 241 | return i32_intFromFloat_f128(a.*); | |
| 242 | } | |
| 243 | pub fn i32_intFromFloat_f128(a: f128) i32 { | |
| 24 | 244 | return intFromFloat(i32, a); |
| 25 | 245 | } |
| 26 | 246 | |
| 27 | pub fn __fixxfti(a: f80) callconv(.c) i128 { | |
| 247 | fn __fixtfdi(a: compiler_rt.f128.Abi) callconv(.c) i64 { | |
| 248 | return i64_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | |
| 249 | } | |
| 250 | fn _Qp_qtox(a: *const f128) callconv(.c) i64 { | |
| 251 | return i64_intFromFloat_f128(a.*); | |
| 252 | } | |
| 253 | pub fn i64_intFromFloat_f128(a: f128) i64 { | |
| 254 | return intFromFloat(i64, a); | |
| 255 | } | |
| 256 | ||
| 257 | fn __fixtfti(a: compiler_rt.f128.Abi) callconv(.c) i128 { | |
| 258 | return i128_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | |
| 259 | } | |
| 260 | pub fn i128_intFromFloat_f128(a: f128) i128 { | |
| 28 | 261 | return intFromFloat(i128, a); |
| 29 | 262 | } |
| 30 | 263 | |
| 31 | pub inline fn intFromFloat(comptime I: type, a: anytype) I { | |
| 264 | fn __fixtfei(r: [*]u8, bits: usize, a: compiler_rt.f128.Abi) callconv(.c) void { | |
| 265 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 266 | return signed_intFromFloat_f128(r[0..byte_size], compiler_rt.f128.fromAbi(a)); | |
| 267 | } | |
| 268 | pub fn signed_intFromFloat_f128(result: []u8, a: f128) void { | |
| 269 | bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); | |
| 270 | } | |
| 271 | ||
| 272 | comptime { | |
| 273 | symbol(&__fixunshfsi, "__fixunshfsi"); | |
| 274 | symbol(&__fixunshfdi, "__fixunshfdi"); | |
| 275 | symbol(&__fixunshfti, "__fixunshfti"); | |
| 276 | symbol(&__fixunshfei, "__fixunshfei"); | |
| 277 | ||
| 278 | if (compiler_rt.want_aeabi) { | |
| 279 | symbol(&__aeabi_f2uiz, "__aeabi_f2uiz"); | |
| 280 | symbol(&__aeabi_f2ulz, "__aeabi_f2ulz"); | |
| 281 | symbol(&__aeabi_fixunssfti, "__fixunssfti"); | |
| 282 | } else { | |
| 283 | symbol(&__fixunssfsi, "__fixunssfsi"); | |
| 284 | symbol(&__fixunssfdi, "__fixunssfdi"); | |
| 285 | if (compiler_rt.want_windows_arm_abi) symbol(&__fixunssfdi, "__stou64"); | |
| 286 | symbol(&__fixunssfti, "__fixunssfti"); | |
| 287 | } | |
| 288 | symbol(&__fixunssfei, "__fixunssfei"); | |
| 289 | ||
| 290 | if (compiler_rt.want_aeabi) { | |
| 291 | symbol(&__aeabi_d2uiz, "__aeabi_d2uiz"); | |
| 292 | symbol(&__aeabi_d2ulz, "__aeabi_d2ulz"); | |
| 293 | symbol(&__aeabi_fixunsdfti, "__fixunsdfti"); | |
| 294 | } else { | |
| 295 | symbol(&__fixunsdfsi, "__fixunsdfsi"); | |
| 296 | symbol(&__fixunsdfdi, "__fixunsdfdi"); | |
| 297 | if (compiler_rt.want_windows_arm_abi) symbol(&__fixunsdfdi, "__dtou64"); | |
| 298 | symbol(&__fixunsdfti, "__fixunsdfti"); | |
| 299 | } | |
| 300 | symbol(&__fixunsdfei, "__fixunsdfei"); | |
| 301 | ||
| 302 | symbol(&__fixunsxfsi, "__fixunsxfsi"); | |
| 303 | symbol(&__fixunsxfdi, "__fixunsxfdi"); | |
| 304 | symbol(&__fixunsxfti, "__fixunsxfti"); | |
| 305 | symbol(&__fixunsxfei, "__fixunsxfei"); | |
| 306 | ||
| 307 | if (compiler_rt.want_ppc_abi) { | |
| 308 | symbol(&__fixunstfsi, "__fixunskfsi"); | |
| 309 | symbol(&__fixunstfdi, "__fixunskfdi"); | |
| 310 | } else if (compiler_rt.want_sparc64_abi) { | |
| 311 | symbol(&_Qp_qtoui, "_Qp_qtoui"); | |
| 312 | symbol(&_Qp_qtoux, "_Qp_qtoux"); | |
| 313 | } else if (compiler_rt.want_sparc32_abi) { | |
| 314 | symbol(&__fixunstfsi, "_Q_qtou"); | |
| 315 | symbol(&__fixunstfdi, "_Q_qtoull"); | |
| 316 | } else { | |
| 317 | symbol(&__fixunstfsi, "__fixunstfsi"); | |
| 318 | symbol(&__fixunstfdi, "__fixunstfdi"); | |
| 319 | } | |
| 320 | if (compiler_rt.want_ppc_abi) { | |
| 321 | symbol(&__fixunstfti, "__fixunskfti"); | |
| 322 | symbol(&__fixunstfei, "__fixunskfei"); | |
| 323 | } else { | |
| 324 | symbol(&__fixunstfti, "__fixunstfti"); | |
| 325 | symbol(&__fixunstfei, "__fixunstfei"); | |
| 326 | } | |
| 327 | } | |
| 328 | ||
| 329 | fn __fixunshfsi(a: compiler_rt.f16.Abi) callconv(.c) u32 { | |
| 330 | return u32_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | |
| 331 | } | |
| 332 | pub fn u32_intFromFloat_f16(a: f16) u32 { | |
| 333 | return intFromFloat(u32, a); | |
| 334 | } | |
| 335 | ||
| 336 | fn __fixunshfdi(a: compiler_rt.f16.Abi) callconv(.c) u64 { | |
| 337 | return u64_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | |
| 338 | } | |
| 339 | pub fn u64_intFromFloat_f16(a: f16) u64 { | |
| 340 | return intFromFloat(u64, a); | |
| 341 | } | |
| 342 | ||
| 343 | fn __fixunshfti(a: compiler_rt.f16.Abi) callconv(.c) u128 { | |
| 344 | return u128_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); | |
| 345 | } | |
| 346 | pub fn u128_intFromFloat_f16(a: f16) u128 { | |
| 347 | return intFromFloat(u128, a); | |
| 348 | } | |
| 349 | ||
| 350 | fn __fixunshfei(r: [*]u8, bits: usize, a: compiler_rt.f16.Abi) callconv(.c) void { | |
| 351 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 352 | return unsigned_intFromFloat_f16(r[0..byte_size], compiler_rt.f16.fromAbi(a)); | |
| 353 | } | |
| 354 | pub fn unsigned_intFromFloat_f16(result: []u8, a: f16) void { | |
| 355 | bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); | |
| 356 | } | |
| 357 | ||
| 358 | fn __fixunssfsi(a: compiler_rt.f32.Abi) callconv(.c) u32 { | |
| 359 | return u32_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | |
| 360 | } | |
| 361 | fn __aeabi_f2uiz(a: f32) callconv(.{ .arm_aapcs = .{} }) u32 { | |
| 362 | return u32_intFromFloat_f32(a); | |
| 363 | } | |
| 364 | pub fn u32_intFromFloat_f32(a: f32) u32 { | |
| 365 | return intFromFloat(u32, a); | |
| 366 | } | |
| 367 | ||
| 368 | fn __fixunssfdi(a: compiler_rt.f32.Abi) callconv(.c) u64 { | |
| 369 | return u64_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | |
| 370 | } | |
| 371 | fn __aeabi_f2ulz(a: f32) callconv(.{ .arm_aapcs = .{} }) u64 { | |
| 372 | return u64_intFromFloat_f32(a); | |
| 373 | } | |
| 374 | pub fn u64_intFromFloat_f32(a: f32) u64 { | |
| 375 | return intFromFloat(u64, a); | |
| 376 | } | |
| 377 | ||
| 378 | fn __fixunssfti(a: compiler_rt.f32.Abi) callconv(.c) u128 { | |
| 379 | return u128_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); | |
| 380 | } | |
| 381 | fn __aeabi_fixunssfti(_: compiler_rt.f32.Abi) callconv(.naked) u128 { | |
| 382 | switch (builtin.abi.float()) { | |
| 383 | .soft => asm volatile ( | |
| 384 | \\ push {r0-r4, lr} | |
| 385 | \\ mov r1, r0 | |
| 386 | \\ mov r0, sp | |
| 387 | \\ bl %[__fixunssfti] | |
| 388 | \\ pop {r0-r4, pc} | |
| 389 | : | |
| 390 | : [__fixunssfti] "X" (&__fixunssfti), | |
| 391 | ), | |
| 392 | .hard => asm volatile ( | |
| 393 | \\ push {r0-r4, lr} | |
| 394 | \\ mov r0, sp | |
| 395 | \\ bl %[__fixunssfti] | |
| 396 | \\ pop {r0-r4, pc} | |
| 397 | : | |
| 398 | : [__fixunssfti] "X" (&__fixunssfti), | |
| 399 | ), | |
| 400 | } | |
| 401 | } | |
| 402 | pub fn u128_intFromFloat_f32(a: f32) u128 { | |
| 403 | return intFromFloat(u128, a); | |
| 404 | } | |
| 405 | ||
| 406 | fn __fixunssfei(r: [*]u8, bits: usize, a: compiler_rt.f32.Abi) callconv(.c) void { | |
| 407 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 408 | return unsigned_intFromFloat_f32(r[0..byte_size], compiler_rt.f32.fromAbi(a)); | |
| 409 | } | |
| 410 | pub fn unsigned_intFromFloat_f32(result: []u8, a: f32) void { | |
| 411 | bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); | |
| 412 | } | |
| 413 | ||
| 414 | fn __fixunsdfsi(a: compiler_rt.f64.Abi) callconv(.c) u32 { | |
| 415 | return u32_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | |
| 416 | } | |
| 417 | fn __aeabi_d2uiz(a: f64) callconv(.{ .arm_aapcs = .{} }) u32 { | |
| 418 | return u32_intFromFloat_f64(a); | |
| 419 | } | |
| 420 | pub fn u32_intFromFloat_f64(a: f64) u32 { | |
| 421 | return intFromFloat(u32, a); | |
| 422 | } | |
| 423 | ||
| 424 | fn __fixunsdfdi(a: compiler_rt.f64.Abi) callconv(.c) u64 { | |
| 425 | return u64_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | |
| 426 | } | |
| 427 | fn __aeabi_d2ulz(a: f64) callconv(.{ .arm_aapcs = .{} }) u64 { | |
| 428 | return u64_intFromFloat_f64(a); | |
| 429 | } | |
| 430 | pub fn u64_intFromFloat_f64(a: f64) u64 { | |
| 431 | return intFromFloat(u64, a); | |
| 432 | } | |
| 433 | ||
| 434 | fn __fixunsdfti(a: compiler_rt.f64.Abi) callconv(.c) u128 { | |
| 435 | return u128_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); | |
| 436 | } | |
| 437 | fn __aeabi_fixunsdfti(_: compiler_rt.f64.Abi) callconv(.naked) u128 { | |
| 438 | switch (builtin.abi.float()) { | |
| 439 | .soft => asm volatile ( | |
| 440 | \\ push {r0-r4, lr} | |
| 441 | \\ mov r3, r1 | |
| 442 | \\ mov r2, r0 | |
| 443 | \\ mov r0, sp | |
| 444 | \\ bl %[__fixunsdfti] | |
| 445 | \\ pop {r0-r4, pc} | |
| 446 | : | |
| 447 | : [__fixunsdfti] "X" (&__fixunsdfti), | |
| 448 | ), | |
| 449 | .hard => asm volatile ( | |
| 450 | \\ push {r0-r4, lr} | |
| 451 | \\ mov r0, sp | |
| 452 | \\ bl %[__fixunsdfti] | |
| 453 | \\ pop {r0-r4, pc} | |
| 454 | : | |
| 455 | : [__fixunsdfti] "X" (&__fixunsdfti), | |
| 456 | ), | |
| 457 | } | |
| 458 | } | |
| 459 | pub fn u128_intFromFloat_f64(a: f64) u128 { | |
| 460 | return intFromFloat(u128, a); | |
| 461 | } | |
| 462 | ||
| 463 | fn __fixunsdfei(r: [*]u8, bits: usize, a: compiler_rt.f64.Abi) callconv(.c) void { | |
| 464 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 465 | return unsigned_intFromFloat_f64(r[0..byte_size], compiler_rt.f64.fromAbi(a)); | |
| 466 | } | |
| 467 | pub fn unsigned_intFromFloat_f64(result: []u8, a: f64) void { | |
| 468 | bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); | |
| 469 | } | |
| 470 | ||
| 471 | fn __fixunsxfsi(a: compiler_rt.f80.Abi) callconv(.c) u32 { | |
| 472 | return u32_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | |
| 473 | } | |
| 474 | pub fn u32_intFromFloat_f80(a: f80) u32 { | |
| 475 | return intFromFloat(u32, a); | |
| 476 | } | |
| 477 | ||
| 478 | fn __fixunsxfdi(a: compiler_rt.f80.Abi) callconv(.c) u64 { | |
| 479 | return u64_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | |
| 480 | } | |
| 481 | pub fn u64_intFromFloat_f80(a: f80) u64 { | |
| 482 | return intFromFloat(u64, a); | |
| 483 | } | |
| 484 | ||
| 485 | fn __fixunsxfti(a: compiler_rt.f80.Abi) callconv(.c) u128 { | |
| 486 | return u128_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); | |
| 487 | } | |
| 488 | pub fn u128_intFromFloat_f80(a: f80) u128 { | |
| 489 | return intFromFloat(u128, a); | |
| 490 | } | |
| 491 | ||
| 492 | fn __fixunsxfei(r: [*]u8, bits: usize, a: compiler_rt.f80.Abi) callconv(.c) void { | |
| 493 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 494 | return unsigned_intFromFloat_f80(r[0..byte_size], compiler_rt.f80.fromAbi(a)); | |
| 495 | } | |
| 496 | pub fn unsigned_intFromFloat_f80(result: []u8, a: f80) void { | |
| 497 | bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); | |
| 498 | } | |
| 499 | ||
| 500 | fn __fixunstfsi(a: compiler_rt.f128.Abi) callconv(.c) u32 { | |
| 501 | return u32_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | |
| 502 | } | |
| 503 | fn _Qp_qtoui(a: *const f128) callconv(.c) u32 { | |
| 504 | return u32_intFromFloat_f128(a.*); | |
| 505 | } | |
| 506 | pub fn u32_intFromFloat_f128(a: f128) u32 { | |
| 507 | return intFromFloat(u32, a); | |
| 508 | } | |
| 509 | ||
| 510 | fn __fixunstfdi(a: compiler_rt.f128.Abi) callconv(.c) u64 { | |
| 511 | return u64_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | |
| 512 | } | |
| 513 | fn _Qp_qtoux(a: *const f128) callconv(.c) u64 { | |
| 514 | return u64_intFromFloat_f128(a.*); | |
| 515 | } | |
| 516 | pub fn u64_intFromFloat_f128(a: f128) u64 { | |
| 517 | return intFromFloat(u64, a); | |
| 518 | } | |
| 519 | ||
| 520 | fn __fixunstfti(a: compiler_rt.f128.Abi) callconv(.c) u128 { | |
| 521 | return u128_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); | |
| 522 | } | |
| 523 | pub fn u128_intFromFloat_f128(a: f128) u128 { | |
| 524 | return intFromFloat(u128, a); | |
| 525 | } | |
| 526 | ||
| 527 | fn __fixunstfei(r: [*]u8, bits: usize, a: compiler_rt.f128.Abi) callconv(.c) void { | |
| 528 | const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); | |
| 529 | return unsigned_intFromFloat_f128(r[0..byte_size], compiler_rt.f128.fromAbi(a)); | |
| 530 | } | |
| 531 | pub fn unsigned_intFromFloat_f128(result: []u8, a: f128) void { | |
| 532 | bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); | |
| 533 | } | |
| 534 | ||
| 535 | inline fn intFromFloat(comptime I: type, a: anytype) I { | |
| 32 | 536 | const F = @TypeOf(a); |
| 33 | 537 | const float_bits = @typeInfo(F).float.bits; |
| 34 | 538 | const int_bits = @typeInfo(I).int.bits; |
| ... | ... | @@ -76,13 +580,14 @@ pub inline fn intFromFloat(comptime I: type, a: anytype) I { |
| 76 | 580 | return result; |
| 77 | 581 | } |
| 78 | 582 | |
| 79 | pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, result: []u32, a: anytype) void { | |
| 583 | inline fn bigIntFromFloat(comptime signedness: std.lang.Signedness, result: []u32, a: anytype) void { | |
| 584 | const endian = builtin.cpu.arch.endian(); | |
| 80 | 585 | switch (result.len) { |
| 81 | 586 | 0 => return, |
| 82 | 587 | inline 1...4 => |limbs_len| { |
| 83 | 588 | const I = @Int(signedness, 32 * limbs_len); |
| 84 | 589 | const low_to_high: [limbs_len]u32 = @bitCast(@as(I, @intFromFloat(a))); |
| 85 | result[0..limbs_len].* = switch (@import("builtin").cpu.arch.endian()) { | |
| 590 | result[0..limbs_len].* = switch (endian) { | |
| 86 | 591 | .little => low_to_high, |
| 87 | 592 | .big => switch (limbs_len) { |
| 88 | 593 | 1 => .{low_to_high[0]}, |
| ... | ... | @@ -111,7 +616,6 @@ pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, resul |
| 111 | 616 | }); |
| 112 | 617 | switch (signedness) { |
| 113 | 618 | .signed => { |
| 114 | const endian = @import("builtin").cpu.arch.endian(); | |
| 115 | 619 | const exponent_limb = switch (endian) { |
| 116 | 620 | .little => exponent / 32, |
| 117 | 621 | .big => result.len - 1 - exponent / 32, |
lib/compiler_rt/int_from_float_test.zig+913-897| ... | ... | @@ -2,1023 +2,1039 @@ const std = @import("std"); |
| 2 | 2 | const testing = std.testing; |
| 3 | 3 | const math = std.math; |
| 4 | 4 | |
| 5 | const __fixunshfti = @import("fixunshfti.zig").__fixunshfti; | |
| 6 | const __fixunsxfti = @import("fixunsxfti.zig").__fixunsxfti; | |
| 7 | ||
| 8 | // Conversion from f32 | |
| 9 | const __fixsfsi = @import("fixsfsi.zig").__fixsfsi; | |
| 10 | const __fixunssfsi = @import("fixunssfsi.zig").__fixunssfsi; | |
| 11 | const __fixsfdi = @import("fixsfdi.zig").__fixsfdi; | |
| 12 | const __fixunssfdi = @import("fixunssfdi.zig").__fixunssfdi; | |
| 13 | const __fixsfti = @import("fixsfti.zig").__fixsfti; | |
| 14 | const __fixunssfti = @import("fixunssfti.zig").__fixunssfti; | |
| 15 | const __fixsfei = @import("fixsfei.zig").__fixsfei; | |
| 16 | const __fixunssfei = @import("fixunssfei.zig").__fixunssfei; | |
| 17 | ||
| 18 | // Conversion from f64 | |
| 19 | const __fixdfsi = @import("fixdfsi.zig").__fixdfsi; | |
| 20 | const __fixunsdfsi = @import("fixunsdfsi.zig").__fixunsdfsi; | |
| 21 | const __fixdfdi = @import("fixdfdi.zig").__fixdfdi; | |
| 22 | const __fixunsdfdi = @import("fixunsdfdi.zig").__fixunsdfdi; | |
| 23 | const __fixdfti = @import("fixdfti.zig").__fixdfti; | |
| 24 | const __fixunsdfti = @import("fixunsdfti.zig").__fixunsdfti; | |
| 25 | const __fixdfei = @import("fixdfei.zig").__fixdfei; | |
| 26 | const __fixunsdfei = @import("fixunsdfei.zig").__fixunsdfei; | |
| 27 | ||
| 28 | // Conversion from f128 | |
| 29 | const __fixtfsi = @import("fixtfsi.zig").__fixtfsi; | |
| 30 | const __fixunstfsi = @import("fixunstfsi.zig").__fixunstfsi; | |
| 31 | const __fixtfdi = @import("fixtfdi.zig").__fixtfdi; | |
| 32 | const __fixunstfdi = @import("fixunstfdi.zig").__fixunstfdi; | |
| 33 | const __fixtfti = @import("fixtfti.zig").__fixtfti; | |
| 34 | const __fixunstfti = @import("fixunstfti.zig").__fixunstfti; | |
| 35 | ||
| 36 | fn test__fixsfsi(a: f32, expected: i32) !void { | |
| 37 | const x = __fixsfsi(a); | |
| 5 | const impl = @import("int_from_float.zig"); | |
| 6 | ||
| 7 | const i32_intFromFloat_f16 = impl.i32_intFromFloat_f16; | |
| 8 | const u32_intFromFloat_f16 = impl.u32_intFromFloat_f16; | |
| 9 | const i64_intFromFloat_f16 = impl.i64_intFromFloat_f16; | |
| 10 | const u64_intFromFloat_f16 = impl.u64_intFromFloat_f16; | |
| 11 | const i128_intFromFloat_f16 = impl.i128_intFromFloat_f16; | |
| 12 | const u128_intFromFloat_f16 = impl.u128_intFromFloat_f16; | |
| 13 | const signed_intFromFloat_f16 = impl.signed_intFromFloat_f16; | |
| 14 | const unsigned_intFromFloat_f16 = impl.unsigned_intFromFloat_f16; | |
| 15 | ||
| 16 | const i32_intFromFloat_f32 = impl.i32_intFromFloat_f32; | |
| 17 | const u32_intFromFloat_f32 = impl.u32_intFromFloat_f32; | |
| 18 | const i64_intFromFloat_f32 = impl.i64_intFromFloat_f32; | |
| 19 | const u64_intFromFloat_f32 = impl.u64_intFromFloat_f32; | |
| 20 | const i128_intFromFloat_f32 = impl.i128_intFromFloat_f32; | |
| 21 | const u128_intFromFloat_f32 = impl.u128_intFromFloat_f32; | |
| 22 | const signed_intFromFloat_f32 = impl.signed_intFromFloat_f32; | |
| 23 | const unsigned_intFromFloat_f32 = impl.unsigned_intFromFloat_f32; | |
| 24 | ||
| 25 | const i32_intFromFloat_f64 = impl.i32_intFromFloat_f64; | |
| 26 | const u32_intFromFloat_f64 = impl.u32_intFromFloat_f64; | |
| 27 | const i64_intFromFloat_f64 = impl.i64_intFromFloat_f64; | |
| 28 | const u64_intFromFloat_f64 = impl.u64_intFromFloat_f64; | |
| 29 | const i128_intFromFloat_f64 = impl.i128_intFromFloat_f64; | |
| 30 | const u128_intFromFloat_f64 = impl.u128_intFromFloat_f64; | |
| 31 | const signed_intFromFloat_f64 = impl.signed_intFromFloat_f64; | |
| 32 | const unsigned_intFromFloat_f64 = impl.unsigned_intFromFloat_f64; | |
| 33 | ||
| 34 | const i32_intFromFloat_f80 = impl.i32_intFromFloat_f80; | |
| 35 | const u32_intFromFloat_f80 = impl.u32_intFromFloat_f80; | |
| 36 | const i64_intFromFloat_f80 = impl.i64_intFromFloat_f80; | |
| 37 | const u64_intFromFloat_f80 = impl.u64_intFromFloat_f80; | |
| 38 | const i128_intFromFloat_f80 = impl.i128_intFromFloat_f80; | |
| 39 | const u128_intFromFloat_f80 = impl.u128_intFromFloat_f80; | |
| 40 | const signed_intFromFloat_f80 = impl.signed_intFromFloat_f80; | |
| 41 | const unsigned_intFromFloat_f80 = impl.unsigned_intFromFloat_f80; | |
| 42 | ||
| 43 | const i32_intFromFloat_f128 = impl.i32_intFromFloat_f128; | |
| 44 | const u32_intFromFloat_f128 = impl.u32_intFromFloat_f128; | |
| 45 | const i64_intFromFloat_f128 = impl.i64_intFromFloat_f128; | |
| 46 | const u64_intFromFloat_f128 = impl.u64_intFromFloat_f128; | |
| 47 | const i128_intFromFloat_f128 = impl.i128_intFromFloat_f128; | |
| 48 | const u128_intFromFloat_f128 = impl.u128_intFromFloat_f128; | |
| 49 | const signed_intFromFloat_f128 = impl.signed_intFromFloat_f128; | |
| 50 | const unsigned_intFromFloat_f128 = impl.unsigned_intFromFloat_f128; | |
| 51 | ||
| 52 | fn test_i32_intFromFloat_f32(a: f32, expected: i32) !void { | |
| 53 | const x = i32_intFromFloat_f32(a); | |
| 38 | 54 | try testing.expect(x == expected); |
| 39 | 55 | } |
| 40 | 56 | |
| 41 | fn test__fixunssfsi(a: f32, expected: u32) !void { | |
| 42 | const x = __fixunssfsi(a); | |
| 57 | fn test_u32_intFromFloat_f32(a: f32, expected: u32) !void { | |
| 58 | const x = u32_intFromFloat_f32(a); | |
| 43 | 59 | try testing.expect(x == expected); |
| 44 | 60 | } |
| 45 | 61 | |
| 46 | test "fixsfsi" { | |
| 47 | try test__fixsfsi(-math.floatMax(f32), math.minInt(i32)); | |
| 48 | ||
| 49 | try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); | |
| 50 | try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); | |
| 51 | ||
| 52 | try test__fixsfsi(-0x1.0000000000000p+127, -0x80000000); | |
| 53 | try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); | |
| 54 | try test__fixsfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); | |
| 55 | ||
| 56 | try test__fixsfsi(-0x1.0000000000001p+63, -0x80000000); | |
| 57 | try test__fixsfsi(-0x1.0000000000000p+63, -0x80000000); | |
| 58 | try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); | |
| 59 | try test__fixsfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); | |
| 60 | ||
| 61 | try test__fixsfsi(-0x1.FFFFFEp+62, -0x80000000); | |
| 62 | try test__fixsfsi(-0x1.FFFFFCp+62, -0x80000000); | |
| 63 | ||
| 64 | try test__fixsfsi(-0x1.000000p+31, -0x80000000); | |
| 65 | try test__fixsfsi(-0x1.FFFFFFp+30, -0x80000000); | |
| 66 | try test__fixsfsi(-0x1.FFFFFEp+30, -0x7FFFFF80); | |
| 67 | try test__fixsfsi(-0x1.FFFFFCp+30, -0x7FFFFF00); | |
| 68 | ||
| 69 | try test__fixsfsi(-2.01, -2); | |
| 70 | try test__fixsfsi(-2.0, -2); | |
| 71 | try test__fixsfsi(-1.99, -1); | |
| 72 | try test__fixsfsi(-1.0, -1); | |
| 73 | try test__fixsfsi(-0.99, 0); | |
| 74 | try test__fixsfsi(-0.5, 0); | |
| 75 | ||
| 76 | try test__fixsfsi(-math.floatMin(f32), 0); | |
| 77 | try test__fixsfsi(0.0, 0); | |
| 78 | try test__fixsfsi(math.floatMin(f32), 0); | |
| 79 | try test__fixsfsi(0.5, 0); | |
| 80 | try test__fixsfsi(0.99, 0); | |
| 81 | try test__fixsfsi(1.0, 1); | |
| 82 | try test__fixsfsi(1.5, 1); | |
| 83 | try test__fixsfsi(1.99, 1); | |
| 84 | try test__fixsfsi(2.0, 2); | |
| 85 | try test__fixsfsi(2.01, 2); | |
| 86 | ||
| 87 | try test__fixsfsi(0x1.FFFFFCp+30, 0x7FFFFF00); | |
| 88 | try test__fixsfsi(0x1.FFFFFEp+30, 0x7FFFFF80); | |
| 89 | try test__fixsfsi(0x1.FFFFFFp+30, 0x7FFFFFFF); | |
| 90 | try test__fixsfsi(0x1.000000p+31, 0x7FFFFFFF); | |
| 91 | ||
| 92 | try test__fixsfsi(0x1.FFFFFCp+62, 0x7FFFFFFF); | |
| 93 | try test__fixsfsi(0x1.FFFFFEp+62, 0x7FFFFFFF); | |
| 94 | ||
| 95 | try test__fixsfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); | |
| 96 | try test__fixsfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); | |
| 97 | try test__fixsfsi(0x1.0000000000000p+63, 0x7FFFFFFF); | |
| 98 | try test__fixsfsi(0x1.0000000000001p+63, 0x7FFFFFFF); | |
| 99 | ||
| 100 | try test__fixsfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); | |
| 101 | try test__fixsfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); | |
| 102 | try test__fixsfsi(0x1.0000000000000p+127, 0x7FFFFFFF); | |
| 103 | ||
| 104 | try test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); | |
| 105 | try test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); | |
| 106 | ||
| 107 | try test__fixsfsi(math.floatMax(f32), math.maxInt(i32)); | |
| 62 | test i32_intFromFloat_f32 { | |
| 63 | try test_i32_intFromFloat_f32(-math.floatMax(f32), math.minInt(i32)); | |
| 64 | ||
| 65 | try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); | |
| 66 | try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); | |
| 67 | ||
| 68 | try test_i32_intFromFloat_f32(-0x1.0000000000000p+127, -0x80000000); | |
| 69 | try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); | |
| 70 | try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); | |
| 71 | ||
| 72 | try test_i32_intFromFloat_f32(-0x1.0000000000001p+63, -0x80000000); | |
| 73 | try test_i32_intFromFloat_f32(-0x1.0000000000000p+63, -0x80000000); | |
| 74 | try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); | |
| 75 | try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); | |
| 76 | ||
| 77 | try test_i32_intFromFloat_f32(-0x1.FFFFFEp+62, -0x80000000); | |
| 78 | try test_i32_intFromFloat_f32(-0x1.FFFFFCp+62, -0x80000000); | |
| 79 | ||
| 80 | try test_i32_intFromFloat_f32(-0x1.000000p+31, -0x80000000); | |
| 81 | try test_i32_intFromFloat_f32(-0x1.FFFFFFp+30, -0x80000000); | |
| 82 | try test_i32_intFromFloat_f32(-0x1.FFFFFEp+30, -0x7FFFFF80); | |
| 83 | try test_i32_intFromFloat_f32(-0x1.FFFFFCp+30, -0x7FFFFF00); | |
| 84 | ||
| 85 | try test_i32_intFromFloat_f32(-2.01, -2); | |
| 86 | try test_i32_intFromFloat_f32(-2.0, -2); | |
| 87 | try test_i32_intFromFloat_f32(-1.99, -1); | |
| 88 | try test_i32_intFromFloat_f32(-1.0, -1); | |
| 89 | try test_i32_intFromFloat_f32(-0.99, 0); | |
| 90 | try test_i32_intFromFloat_f32(-0.5, 0); | |
| 91 | ||
| 92 | try test_i32_intFromFloat_f32(-math.floatMin(f32), 0); | |
| 93 | try test_i32_intFromFloat_f32(0.0, 0); | |
| 94 | try test_i32_intFromFloat_f32(math.floatMin(f32), 0); | |
| 95 | try test_i32_intFromFloat_f32(0.5, 0); | |
| 96 | try test_i32_intFromFloat_f32(0.99, 0); | |
| 97 | try test_i32_intFromFloat_f32(1.0, 1); | |
| 98 | try test_i32_intFromFloat_f32(1.5, 1); | |
| 99 | try test_i32_intFromFloat_f32(1.99, 1); | |
| 100 | try test_i32_intFromFloat_f32(2.0, 2); | |
| 101 | try test_i32_intFromFloat_f32(2.01, 2); | |
| 102 | ||
| 103 | try test_i32_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00); | |
| 104 | try test_i32_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80); | |
| 105 | try test_i32_intFromFloat_f32(0x1.FFFFFFp+30, 0x7FFFFFFF); | |
| 106 | try test_i32_intFromFloat_f32(0x1.000000p+31, 0x7FFFFFFF); | |
| 107 | ||
| 108 | try test_i32_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFFFF); | |
| 109 | try test_i32_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFFFF); | |
| 110 | ||
| 111 | try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); | |
| 112 | try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); | |
| 113 | try test_i32_intFromFloat_f32(0x1.0000000000000p+63, 0x7FFFFFFF); | |
| 114 | try test_i32_intFromFloat_f32(0x1.0000000000001p+63, 0x7FFFFFFF); | |
| 115 | ||
| 116 | try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); | |
| 117 | try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); | |
| 118 | try test_i32_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFF); | |
| 119 | ||
| 120 | try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); | |
| 121 | try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); | |
| 122 | ||
| 123 | try test_i32_intFromFloat_f32(math.floatMax(f32), math.maxInt(i32)); | |
| 108 | 124 | } |
| 109 | 125 | |
| 110 | test "fixunssfsi" { | |
| 111 | try test__fixunssfsi(0.0, 0); | |
| 112 | ||
| 113 | try test__fixunssfsi(0.5, 0); | |
| 114 | try test__fixunssfsi(0.99, 0); | |
| 115 | try test__fixunssfsi(1.0, 1); | |
| 116 | try test__fixunssfsi(1.5, 1); | |
| 117 | try test__fixunssfsi(1.99, 1); | |
| 118 | try test__fixunssfsi(2.0, 2); | |
| 119 | try test__fixunssfsi(2.01, 2); | |
| 120 | try test__fixunssfsi(-0.5, 0); | |
| 121 | try test__fixunssfsi(-0.99, 0); | |
| 122 | ||
| 123 | try test__fixunssfsi(-1.0, 0); | |
| 124 | try test__fixunssfsi(-1.5, 0); | |
| 125 | try test__fixunssfsi(-1.99, 0); | |
| 126 | try test__fixunssfsi(-2.0, 0); | |
| 127 | try test__fixunssfsi(-2.01, 0); | |
| 128 | ||
| 129 | try test__fixunssfsi(0x1.000000p+31, 0x80000000); | |
| 130 | try test__fixunssfsi(0x1.000000p+32, 0xFFFFFFFF); | |
| 131 | try test__fixunssfsi(0x1.FFFFFEp+31, 0xFFFFFF00); | |
| 132 | try test__fixunssfsi(0x1.FFFFFEp+30, 0x7FFFFF80); | |
| 133 | try test__fixunssfsi(0x1.FFFFFCp+30, 0x7FFFFF00); | |
| 134 | ||
| 135 | try test__fixunssfsi(-0x1.FFFFFEp+30, 0); | |
| 136 | try test__fixunssfsi(-0x1.FFFFFCp+30, 0); | |
| 126 | test u32_intFromFloat_f32 { | |
| 127 | try test_u32_intFromFloat_f32(0.0, 0); | |
| 128 | ||
| 129 | try test_u32_intFromFloat_f32(0.5, 0); | |
| 130 | try test_u32_intFromFloat_f32(0.99, 0); | |
| 131 | try test_u32_intFromFloat_f32(1.0, 1); | |
| 132 | try test_u32_intFromFloat_f32(1.5, 1); | |
| 133 | try test_u32_intFromFloat_f32(1.99, 1); | |
| 134 | try test_u32_intFromFloat_f32(2.0, 2); | |
| 135 | try test_u32_intFromFloat_f32(2.01, 2); | |
| 136 | try test_u32_intFromFloat_f32(-0.5, 0); | |
| 137 | try test_u32_intFromFloat_f32(-0.99, 0); | |
| 138 | ||
| 139 | try test_u32_intFromFloat_f32(-1.0, 0); | |
| 140 | try test_u32_intFromFloat_f32(-1.5, 0); | |
| 141 | try test_u32_intFromFloat_f32(-1.99, 0); | |
| 142 | try test_u32_intFromFloat_f32(-2.0, 0); | |
| 143 | try test_u32_intFromFloat_f32(-2.01, 0); | |
| 144 | ||
| 145 | try test_u32_intFromFloat_f32(0x1.000000p+31, 0x80000000); | |
| 146 | try test_u32_intFromFloat_f32(0x1.000000p+32, 0xFFFFFFFF); | |
| 147 | try test_u32_intFromFloat_f32(0x1.FFFFFEp+31, 0xFFFFFF00); | |
| 148 | try test_u32_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80); | |
| 149 | try test_u32_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00); | |
| 150 | ||
| 151 | try test_u32_intFromFloat_f32(-0x1.FFFFFEp+30, 0); | |
| 152 | try test_u32_intFromFloat_f32(-0x1.FFFFFCp+30, 0); | |
| 137 | 153 | } |
| 138 | 154 | |
| 139 | fn test__fixsfdi(a: f32, expected: i64) !void { | |
| 140 | const x = __fixsfdi(a); | |
| 155 | fn test_i64_intFromFloat_f32(a: f32, expected: i64) !void { | |
| 156 | const x = i64_intFromFloat_f32(a); | |
| 141 | 157 | try testing.expect(x == expected); |
| 142 | 158 | } |
| 143 | 159 | |
| 144 | fn test__fixunssfdi(a: f32, expected: u64) !void { | |
| 145 | const x = __fixunssfdi(a); | |
| 160 | fn test_u64_intFromFloat_f32(a: f32, expected: u64) !void { | |
| 161 | const x = u64_intFromFloat_f32(a); | |
| 146 | 162 | try testing.expect(x == expected); |
| 147 | 163 | } |
| 148 | 164 | |
| 149 | test "fixsfdi" { | |
| 150 | try test__fixsfdi(-math.floatMax(f32), math.minInt(i64)); | |
| 151 | ||
| 152 | try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); | |
| 153 | try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); | |
| 154 | ||
| 155 | try test__fixsfdi(-0x1.0000000000000p+127, -0x8000000000000000); | |
| 156 | try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); | |
| 157 | try test__fixsfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); | |
| 158 | ||
| 159 | try test__fixsfdi(-0x1.0000000000001p+63, -0x8000000000000000); | |
| 160 | try test__fixsfdi(-0x1.0000000000000p+63, -0x8000000000000000); | |
| 161 | try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000); | |
| 162 | try test__fixsfdi(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000); | |
| 163 | ||
| 164 | try test__fixsfdi(-0x1.FFFFFFp+62, -0x8000000000000000); | |
| 165 | try test__fixsfdi(-0x1.FFFFFEp+62, -0x7fffff8000000000); | |
| 166 | try test__fixsfdi(-0x1.FFFFFCp+62, -0x7fffff0000000000); | |
| 167 | ||
| 168 | try test__fixsfdi(-2.01, -2); | |
| 169 | try test__fixsfdi(-2.0, -2); | |
| 170 | try test__fixsfdi(-1.99, -1); | |
| 171 | try test__fixsfdi(-1.0, -1); | |
| 172 | try test__fixsfdi(-0.99, 0); | |
| 173 | try test__fixsfdi(-0.5, 0); | |
| 174 | try test__fixsfdi(-math.floatMin(f32), 0); | |
| 175 | try test__fixsfdi(0.0, 0); | |
| 176 | try test__fixsfdi(math.floatMin(f32), 0); | |
| 177 | try test__fixsfdi(0.5, 0); | |
| 178 | try test__fixsfdi(0.99, 0); | |
| 179 | try test__fixsfdi(1.0, 1); | |
| 180 | try test__fixsfdi(1.5, 1); | |
| 181 | try test__fixsfdi(1.99, 1); | |
| 182 | try test__fixsfdi(2.0, 2); | |
| 183 | try test__fixsfdi(2.01, 2); | |
| 184 | ||
| 185 | try test__fixsfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 186 | try test__fixsfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 187 | try test__fixsfdi(0x1.FFFFFFp+62, 0x7FFFFFFFFFFFFFFF); | |
| 188 | ||
| 189 | try test__fixsfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFFFFF); | |
| 190 | try test__fixsfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFFFF); | |
| 191 | try test__fixsfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); | |
| 192 | try test__fixsfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); | |
| 193 | ||
| 194 | try test__fixsfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); | |
| 195 | try test__fixsfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); | |
| 196 | try test__fixsfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); | |
| 197 | ||
| 198 | try test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); | |
| 199 | try test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); | |
| 200 | ||
| 201 | try test__fixsfdi(math.floatMax(f32), math.maxInt(i64)); | |
| 165 | test i64_intFromFloat_f32 { | |
| 166 | try test_i64_intFromFloat_f32(-math.floatMax(f32), math.minInt(i64)); | |
| 167 | ||
| 168 | try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); | |
| 169 | try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); | |
| 170 | ||
| 171 | try test_i64_intFromFloat_f32(-0x1.0000000000000p+127, -0x8000000000000000); | |
| 172 | try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); | |
| 173 | try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); | |
| 174 | ||
| 175 | try test_i64_intFromFloat_f32(-0x1.0000000000001p+63, -0x8000000000000000); | |
| 176 | try test_i64_intFromFloat_f32(-0x1.0000000000000p+63, -0x8000000000000000); | |
| 177 | try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000); | |
| 178 | try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000); | |
| 179 | ||
| 180 | try test_i64_intFromFloat_f32(-0x1.FFFFFFp+62, -0x8000000000000000); | |
| 181 | try test_i64_intFromFloat_f32(-0x1.FFFFFEp+62, -0x7fffff8000000000); | |
| 182 | try test_i64_intFromFloat_f32(-0x1.FFFFFCp+62, -0x7fffff0000000000); | |
| 183 | ||
| 184 | try test_i64_intFromFloat_f32(-2.01, -2); | |
| 185 | try test_i64_intFromFloat_f32(-2.0, -2); | |
| 186 | try test_i64_intFromFloat_f32(-1.99, -1); | |
| 187 | try test_i64_intFromFloat_f32(-1.0, -1); | |
| 188 | try test_i64_intFromFloat_f32(-0.99, 0); | |
| 189 | try test_i64_intFromFloat_f32(-0.5, 0); | |
| 190 | try test_i64_intFromFloat_f32(-math.floatMin(f32), 0); | |
| 191 | try test_i64_intFromFloat_f32(0.0, 0); | |
| 192 | try test_i64_intFromFloat_f32(math.floatMin(f32), 0); | |
| 193 | try test_i64_intFromFloat_f32(0.5, 0); | |
| 194 | try test_i64_intFromFloat_f32(0.99, 0); | |
| 195 | try test_i64_intFromFloat_f32(1.0, 1); | |
| 196 | try test_i64_intFromFloat_f32(1.5, 1); | |
| 197 | try test_i64_intFromFloat_f32(1.99, 1); | |
| 198 | try test_i64_intFromFloat_f32(2.0, 2); | |
| 199 | try test_i64_intFromFloat_f32(2.01, 2); | |
| 200 | ||
| 201 | try test_i64_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 202 | try test_i64_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 203 | try test_i64_intFromFloat_f32(0x1.FFFFFFp+62, 0x7FFFFFFFFFFFFFFF); | |
| 204 | ||
| 205 | try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFFFFF); | |
| 206 | try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFFFF); | |
| 207 | try test_i64_intFromFloat_f32(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); | |
| 208 | try test_i64_intFromFloat_f32(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); | |
| 209 | ||
| 210 | try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); | |
| 211 | try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); | |
| 212 | try test_i64_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); | |
| 213 | ||
| 214 | try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); | |
| 215 | try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); | |
| 216 | ||
| 217 | try test_i64_intFromFloat_f32(math.floatMax(f32), math.maxInt(i64)); | |
| 202 | 218 | } |
| 203 | 219 | |
| 204 | test "fixunssfdi" { | |
| 205 | try test__fixunssfdi(0.0, 0); | |
| 206 | ||
| 207 | try test__fixunssfdi(0.5, 0); | |
| 208 | try test__fixunssfdi(0.99, 0); | |
| 209 | try test__fixunssfdi(1.0, 1); | |
| 210 | try test__fixunssfdi(1.5, 1); | |
| 211 | try test__fixunssfdi(1.99, 1); | |
| 212 | try test__fixunssfdi(2.0, 2); | |
| 213 | try test__fixunssfdi(2.01, 2); | |
| 214 | try test__fixunssfdi(-0.5, 0); | |
| 215 | try test__fixunssfdi(-0.99, 0); | |
| 216 | ||
| 217 | try test__fixunssfdi(-1.0, 0); | |
| 218 | try test__fixunssfdi(-1.5, 0); | |
| 219 | try test__fixunssfdi(-1.99, 0); | |
| 220 | try test__fixunssfdi(-2.0, 0); | |
| 221 | try test__fixunssfdi(-2.01, 0); | |
| 222 | ||
| 223 | try test__fixunssfdi(0x1.FFFFFEp+63, 0xFFFFFF0000000000); | |
| 224 | try test__fixunssfdi(0x1.000000p+63, 0x8000000000000000); | |
| 225 | try test__fixunssfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 226 | try test__fixunssfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 227 | ||
| 228 | try test__fixunssfdi(-0x1.FFFFFEp+62, 0x0000000000000000); | |
| 229 | try test__fixunssfdi(-0x1.FFFFFCp+62, 0x0000000000000000); | |
| 220 | test u64_intFromFloat_f32 { | |
| 221 | try test_u64_intFromFloat_f32(0.0, 0); | |
| 222 | ||
| 223 | try test_u64_intFromFloat_f32(0.5, 0); | |
| 224 | try test_u64_intFromFloat_f32(0.99, 0); | |
| 225 | try test_u64_intFromFloat_f32(1.0, 1); | |
| 226 | try test_u64_intFromFloat_f32(1.5, 1); | |
| 227 | try test_u64_intFromFloat_f32(1.99, 1); | |
| 228 | try test_u64_intFromFloat_f32(2.0, 2); | |
| 229 | try test_u64_intFromFloat_f32(2.01, 2); | |
| 230 | try test_u64_intFromFloat_f32(-0.5, 0); | |
| 231 | try test_u64_intFromFloat_f32(-0.99, 0); | |
| 232 | ||
| 233 | try test_u64_intFromFloat_f32(-1.0, 0); | |
| 234 | try test_u64_intFromFloat_f32(-1.5, 0); | |
| 235 | try test_u64_intFromFloat_f32(-1.99, 0); | |
| 236 | try test_u64_intFromFloat_f32(-2.0, 0); | |
| 237 | try test_u64_intFromFloat_f32(-2.01, 0); | |
| 238 | ||
| 239 | try test_u64_intFromFloat_f32(0x1.FFFFFEp+63, 0xFFFFFF0000000000); | |
| 240 | try test_u64_intFromFloat_f32(0x1.000000p+63, 0x8000000000000000); | |
| 241 | try test_u64_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 242 | try test_u64_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 243 | ||
| 244 | try test_u64_intFromFloat_f32(-0x1.FFFFFEp+62, 0x0000000000000000); | |
| 245 | try test_u64_intFromFloat_f32(-0x1.FFFFFCp+62, 0x0000000000000000); | |
| 230 | 246 | } |
| 231 | 247 | |
| 232 | fn test__fixsfti(a: f32, expected: i128) !void { | |
| 233 | const x = __fixsfti(a); | |
| 248 | fn test_i128_intFromFloat_f32(a: f32, expected: i128) !void { | |
| 249 | const x = i128_intFromFloat_f32(a); | |
| 234 | 250 | try testing.expect(x == expected); |
| 235 | 251 | } |
| 236 | 252 | |
| 237 | fn test__fixunssfti(a: f32, expected: u128) !void { | |
| 238 | const x = __fixunssfti(a); | |
| 253 | fn test_u128_intFromFloat_f32(a: f32, expected: u128) !void { | |
| 254 | const x = u128_intFromFloat_f32(a); | |
| 239 | 255 | try testing.expect(x == expected); |
| 240 | 256 | } |
| 241 | 257 | |
| 242 | test "fixsfti" { | |
| 243 | try test__fixsfti(-math.floatMax(f32), math.minInt(i128)); | |
| 244 | ||
| 245 | try test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); | |
| 246 | try test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); | |
| 247 | ||
| 248 | try test__fixsfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); | |
| 249 | try test__fixsfti(-0x1.FFFFFFFFFFFFFp+126, -0x80000000000000000000000000000000); | |
| 250 | try test__fixsfti(-0x1.FFFFFFFFFFFFEp+126, -0x80000000000000000000000000000000); | |
| 251 | try test__fixsfti(-0x1.FFFFFF0000000p+126, -0x80000000000000000000000000000000); | |
| 252 | try test__fixsfti(-0x1.FFFFFE0000000p+126, -0x7FFFFF80000000000000000000000000); | |
| 253 | try test__fixsfti(-0x1.FFFFFC0000000p+126, -0x7FFFFF00000000000000000000000000); | |
| 254 | ||
| 255 | try test__fixsfti(-0x1.0000000000001p+63, -0x8000000000000000); | |
| 256 | try test__fixsfti(-0x1.0000000000000p+63, -0x8000000000000000); | |
| 257 | try test__fixsfti(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000); | |
| 258 | try test__fixsfti(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000); | |
| 259 | ||
| 260 | try test__fixsfti(-0x1.FFFFFFp+62, -0x8000000000000000); | |
| 261 | try test__fixsfti(-0x1.FFFFFEp+62, -0x7fffff8000000000); | |
| 262 | try test__fixsfti(-0x1.FFFFFCp+62, -0x7fffff0000000000); | |
| 263 | ||
| 264 | try test__fixsfti(-0x1.000000p+31, -0x80000000); | |
| 265 | try test__fixsfti(-0x1.FFFFFFp+30, -0x80000000); | |
| 266 | try test__fixsfti(-0x1.FFFFFEp+30, -0x7FFFFF80); | |
| 267 | try test__fixsfti(-0x1.FFFFFCp+30, -0x7FFFFF00); | |
| 268 | ||
| 269 | try test__fixsfti(-2.01, -2); | |
| 270 | try test__fixsfti(-2.0, -2); | |
| 271 | try test__fixsfti(-1.99, -1); | |
| 272 | try test__fixsfti(-1.0, -1); | |
| 273 | try test__fixsfti(-0.99, 0); | |
| 274 | try test__fixsfti(-0.5, 0); | |
| 275 | try test__fixsfti(-math.floatMin(f32), 0); | |
| 276 | try test__fixsfti(0.0, 0); | |
| 277 | try test__fixsfti(math.floatMin(f32), 0); | |
| 278 | try test__fixsfti(0.5, 0); | |
| 279 | try test__fixsfti(0.99, 0); | |
| 280 | try test__fixsfti(1.0, 1); | |
| 281 | try test__fixsfti(1.5, 1); | |
| 282 | try test__fixsfti(1.99, 1); | |
| 283 | try test__fixsfti(2.0, 2); | |
| 284 | try test__fixsfti(2.01, 2); | |
| 285 | ||
| 286 | try test__fixsfti(0x1.FFFFFCp+30, 0x7FFFFF00); | |
| 287 | try test__fixsfti(0x1.FFFFFEp+30, 0x7FFFFF80); | |
| 288 | try test__fixsfti(0x1.FFFFFFp+30, 0x80000000); | |
| 289 | try test__fixsfti(0x1.000000p+31, 0x80000000); | |
| 290 | ||
| 291 | try test__fixsfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 292 | try test__fixsfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 293 | try test__fixsfti(0x1.FFFFFFp+62, 0x8000000000000000); | |
| 294 | ||
| 295 | try test__fixsfti(0x1.FFFFFFFFFFFFEp+62, 0x8000000000000000); | |
| 296 | try test__fixsfti(0x1.FFFFFFFFFFFFFp+62, 0x8000000000000000); | |
| 297 | try test__fixsfti(0x1.0000000000000p+63, 0x8000000000000000); | |
| 298 | try test__fixsfti(0x1.0000000000001p+63, 0x8000000000000000); | |
| 299 | ||
| 300 | try test__fixsfti(0x1.FFFFFC0000000p+126, 0x7FFFFF00000000000000000000000000); | |
| 301 | try test__fixsfti(0x1.FFFFFE0000000p+126, 0x7FFFFF80000000000000000000000000); | |
| 302 | try test__fixsfti(0x1.FFFFFF0000000p+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 303 | try test__fixsfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 304 | try test__fixsfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 305 | try test__fixsfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 306 | ||
| 307 | try test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 308 | try test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); | |
| 309 | ||
| 310 | try test__fixsfti(math.floatMax(f32), math.maxInt(i128)); | |
| 258 | test i128_intFromFloat_f32 { | |
| 259 | try test_i128_intFromFloat_f32(-math.floatMax(f32), math.minInt(i128)); | |
| 260 | ||
| 261 | try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); | |
| 262 | try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); | |
| 263 | ||
| 264 | try test_i128_intFromFloat_f32(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); | |
| 265 | try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x80000000000000000000000000000000); | |
| 266 | try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x80000000000000000000000000000000); | |
| 267 | try test_i128_intFromFloat_f32(-0x1.FFFFFF0000000p+126, -0x80000000000000000000000000000000); | |
| 268 | try test_i128_intFromFloat_f32(-0x1.FFFFFE0000000p+126, -0x7FFFFF80000000000000000000000000); | |
| 269 | try test_i128_intFromFloat_f32(-0x1.FFFFFC0000000p+126, -0x7FFFFF00000000000000000000000000); | |
| 270 | ||
| 271 | try test_i128_intFromFloat_f32(-0x1.0000000000001p+63, -0x8000000000000000); | |
| 272 | try test_i128_intFromFloat_f32(-0x1.0000000000000p+63, -0x8000000000000000); | |
| 273 | try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000); | |
| 274 | try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000); | |
| 275 | ||
| 276 | try test_i128_intFromFloat_f32(-0x1.FFFFFFp+62, -0x8000000000000000); | |
| 277 | try test_i128_intFromFloat_f32(-0x1.FFFFFEp+62, -0x7fffff8000000000); | |
| 278 | try test_i128_intFromFloat_f32(-0x1.FFFFFCp+62, -0x7fffff0000000000); | |
| 279 | ||
| 280 | try test_i128_intFromFloat_f32(-0x1.000000p+31, -0x80000000); | |
| 281 | try test_i128_intFromFloat_f32(-0x1.FFFFFFp+30, -0x80000000); | |
| 282 | try test_i128_intFromFloat_f32(-0x1.FFFFFEp+30, -0x7FFFFF80); | |
| 283 | try test_i128_intFromFloat_f32(-0x1.FFFFFCp+30, -0x7FFFFF00); | |
| 284 | ||
| 285 | try test_i128_intFromFloat_f32(-2.01, -2); | |
| 286 | try test_i128_intFromFloat_f32(-2.0, -2); | |
| 287 | try test_i128_intFromFloat_f32(-1.99, -1); | |
| 288 | try test_i128_intFromFloat_f32(-1.0, -1); | |
| 289 | try test_i128_intFromFloat_f32(-0.99, 0); | |
| 290 | try test_i128_intFromFloat_f32(-0.5, 0); | |
| 291 | try test_i128_intFromFloat_f32(-math.floatMin(f32), 0); | |
| 292 | try test_i128_intFromFloat_f32(0.0, 0); | |
| 293 | try test_i128_intFromFloat_f32(math.floatMin(f32), 0); | |
| 294 | try test_i128_intFromFloat_f32(0.5, 0); | |
| 295 | try test_i128_intFromFloat_f32(0.99, 0); | |
| 296 | try test_i128_intFromFloat_f32(1.0, 1); | |
| 297 | try test_i128_intFromFloat_f32(1.5, 1); | |
| 298 | try test_i128_intFromFloat_f32(1.99, 1); | |
| 299 | try test_i128_intFromFloat_f32(2.0, 2); | |
| 300 | try test_i128_intFromFloat_f32(2.01, 2); | |
| 301 | ||
| 302 | try test_i128_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00); | |
| 303 | try test_i128_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80); | |
| 304 | try test_i128_intFromFloat_f32(0x1.FFFFFFp+30, 0x80000000); | |
| 305 | try test_i128_intFromFloat_f32(0x1.000000p+31, 0x80000000); | |
| 306 | ||
| 307 | try test_i128_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 308 | try test_i128_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 309 | try test_i128_intFromFloat_f32(0x1.FFFFFFp+62, 0x8000000000000000); | |
| 310 | ||
| 311 | try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x8000000000000000); | |
| 312 | try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x8000000000000000); | |
| 313 | try test_i128_intFromFloat_f32(0x1.0000000000000p+63, 0x8000000000000000); | |
| 314 | try test_i128_intFromFloat_f32(0x1.0000000000001p+63, 0x8000000000000000); | |
| 315 | ||
| 316 | try test_i128_intFromFloat_f32(0x1.FFFFFC0000000p+126, 0x7FFFFF00000000000000000000000000); | |
| 317 | try test_i128_intFromFloat_f32(0x1.FFFFFE0000000p+126, 0x7FFFFF80000000000000000000000000); | |
| 318 | try test_i128_intFromFloat_f32(0x1.FFFFFF0000000p+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 319 | try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 320 | try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 321 | try test_i128_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 322 | ||
| 323 | try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 324 | try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); | |
| 325 | ||
| 326 | try test_i128_intFromFloat_f32(math.floatMax(f32), math.maxInt(i128)); | |
| 311 | 327 | } |
| 312 | 328 | |
| 313 | test "fixunssfti" { | |
| 314 | try test__fixunssfti(0.0, 0); | |
| 315 | ||
| 316 | try test__fixunssfti(0.5, 0); | |
| 317 | try test__fixunssfti(0.99, 0); | |
| 318 | try test__fixunssfti(1.0, 1); | |
| 319 | try test__fixunssfti(1.5, 1); | |
| 320 | try test__fixunssfti(1.99, 1); | |
| 321 | try test__fixunssfti(2.0, 2); | |
| 322 | try test__fixunssfti(2.01, 2); | |
| 323 | try test__fixunssfti(-0.5, 0); | |
| 324 | try test__fixunssfti(-0.99, 0); | |
| 325 | ||
| 326 | try test__fixunssfti(-1.0, 0); | |
| 327 | try test__fixunssfti(-1.5, 0); | |
| 328 | try test__fixunssfti(-1.99, 0); | |
| 329 | try test__fixunssfti(-2.0, 0); | |
| 330 | try test__fixunssfti(-2.01, 0); | |
| 331 | ||
| 332 | try test__fixunssfti(0x1.FFFFFEp+63, 0xFFFFFF0000000000); | |
| 333 | try test__fixunssfti(0x1.000000p+63, 0x8000000000000000); | |
| 334 | try test__fixunssfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 335 | try test__fixunssfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 336 | try test__fixunssfti(0x1.FFFFFEp+127, 0xFFFFFF00000000000000000000000000); | |
| 337 | try test__fixunssfti(0x1.000000p+127, 0x80000000000000000000000000000000); | |
| 338 | try test__fixunssfti(0x1.FFFFFEp+126, 0x7FFFFF80000000000000000000000000); | |
| 339 | try test__fixunssfti(0x1.FFFFFCp+126, 0x7FFFFF00000000000000000000000000); | |
| 340 | ||
| 341 | try test__fixunssfti(-0x1.FFFFFEp+62, 0x0000000000000000); | |
| 342 | try test__fixunssfti(-0x1.FFFFFCp+62, 0x0000000000000000); | |
| 343 | try test__fixunssfti(-0x1.FFFFFEp+126, 0x0000000000000000); | |
| 344 | try test__fixunssfti(-0x1.FFFFFCp+126, 0x0000000000000000); | |
| 345 | try test__fixunssfti(math.floatMax(f32), 0xffffff00000000000000000000000000); | |
| 346 | try test__fixunssfti(math.inf(f32), math.maxInt(u128)); | |
| 329 | test u128_intFromFloat_f32 { | |
| 330 | try test_u128_intFromFloat_f32(0.0, 0); | |
| 331 | ||
| 332 | try test_u128_intFromFloat_f32(0.5, 0); | |
| 333 | try test_u128_intFromFloat_f32(0.99, 0); | |
| 334 | try test_u128_intFromFloat_f32(1.0, 1); | |
| 335 | try test_u128_intFromFloat_f32(1.5, 1); | |
| 336 | try test_u128_intFromFloat_f32(1.99, 1); | |
| 337 | try test_u128_intFromFloat_f32(2.0, 2); | |
| 338 | try test_u128_intFromFloat_f32(2.01, 2); | |
| 339 | try test_u128_intFromFloat_f32(-0.5, 0); | |
| 340 | try test_u128_intFromFloat_f32(-0.99, 0); | |
| 341 | ||
| 342 | try test_u128_intFromFloat_f32(-1.0, 0); | |
| 343 | try test_u128_intFromFloat_f32(-1.5, 0); | |
| 344 | try test_u128_intFromFloat_f32(-1.99, 0); | |
| 345 | try test_u128_intFromFloat_f32(-2.0, 0); | |
| 346 | try test_u128_intFromFloat_f32(-2.01, 0); | |
| 347 | ||
| 348 | try test_u128_intFromFloat_f32(0x1.FFFFFEp+63, 0xFFFFFF0000000000); | |
| 349 | try test_u128_intFromFloat_f32(0x1.000000p+63, 0x8000000000000000); | |
| 350 | try test_u128_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 351 | try test_u128_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 352 | try test_u128_intFromFloat_f32(0x1.FFFFFEp+127, 0xFFFFFF00000000000000000000000000); | |
| 353 | try test_u128_intFromFloat_f32(0x1.000000p+127, 0x80000000000000000000000000000000); | |
| 354 | try test_u128_intFromFloat_f32(0x1.FFFFFEp+126, 0x7FFFFF80000000000000000000000000); | |
| 355 | try test_u128_intFromFloat_f32(0x1.FFFFFCp+126, 0x7FFFFF00000000000000000000000000); | |
| 356 | ||
| 357 | try test_u128_intFromFloat_f32(-0x1.FFFFFEp+62, 0x0000000000000000); | |
| 358 | try test_u128_intFromFloat_f32(-0x1.FFFFFCp+62, 0x0000000000000000); | |
| 359 | try test_u128_intFromFloat_f32(-0x1.FFFFFEp+126, 0x0000000000000000); | |
| 360 | try test_u128_intFromFloat_f32(-0x1.FFFFFCp+126, 0x0000000000000000); | |
| 361 | try test_u128_intFromFloat_f32(math.floatMax(f32), 0xffffff00000000000000000000000000); | |
| 362 | try test_u128_intFromFloat_f32(math.inf(f32), math.maxInt(u128)); | |
| 347 | 363 | } |
| 348 | 364 | |
| 349 | fn test_fixsfei(comptime T: type, expected: T, a: f32) !void { | |
| 365 | fn test_intFromFloat_f32(comptime T: type, expected: T, a: f32) !void { | |
| 350 | 366 | const int = @typeInfo(T).int; |
| 351 | 367 | var actual: T = undefined; |
| 352 | 368 | _ = switch (int.signedness) { |
| 353 | .signed => __fixsfei, | |
| 354 | .unsigned => __fixunssfei, | |
| 355 | }(@ptrCast(&actual), int.bits, a); | |
| 369 | .signed => signed_intFromFloat_f32, | |
| 370 | .unsigned => unsigned_intFromFloat_f32, | |
| 371 | }(@ptrCast(&actual), a); | |
| 356 | 372 | try testing.expect(expected == actual); |
| 357 | 373 | } |
| 358 | 374 | |
| 359 | test "fixsfei" { | |
| 360 | try test_fixsfei(i256, -1 << 127, -0x1p127); | |
| 361 | try test_fixsfei(i256, -1 << 100, -0x1p100); | |
| 362 | try test_fixsfei(i256, -1 << 50, -0x1p50); | |
| 363 | try test_fixsfei(i256, -1 << 1, -0x1p1); | |
| 364 | try test_fixsfei(i256, -1 << 0, -0x1p0); | |
| 365 | try test_fixsfei(i256, 0, 0); | |
| 366 | try test_fixsfei(i256, 1 << 0, 0x1p0); | |
| 367 | try test_fixsfei(i256, 1 << 1, 0x1p1); | |
| 368 | try test_fixsfei(i256, 1 << 50, 0x1p50); | |
| 369 | try test_fixsfei(i256, 1 << 100, 0x1p100); | |
| 370 | try test_fixsfei(i256, 1 << 127, 0x1p127); | |
| 375 | test signed_intFromFloat_f32 { | |
| 376 | try test_intFromFloat_f32(i256, -1 << 127, -0x1p127); | |
| 377 | try test_intFromFloat_f32(i256, -1 << 100, -0x1p100); | |
| 378 | try test_intFromFloat_f32(i256, -1 << 50, -0x1p50); | |
| 379 | try test_intFromFloat_f32(i256, -1 << 1, -0x1p1); | |
| 380 | try test_intFromFloat_f32(i256, -1 << 0, -0x1p0); | |
| 381 | try test_intFromFloat_f32(i256, 0, 0); | |
| 382 | try test_intFromFloat_f32(i256, 1 << 0, 0x1p0); | |
| 383 | try test_intFromFloat_f32(i256, 1 << 1, 0x1p1); | |
| 384 | try test_intFromFloat_f32(i256, 1 << 50, 0x1p50); | |
| 385 | try test_intFromFloat_f32(i256, 1 << 100, 0x1p100); | |
| 386 | try test_intFromFloat_f32(i256, 1 << 127, 0x1p127); | |
| 371 | 387 | } |
| 372 | 388 | |
| 373 | test "fixunsfei" { | |
| 374 | try test_fixsfei(u256, 0, 0); | |
| 375 | try test_fixsfei(u256, 1 << 0, 0x1p0); | |
| 376 | try test_fixsfei(u256, 1 << 1, 0x1p1); | |
| 377 | try test_fixsfei(u256, 1 << 50, 0x1p50); | |
| 378 | try test_fixsfei(u256, 1 << 100, 0x1p100); | |
| 379 | try test_fixsfei(u256, 1 << 127, 0x1p127); | |
| 389 | test unsigned_intFromFloat_f32 { | |
| 390 | try test_intFromFloat_f32(u256, 0, 0); | |
| 391 | try test_intFromFloat_f32(u256, 1 << 0, 0x1p0); | |
| 392 | try test_intFromFloat_f32(u256, 1 << 1, 0x1p1); | |
| 393 | try test_intFromFloat_f32(u256, 1 << 50, 0x1p50); | |
| 394 | try test_intFromFloat_f32(u256, 1 << 100, 0x1p100); | |
| 395 | try test_intFromFloat_f32(u256, 1 << 127, 0x1p127); | |
| 380 | 396 | } |
| 381 | 397 | |
| 382 | fn test__fixdfsi(a: f64, expected: i32) !void { | |
| 383 | const x = __fixdfsi(a); | |
| 398 | fn test_i32_intFromFloat_f64(a: f64, expected: i32) !void { | |
| 399 | const x = i32_intFromFloat_f64(a); | |
| 384 | 400 | try testing.expect(x == expected); |
| 385 | 401 | } |
| 386 | 402 | |
| 387 | fn test__fixunsdfsi(a: f64, expected: u32) !void { | |
| 388 | const x = __fixunsdfsi(a); | |
| 403 | fn test_u32_intFromFloat_f64(a: f64, expected: u32) !void { | |
| 404 | const x = u32_intFromFloat_f64(a); | |
| 389 | 405 | try testing.expect(x == expected); |
| 390 | 406 | } |
| 391 | 407 | |
| 392 | test "fixdfsi" { | |
| 393 | try test__fixdfsi(-math.floatMax(f64), math.minInt(i32)); | |
| 394 | ||
| 395 | try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); | |
| 396 | try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); | |
| 397 | ||
| 398 | try test__fixdfsi(-0x1.0000000000000p+127, -0x80000000); | |
| 399 | try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); | |
| 400 | try test__fixdfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); | |
| 401 | ||
| 402 | try test__fixdfsi(-0x1.0000000000001p+63, -0x80000000); | |
| 403 | try test__fixdfsi(-0x1.0000000000000p+63, -0x80000000); | |
| 404 | try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); | |
| 405 | try test__fixdfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); | |
| 406 | ||
| 407 | try test__fixdfsi(-0x1.FFFFFEp+62, -0x80000000); | |
| 408 | try test__fixdfsi(-0x1.FFFFFCp+62, -0x80000000); | |
| 409 | ||
| 410 | try test__fixdfsi(-0x1.000000p+31, -0x80000000); | |
| 411 | try test__fixdfsi(-0x1.FFFFFFp+30, -0x7FFFFFC0); | |
| 412 | try test__fixdfsi(-0x1.FFFFFEp+30, -0x7FFFFF80); | |
| 413 | ||
| 414 | try test__fixdfsi(-2.01, -2); | |
| 415 | try test__fixdfsi(-2.0, -2); | |
| 416 | try test__fixdfsi(-1.99, -1); | |
| 417 | try test__fixdfsi(-1.0, -1); | |
| 418 | try test__fixdfsi(-0.99, 0); | |
| 419 | try test__fixdfsi(-0.5, 0); | |
| 420 | try test__fixdfsi(-math.floatMin(f64), 0); | |
| 421 | try test__fixdfsi(0.0, 0); | |
| 422 | try test__fixdfsi(math.floatMin(f64), 0); | |
| 423 | try test__fixdfsi(0.5, 0); | |
| 424 | try test__fixdfsi(0.99, 0); | |
| 425 | try test__fixdfsi(1.0, 1); | |
| 426 | try test__fixdfsi(1.5, 1); | |
| 427 | try test__fixdfsi(1.99, 1); | |
| 428 | try test__fixdfsi(2.0, 2); | |
| 429 | try test__fixdfsi(2.01, 2); | |
| 430 | ||
| 431 | try test__fixdfsi(0x1.FFFFFEp+30, 0x7FFFFF80); | |
| 432 | try test__fixdfsi(0x1.FFFFFFp+30, 0x7FFFFFC0); | |
| 433 | try test__fixdfsi(0x1.000000p+31, 0x7FFFFFFF); | |
| 434 | ||
| 435 | try test__fixdfsi(0x1.FFFFFCp+62, 0x7FFFFFFF); | |
| 436 | try test__fixdfsi(0x1.FFFFFEp+62, 0x7FFFFFFF); | |
| 437 | ||
| 438 | try test__fixdfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); | |
| 439 | try test__fixdfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); | |
| 440 | try test__fixdfsi(0x1.0000000000000p+63, 0x7FFFFFFF); | |
| 441 | try test__fixdfsi(0x1.0000000000001p+63, 0x7FFFFFFF); | |
| 442 | ||
| 443 | try test__fixdfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); | |
| 444 | try test__fixdfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); | |
| 445 | try test__fixdfsi(0x1.0000000000000p+127, 0x7FFFFFFF); | |
| 446 | ||
| 447 | try test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); | |
| 448 | try test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); | |
| 449 | ||
| 450 | try test__fixdfsi(math.floatMax(f64), math.maxInt(i32)); | |
| 408 | test i32_intFromFloat_f64 { | |
| 409 | try test_i32_intFromFloat_f64(-math.floatMax(f64), math.minInt(i32)); | |
| 410 | ||
| 411 | try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); | |
| 412 | try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); | |
| 413 | ||
| 414 | try test_i32_intFromFloat_f64(-0x1.0000000000000p+127, -0x80000000); | |
| 415 | try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); | |
| 416 | try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); | |
| 417 | ||
| 418 | try test_i32_intFromFloat_f64(-0x1.0000000000001p+63, -0x80000000); | |
| 419 | try test_i32_intFromFloat_f64(-0x1.0000000000000p+63, -0x80000000); | |
| 420 | try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); | |
| 421 | try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); | |
| 422 | ||
| 423 | try test_i32_intFromFloat_f64(-0x1.FFFFFEp+62, -0x80000000); | |
| 424 | try test_i32_intFromFloat_f64(-0x1.FFFFFCp+62, -0x80000000); | |
| 425 | ||
| 426 | try test_i32_intFromFloat_f64(-0x1.000000p+31, -0x80000000); | |
| 427 | try test_i32_intFromFloat_f64(-0x1.FFFFFFp+30, -0x7FFFFFC0); | |
| 428 | try test_i32_intFromFloat_f64(-0x1.FFFFFEp+30, -0x7FFFFF80); | |
| 429 | ||
| 430 | try test_i32_intFromFloat_f64(-2.01, -2); | |
| 431 | try test_i32_intFromFloat_f64(-2.0, -2); | |
| 432 | try test_i32_intFromFloat_f64(-1.99, -1); | |
| 433 | try test_i32_intFromFloat_f64(-1.0, -1); | |
| 434 | try test_i32_intFromFloat_f64(-0.99, 0); | |
| 435 | try test_i32_intFromFloat_f64(-0.5, 0); | |
| 436 | try test_i32_intFromFloat_f64(-math.floatMin(f64), 0); | |
| 437 | try test_i32_intFromFloat_f64(0.0, 0); | |
| 438 | try test_i32_intFromFloat_f64(math.floatMin(f64), 0); | |
| 439 | try test_i32_intFromFloat_f64(0.5, 0); | |
| 440 | try test_i32_intFromFloat_f64(0.99, 0); | |
| 441 | try test_i32_intFromFloat_f64(1.0, 1); | |
| 442 | try test_i32_intFromFloat_f64(1.5, 1); | |
| 443 | try test_i32_intFromFloat_f64(1.99, 1); | |
| 444 | try test_i32_intFromFloat_f64(2.0, 2); | |
| 445 | try test_i32_intFromFloat_f64(2.01, 2); | |
| 446 | ||
| 447 | try test_i32_intFromFloat_f64(0x1.FFFFFEp+30, 0x7FFFFF80); | |
| 448 | try test_i32_intFromFloat_f64(0x1.FFFFFFp+30, 0x7FFFFFC0); | |
| 449 | try test_i32_intFromFloat_f64(0x1.000000p+31, 0x7FFFFFFF); | |
| 450 | ||
| 451 | try test_i32_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFFFF); | |
| 452 | try test_i32_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFFFF); | |
| 453 | ||
| 454 | try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); | |
| 455 | try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); | |
| 456 | try test_i32_intFromFloat_f64(0x1.0000000000000p+63, 0x7FFFFFFF); | |
| 457 | try test_i32_intFromFloat_f64(0x1.0000000000001p+63, 0x7FFFFFFF); | |
| 458 | ||
| 459 | try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); | |
| 460 | try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); | |
| 461 | try test_i32_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFF); | |
| 462 | ||
| 463 | try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); | |
| 464 | try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); | |
| 465 | ||
| 466 | try test_i32_intFromFloat_f64(math.floatMax(f64), math.maxInt(i32)); | |
| 451 | 467 | } |
| 452 | 468 | |
| 453 | test "fixunsdfsi" { | |
| 454 | try test__fixunsdfsi(0.0, 0); | |
| 455 | ||
| 456 | try test__fixunsdfsi(0.5, 0); | |
| 457 | try test__fixunsdfsi(0.99, 0); | |
| 458 | try test__fixunsdfsi(1.0, 1); | |
| 459 | try test__fixunsdfsi(1.5, 1); | |
| 460 | try test__fixunsdfsi(1.99, 1); | |
| 461 | try test__fixunsdfsi(2.0, 2); | |
| 462 | try test__fixunsdfsi(2.01, 2); | |
| 463 | try test__fixunsdfsi(-0.5, 0); | |
| 464 | try test__fixunsdfsi(-0.99, 0); | |
| 465 | try test__fixunsdfsi(-1.0, 0); | |
| 466 | try test__fixunsdfsi(-1.5, 0); | |
| 467 | try test__fixunsdfsi(-1.99, 0); | |
| 468 | try test__fixunsdfsi(-2.0, 0); | |
| 469 | try test__fixunsdfsi(-2.01, 0); | |
| 470 | ||
| 471 | try test__fixunsdfsi(0x1.000000p+31, 0x80000000); | |
| 472 | try test__fixunsdfsi(0x1.000000p+32, 0xFFFFFFFF); | |
| 473 | try test__fixunsdfsi(0x1.FFFFFEp+31, 0xFFFFFF00); | |
| 474 | try test__fixunsdfsi(0x1.FFFFFEp+30, 0x7FFFFF80); | |
| 475 | try test__fixunsdfsi(0x1.FFFFFCp+30, 0x7FFFFF00); | |
| 476 | ||
| 477 | try test__fixunsdfsi(-0x1.FFFFFEp+30, 0); | |
| 478 | try test__fixunsdfsi(-0x1.FFFFFCp+30, 0); | |
| 479 | ||
| 480 | try test__fixunsdfsi(0x1.FFFFFFFEp+31, 0xFFFFFFFF); | |
| 481 | try test__fixunsdfsi(0x1.FFFFFFFC00000p+30, 0x7FFFFFFF); | |
| 482 | try test__fixunsdfsi(0x1.FFFFFFF800000p+30, 0x7FFFFFFE); | |
| 469 | test u32_intFromFloat_f64 { | |
| 470 | try test_u32_intFromFloat_f64(0.0, 0); | |
| 471 | ||
| 472 | try test_u32_intFromFloat_f64(0.5, 0); | |
| 473 | try test_u32_intFromFloat_f64(0.99, 0); | |
| 474 | try test_u32_intFromFloat_f64(1.0, 1); | |
| 475 | try test_u32_intFromFloat_f64(1.5, 1); | |
| 476 | try test_u32_intFromFloat_f64(1.99, 1); | |
| 477 | try test_u32_intFromFloat_f64(2.0, 2); | |
| 478 | try test_u32_intFromFloat_f64(2.01, 2); | |
| 479 | try test_u32_intFromFloat_f64(-0.5, 0); | |
| 480 | try test_u32_intFromFloat_f64(-0.99, 0); | |
| 481 | try test_u32_intFromFloat_f64(-1.0, 0); | |
| 482 | try test_u32_intFromFloat_f64(-1.5, 0); | |
| 483 | try test_u32_intFromFloat_f64(-1.99, 0); | |
| 484 | try test_u32_intFromFloat_f64(-2.0, 0); | |
| 485 | try test_u32_intFromFloat_f64(-2.01, 0); | |
| 486 | ||
| 487 | try test_u32_intFromFloat_f64(0x1.000000p+31, 0x80000000); | |
| 488 | try test_u32_intFromFloat_f64(0x1.000000p+32, 0xFFFFFFFF); | |
| 489 | try test_u32_intFromFloat_f64(0x1.FFFFFEp+31, 0xFFFFFF00); | |
| 490 | try test_u32_intFromFloat_f64(0x1.FFFFFEp+30, 0x7FFFFF80); | |
| 491 | try test_u32_intFromFloat_f64(0x1.FFFFFCp+30, 0x7FFFFF00); | |
| 492 | ||
| 493 | try test_u32_intFromFloat_f64(-0x1.FFFFFEp+30, 0); | |
| 494 | try test_u32_intFromFloat_f64(-0x1.FFFFFCp+30, 0); | |
| 495 | ||
| 496 | try test_u32_intFromFloat_f64(0x1.FFFFFFFEp+31, 0xFFFFFFFF); | |
| 497 | try test_u32_intFromFloat_f64(0x1.FFFFFFFC00000p+30, 0x7FFFFFFF); | |
| 498 | try test_u32_intFromFloat_f64(0x1.FFFFFFF800000p+30, 0x7FFFFFFE); | |
| 483 | 499 | } |
| 484 | 500 | |
| 485 | fn test__fixdfdi(a: f64, expected: i64) !void { | |
| 486 | const x = __fixdfdi(a); | |
| 501 | fn test_i64_intFromFloat_f64(a: f64, expected: i64) !void { | |
| 502 | const x = i64_intFromFloat_f64(a); | |
| 487 | 503 | try testing.expect(x == expected); |
| 488 | 504 | } |
| 489 | 505 | |
| 490 | fn test__fixunsdfdi(a: f64, expected: u64) !void { | |
| 491 | const x = __fixunsdfdi(a); | |
| 506 | fn test_u64_intFromFloat_f64(a: f64, expected: u64) !void { | |
| 507 | const x = u64_intFromFloat_f64(a); | |
| 492 | 508 | try testing.expect(x == expected); |
| 493 | 509 | } |
| 494 | 510 | |
| 495 | test "fixdfdi" { | |
| 496 | try test__fixdfdi(-math.floatMax(f64), math.minInt(i64)); | |
| 497 | ||
| 498 | try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); | |
| 499 | try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); | |
| 500 | ||
| 501 | try test__fixdfdi(-0x1.0000000000000p+127, -0x8000000000000000); | |
| 502 | try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); | |
| 503 | try test__fixdfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); | |
| 504 | ||
| 505 | try test__fixdfdi(-0x1.0000000000001p+63, -0x8000000000000000); | |
| 506 | try test__fixdfdi(-0x1.0000000000000p+63, -0x8000000000000000); | |
| 507 | try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); | |
| 508 | try test__fixdfdi(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); | |
| 509 | ||
| 510 | try test__fixdfdi(-0x1.FFFFFEp+62, -0x7fffff8000000000); | |
| 511 | try test__fixdfdi(-0x1.FFFFFCp+62, -0x7fffff0000000000); | |
| 512 | ||
| 513 | try test__fixdfdi(-2.01, -2); | |
| 514 | try test__fixdfdi(-2.0, -2); | |
| 515 | try test__fixdfdi(-1.99, -1); | |
| 516 | try test__fixdfdi(-1.0, -1); | |
| 517 | try test__fixdfdi(-0.99, 0); | |
| 518 | try test__fixdfdi(-0.5, 0); | |
| 519 | try test__fixdfdi(-math.floatMin(f64), 0); | |
| 520 | try test__fixdfdi(0.0, 0); | |
| 521 | try test__fixdfdi(math.floatMin(f64), 0); | |
| 522 | try test__fixdfdi(0.5, 0); | |
| 523 | try test__fixdfdi(0.99, 0); | |
| 524 | try test__fixdfdi(1.0, 1); | |
| 525 | try test__fixdfdi(1.5, 1); | |
| 526 | try test__fixdfdi(1.99, 1); | |
| 527 | try test__fixdfdi(2.0, 2); | |
| 528 | try test__fixdfdi(2.01, 2); | |
| 529 | ||
| 530 | try test__fixdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 531 | try test__fixdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 532 | ||
| 533 | try test__fixdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | |
| 534 | try test__fixdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | |
| 535 | try test__fixdfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); | |
| 536 | try test__fixdfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); | |
| 537 | ||
| 538 | try test__fixdfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); | |
| 539 | try test__fixdfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); | |
| 540 | try test__fixdfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); | |
| 541 | ||
| 542 | try test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); | |
| 543 | try test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); | |
| 544 | ||
| 545 | try test__fixdfdi(math.floatMax(f64), math.maxInt(i64)); | |
| 511 | test i64_intFromFloat_f64 { | |
| 512 | try test_i64_intFromFloat_f64(-math.floatMax(f64), math.minInt(i64)); | |
| 513 | ||
| 514 | try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); | |
| 515 | try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); | |
| 516 | ||
| 517 | try test_i64_intFromFloat_f64(-0x1.0000000000000p+127, -0x8000000000000000); | |
| 518 | try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); | |
| 519 | try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); | |
| 520 | ||
| 521 | try test_i64_intFromFloat_f64(-0x1.0000000000001p+63, -0x8000000000000000); | |
| 522 | try test_i64_intFromFloat_f64(-0x1.0000000000000p+63, -0x8000000000000000); | |
| 523 | try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); | |
| 524 | try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); | |
| 525 | ||
| 526 | try test_i64_intFromFloat_f64(-0x1.FFFFFEp+62, -0x7fffff8000000000); | |
| 527 | try test_i64_intFromFloat_f64(-0x1.FFFFFCp+62, -0x7fffff0000000000); | |
| 528 | ||
| 529 | try test_i64_intFromFloat_f64(-2.01, -2); | |
| 530 | try test_i64_intFromFloat_f64(-2.0, -2); | |
| 531 | try test_i64_intFromFloat_f64(-1.99, -1); | |
| 532 | try test_i64_intFromFloat_f64(-1.0, -1); | |
| 533 | try test_i64_intFromFloat_f64(-0.99, 0); | |
| 534 | try test_i64_intFromFloat_f64(-0.5, 0); | |
| 535 | try test_i64_intFromFloat_f64(-math.floatMin(f64), 0); | |
| 536 | try test_i64_intFromFloat_f64(0.0, 0); | |
| 537 | try test_i64_intFromFloat_f64(math.floatMin(f64), 0); | |
| 538 | try test_i64_intFromFloat_f64(0.5, 0); | |
| 539 | try test_i64_intFromFloat_f64(0.99, 0); | |
| 540 | try test_i64_intFromFloat_f64(1.0, 1); | |
| 541 | try test_i64_intFromFloat_f64(1.5, 1); | |
| 542 | try test_i64_intFromFloat_f64(1.99, 1); | |
| 543 | try test_i64_intFromFloat_f64(2.0, 2); | |
| 544 | try test_i64_intFromFloat_f64(2.01, 2); | |
| 545 | ||
| 546 | try test_i64_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 547 | try test_i64_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 548 | ||
| 549 | try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | |
| 550 | try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | |
| 551 | try test_i64_intFromFloat_f64(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); | |
| 552 | try test_i64_intFromFloat_f64(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); | |
| 553 | ||
| 554 | try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); | |
| 555 | try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); | |
| 556 | try test_i64_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); | |
| 557 | ||
| 558 | try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); | |
| 559 | try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); | |
| 560 | ||
| 561 | try test_i64_intFromFloat_f64(math.floatMax(f64), math.maxInt(i64)); | |
| 546 | 562 | } |
| 547 | 563 | |
| 548 | test "fixunsdfdi" { | |
| 549 | try test__fixunsdfdi(0.0, 0); | |
| 550 | try test__fixunsdfdi(0.5, 0); | |
| 551 | try test__fixunsdfdi(0.99, 0); | |
| 552 | try test__fixunsdfdi(1.0, 1); | |
| 553 | try test__fixunsdfdi(1.5, 1); | |
| 554 | try test__fixunsdfdi(1.99, 1); | |
| 555 | try test__fixunsdfdi(2.0, 2); | |
| 556 | try test__fixunsdfdi(2.01, 2); | |
| 557 | try test__fixunsdfdi(-0.5, 0); | |
| 558 | try test__fixunsdfdi(-0.99, 0); | |
| 559 | try test__fixunsdfdi(-1.0, 0); | |
| 560 | try test__fixunsdfdi(-1.5, 0); | |
| 561 | try test__fixunsdfdi(-1.99, 0); | |
| 562 | try test__fixunsdfdi(-2.0, 0); | |
| 563 | try test__fixunsdfdi(-2.01, 0); | |
| 564 | ||
| 565 | try test__fixunsdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 566 | try test__fixunsdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 567 | ||
| 568 | try test__fixunsdfdi(-0x1.FFFFFEp+62, 0); | |
| 569 | try test__fixunsdfdi(-0x1.FFFFFCp+62, 0); | |
| 570 | ||
| 571 | try test__fixunsdfdi(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800); | |
| 572 | try test__fixunsdfdi(0x1.0000000000000p+63, 0x8000000000000000); | |
| 573 | try test__fixunsdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | |
| 574 | try test__fixunsdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | |
| 575 | ||
| 576 | try test__fixunsdfdi(-0x1.FFFFFFFFFFFFFp+62, 0); | |
| 577 | try test__fixunsdfdi(-0x1.FFFFFFFFFFFFEp+62, 0); | |
| 564 | test u64_intFromFloat_f64 { | |
| 565 | try test_u64_intFromFloat_f64(0.0, 0); | |
| 566 | try test_u64_intFromFloat_f64(0.5, 0); | |
| 567 | try test_u64_intFromFloat_f64(0.99, 0); | |
| 568 | try test_u64_intFromFloat_f64(1.0, 1); | |
| 569 | try test_u64_intFromFloat_f64(1.5, 1); | |
| 570 | try test_u64_intFromFloat_f64(1.99, 1); | |
| 571 | try test_u64_intFromFloat_f64(2.0, 2); | |
| 572 | try test_u64_intFromFloat_f64(2.01, 2); | |
| 573 | try test_u64_intFromFloat_f64(-0.5, 0); | |
| 574 | try test_u64_intFromFloat_f64(-0.99, 0); | |
| 575 | try test_u64_intFromFloat_f64(-1.0, 0); | |
| 576 | try test_u64_intFromFloat_f64(-1.5, 0); | |
| 577 | try test_u64_intFromFloat_f64(-1.99, 0); | |
| 578 | try test_u64_intFromFloat_f64(-2.0, 0); | |
| 579 | try test_u64_intFromFloat_f64(-2.01, 0); | |
| 580 | ||
| 581 | try test_u64_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 582 | try test_u64_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 583 | ||
| 584 | try test_u64_intFromFloat_f64(-0x1.FFFFFEp+62, 0); | |
| 585 | try test_u64_intFromFloat_f64(-0x1.FFFFFCp+62, 0); | |
| 586 | ||
| 587 | try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800); | |
| 588 | try test_u64_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000); | |
| 589 | try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | |
| 590 | try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | |
| 591 | ||
| 592 | try test_u64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, 0); | |
| 593 | try test_u64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, 0); | |
| 578 | 594 | } |
| 579 | 595 | |
| 580 | fn test__fixdfti(a: f64, expected: i128) !void { | |
| 581 | const x = __fixdfti(a); | |
| 596 | fn test_i128_intFromFloat_f64(a: f64, expected: i128) !void { | |
| 597 | const x = i128_intFromFloat_f64(a); | |
| 582 | 598 | try testing.expect(x == expected); |
| 583 | 599 | } |
| 584 | 600 | |
| 585 | fn test__fixunsdfti(a: f64, expected: u128) !void { | |
| 586 | const x = __fixunsdfti(a); | |
| 601 | fn test_u128_intFromFloat_f64(a: f64, expected: u128) !void { | |
| 602 | const x = u128_intFromFloat_f64(a); | |
| 587 | 603 | try testing.expect(x == expected); |
| 588 | 604 | } |
| 589 | 605 | |
| 590 | test "fixdfti" { | |
| 591 | try test__fixdfti(-math.floatMax(f64), math.minInt(i128)); | |
| 592 | ||
| 593 | try test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); | |
| 594 | try test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); | |
| 595 | ||
| 596 | try test__fixdfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); | |
| 597 | try test__fixdfti(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000); | |
| 598 | try test__fixdfti(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000); | |
| 599 | ||
| 600 | try test__fixdfti(-0x1.0000000000001p+63, -0x8000000000000800); | |
| 601 | try test__fixdfti(-0x1.0000000000000p+63, -0x8000000000000000); | |
| 602 | try test__fixdfti(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); | |
| 603 | try test__fixdfti(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); | |
| 604 | ||
| 605 | try test__fixdfti(-0x1.FFFFFEp+62, -0x7fffff8000000000); | |
| 606 | try test__fixdfti(-0x1.FFFFFCp+62, -0x7fffff0000000000); | |
| 607 | ||
| 608 | try test__fixdfti(-2.01, -2); | |
| 609 | try test__fixdfti(-2.0, -2); | |
| 610 | try test__fixdfti(-1.99, -1); | |
| 611 | try test__fixdfti(-1.0, -1); | |
| 612 | try test__fixdfti(-0.99, 0); | |
| 613 | try test__fixdfti(-0.5, 0); | |
| 614 | try test__fixdfti(-math.floatMin(f64), 0); | |
| 615 | try test__fixdfti(0.0, 0); | |
| 616 | try test__fixdfti(math.floatMin(f64), 0); | |
| 617 | try test__fixdfti(0.5, 0); | |
| 618 | try test__fixdfti(0.99, 0); | |
| 619 | try test__fixdfti(1.0, 1); | |
| 620 | try test__fixdfti(1.5, 1); | |
| 621 | try test__fixdfti(1.99, 1); | |
| 622 | try test__fixdfti(2.0, 2); | |
| 623 | try test__fixdfti(2.01, 2); | |
| 624 | ||
| 625 | try test__fixdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 626 | try test__fixdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 627 | ||
| 628 | try test__fixdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | |
| 629 | try test__fixdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | |
| 630 | try test__fixdfti(0x1.0000000000000p+63, 0x8000000000000000); | |
| 631 | try test__fixdfti(0x1.0000000000001p+63, 0x8000000000000800); | |
| 632 | ||
| 633 | try test__fixdfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); | |
| 634 | try test__fixdfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); | |
| 635 | try test__fixdfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 636 | ||
| 637 | try test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 638 | try test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); | |
| 639 | ||
| 640 | try test__fixdfti(math.floatMax(f64), math.maxInt(i128)); | |
| 606 | test i128_intFromFloat_f64 { | |
| 607 | try test_i128_intFromFloat_f64(-math.floatMax(f64), math.minInt(i128)); | |
| 608 | ||
| 609 | try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); | |
| 610 | try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); | |
| 611 | ||
| 612 | try test_i128_intFromFloat_f64(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); | |
| 613 | try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000); | |
| 614 | try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000); | |
| 615 | ||
| 616 | try test_i128_intFromFloat_f64(-0x1.0000000000001p+63, -0x8000000000000800); | |
| 617 | try test_i128_intFromFloat_f64(-0x1.0000000000000p+63, -0x8000000000000000); | |
| 618 | try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); | |
| 619 | try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); | |
| 620 | ||
| 621 | try test_i128_intFromFloat_f64(-0x1.FFFFFEp+62, -0x7fffff8000000000); | |
| 622 | try test_i128_intFromFloat_f64(-0x1.FFFFFCp+62, -0x7fffff0000000000); | |
| 623 | ||
| 624 | try test_i128_intFromFloat_f64(-2.01, -2); | |
| 625 | try test_i128_intFromFloat_f64(-2.0, -2); | |
| 626 | try test_i128_intFromFloat_f64(-1.99, -1); | |
| 627 | try test_i128_intFromFloat_f64(-1.0, -1); | |
| 628 | try test_i128_intFromFloat_f64(-0.99, 0); | |
| 629 | try test_i128_intFromFloat_f64(-0.5, 0); | |
| 630 | try test_i128_intFromFloat_f64(-math.floatMin(f64), 0); | |
| 631 | try test_i128_intFromFloat_f64(0.0, 0); | |
| 632 | try test_i128_intFromFloat_f64(math.floatMin(f64), 0); | |
| 633 | try test_i128_intFromFloat_f64(0.5, 0); | |
| 634 | try test_i128_intFromFloat_f64(0.99, 0); | |
| 635 | try test_i128_intFromFloat_f64(1.0, 1); | |
| 636 | try test_i128_intFromFloat_f64(1.5, 1); | |
| 637 | try test_i128_intFromFloat_f64(1.99, 1); | |
| 638 | try test_i128_intFromFloat_f64(2.0, 2); | |
| 639 | try test_i128_intFromFloat_f64(2.01, 2); | |
| 640 | ||
| 641 | try test_i128_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 642 | try test_i128_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 643 | ||
| 644 | try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | |
| 645 | try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | |
| 646 | try test_i128_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000); | |
| 647 | try test_i128_intFromFloat_f64(0x1.0000000000001p+63, 0x8000000000000800); | |
| 648 | ||
| 649 | try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); | |
| 650 | try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); | |
| 651 | try test_i128_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 652 | ||
| 653 | try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 654 | try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); | |
| 655 | ||
| 656 | try test_i128_intFromFloat_f64(math.floatMax(f64), math.maxInt(i128)); | |
| 641 | 657 | } |
| 642 | 658 | |
| 643 | test "fixunsdfti" { | |
| 644 | try test__fixunsdfti(0.0, 0); | |
| 645 | ||
| 646 | try test__fixunsdfti(0.5, 0); | |
| 647 | try test__fixunsdfti(0.99, 0); | |
| 648 | try test__fixunsdfti(1.0, 1); | |
| 649 | try test__fixunsdfti(1.5, 1); | |
| 650 | try test__fixunsdfti(1.99, 1); | |
| 651 | try test__fixunsdfti(2.0, 2); | |
| 652 | try test__fixunsdfti(2.01, 2); | |
| 653 | try test__fixunsdfti(-0.5, 0); | |
| 654 | try test__fixunsdfti(-0.99, 0); | |
| 655 | try test__fixunsdfti(-1.0, 0); | |
| 656 | try test__fixunsdfti(-1.5, 0); | |
| 657 | try test__fixunsdfti(-1.99, 0); | |
| 658 | try test__fixunsdfti(-2.0, 0); | |
| 659 | try test__fixunsdfti(-2.01, 0); | |
| 660 | ||
| 661 | try test__fixunsdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 662 | try test__fixunsdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 663 | ||
| 664 | try test__fixunsdfti(-0x1.FFFFFEp+62, 0); | |
| 665 | try test__fixunsdfti(-0x1.FFFFFCp+62, 0); | |
| 666 | ||
| 667 | try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800); | |
| 668 | try test__fixunsdfti(0x1.0000000000000p+63, 0x8000000000000000); | |
| 669 | try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | |
| 670 | try test__fixunsdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | |
| 671 | ||
| 672 | try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+127, 0xFFFFFFFFFFFFF8000000000000000000); | |
| 673 | try test__fixunsdfti(0x1.0000000000000p+127, 0x80000000000000000000000000000000); | |
| 674 | try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); | |
| 675 | try test__fixunsdfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); | |
| 676 | try test__fixunsdfti(0x1.0000000000000p+128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 677 | ||
| 678 | try test__fixunsdfti(-0x1.FFFFFFFFFFFFFp+62, 0); | |
| 679 | try test__fixunsdfti(-0x1.FFFFFFFFFFFFEp+62, 0); | |
| 659 | test u128_intFromFloat_f64 { | |
| 660 | try test_u128_intFromFloat_f64(0.0, 0); | |
| 661 | ||
| 662 | try test_u128_intFromFloat_f64(0.5, 0); | |
| 663 | try test_u128_intFromFloat_f64(0.99, 0); | |
| 664 | try test_u128_intFromFloat_f64(1.0, 1); | |
| 665 | try test_u128_intFromFloat_f64(1.5, 1); | |
| 666 | try test_u128_intFromFloat_f64(1.99, 1); | |
| 667 | try test_u128_intFromFloat_f64(2.0, 2); | |
| 668 | try test_u128_intFromFloat_f64(2.01, 2); | |
| 669 | try test_u128_intFromFloat_f64(-0.5, 0); | |
| 670 | try test_u128_intFromFloat_f64(-0.99, 0); | |
| 671 | try test_u128_intFromFloat_f64(-1.0, 0); | |
| 672 | try test_u128_intFromFloat_f64(-1.5, 0); | |
| 673 | try test_u128_intFromFloat_f64(-1.99, 0); | |
| 674 | try test_u128_intFromFloat_f64(-2.0, 0); | |
| 675 | try test_u128_intFromFloat_f64(-2.01, 0); | |
| 676 | ||
| 677 | try test_u128_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 678 | try test_u128_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 679 | ||
| 680 | try test_u128_intFromFloat_f64(-0x1.FFFFFEp+62, 0); | |
| 681 | try test_u128_intFromFloat_f64(-0x1.FFFFFCp+62, 0); | |
| 682 | ||
| 683 | try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800); | |
| 684 | try test_u128_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000); | |
| 685 | try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | |
| 686 | try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | |
| 687 | ||
| 688 | try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+127, 0xFFFFFFFFFFFFF8000000000000000000); | |
| 689 | try test_u128_intFromFloat_f64(0x1.0000000000000p+127, 0x80000000000000000000000000000000); | |
| 690 | try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); | |
| 691 | try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); | |
| 692 | try test_u128_intFromFloat_f64(0x1.0000000000000p+128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 693 | ||
| 694 | try test_u128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, 0); | |
| 695 | try test_u128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, 0); | |
| 680 | 696 | } |
| 681 | 697 | |
| 682 | fn test_fixdfei(comptime T: type, expected: T, a: f64) !void { | |
| 698 | fn test_intFromFloat_f64(comptime T: type, expected: T, a: f64) !void { | |
| 683 | 699 | const int = @typeInfo(T).int; |
| 684 | 700 | var actual: T = undefined; |
| 685 | 701 | _ = switch (int.signedness) { |
| 686 | .signed => __fixdfei, | |
| 687 | .unsigned => __fixunsdfei, | |
| 688 | }(@ptrCast(&actual), int.bits, a); | |
| 702 | .signed => signed_intFromFloat_f64, | |
| 703 | .unsigned => unsigned_intFromFloat_f64, | |
| 704 | }(@ptrCast(&actual), a); | |
| 689 | 705 | try testing.expect(expected == actual); |
| 690 | 706 | } |
| 691 | 707 | |
| 692 | test "fixdfei" { | |
| 693 | try test_fixdfei(i256, -1 << 255, -0x1p255); | |
| 694 | try test_fixdfei(i256, -1 << 127, -0x1p127); | |
| 695 | try test_fixdfei(i256, -1 << 100, -0x1p100); | |
| 696 | try test_fixdfei(i256, -1 << 50, -0x1p50); | |
| 697 | try test_fixdfei(i256, -1 << 1, -0x1p1); | |
| 698 | try test_fixdfei(i256, -1 << 0, -0x1p0); | |
| 699 | try test_fixdfei(i256, 0, 0); | |
| 700 | try test_fixdfei(i256, 1 << 0, 0x1p0); | |
| 701 | try test_fixdfei(i256, 1 << 1, 0x1p1); | |
| 702 | try test_fixdfei(i256, 1 << 50, 0x1p50); | |
| 703 | try test_fixdfei(i256, 1 << 100, 0x1p100); | |
| 704 | try test_fixdfei(i256, 1 << 127, 0x1p127); | |
| 705 | try test_fixdfei(i256, 1 << 254, 0x1p254); | |
| 708 | test signed_intFromFloat_f64 { | |
| 709 | try test_intFromFloat_f64(i256, -1 << 255, -0x1p255); | |
| 710 | try test_intFromFloat_f64(i256, -1 << 127, -0x1p127); | |
| 711 | try test_intFromFloat_f64(i256, -1 << 100, -0x1p100); | |
| 712 | try test_intFromFloat_f64(i256, -1 << 50, -0x1p50); | |
| 713 | try test_intFromFloat_f64(i256, -1 << 1, -0x1p1); | |
| 714 | try test_intFromFloat_f64(i256, -1 << 0, -0x1p0); | |
| 715 | try test_intFromFloat_f64(i256, 0, 0); | |
| 716 | try test_intFromFloat_f64(i256, 1 << 0, 0x1p0); | |
| 717 | try test_intFromFloat_f64(i256, 1 << 1, 0x1p1); | |
| 718 | try test_intFromFloat_f64(i256, 1 << 50, 0x1p50); | |
| 719 | try test_intFromFloat_f64(i256, 1 << 100, 0x1p100); | |
| 720 | try test_intFromFloat_f64(i256, 1 << 127, 0x1p127); | |
| 721 | try test_intFromFloat_f64(i256, 1 << 254, 0x1p254); | |
| 706 | 722 | } |
| 707 | 723 | |
| 708 | test "fixundfei" { | |
| 709 | try test_fixdfei(u256, 0, 0); | |
| 710 | try test_fixdfei(u256, 1 << 0, 0x1p0); | |
| 711 | try test_fixdfei(u256, 1 << 1, 0x1p1); | |
| 712 | try test_fixdfei(u256, 1 << 50, 0x1p50); | |
| 713 | try test_fixdfei(u256, 1 << 100, 0x1p100); | |
| 714 | try test_fixdfei(u256, 1 << 127, 0x1p127); | |
| 715 | try test_fixdfei(u256, 1 << 255, 0x1p255); | |
| 724 | test unsigned_intFromFloat_f64 { | |
| 725 | try test_intFromFloat_f64(u256, 0, 0); | |
| 726 | try test_intFromFloat_f64(u256, 1 << 0, 0x1p0); | |
| 727 | try test_intFromFloat_f64(u256, 1 << 1, 0x1p1); | |
| 728 | try test_intFromFloat_f64(u256, 1 << 50, 0x1p50); | |
| 729 | try test_intFromFloat_f64(u256, 1 << 100, 0x1p100); | |
| 730 | try test_intFromFloat_f64(u256, 1 << 127, 0x1p127); | |
| 731 | try test_intFromFloat_f64(u256, 1 << 255, 0x1p255); | |
| 716 | 732 | } |
| 717 | 733 | |
| 718 | fn test__fixtfsi(a: f128, expected: i32) !void { | |
| 719 | const x = __fixtfsi(a); | |
| 734 | fn test_i32_intFromFloat_f128(a: f128, expected: i32) !void { | |
| 735 | const x = i32_intFromFloat_f128(a); | |
| 720 | 736 | try testing.expect(x == expected); |
| 721 | 737 | } |
| 722 | 738 | |
| 723 | fn test__fixunstfsi(a: f128, expected: u32) !void { | |
| 724 | const x = __fixunstfsi(a); | |
| 739 | fn test_u32_intFromFloat_f128(a: f128, expected: u32) !void { | |
| 740 | const x = u32_intFromFloat_f128(a); | |
| 725 | 741 | try testing.expect(x == expected); |
| 726 | 742 | } |
| 727 | 743 | |
| 728 | test "fixtfsi" { | |
| 729 | try test__fixtfsi(-math.floatMax(f128), math.minInt(i32)); | |
| 730 | ||
| 731 | try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); | |
| 732 | try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); | |
| 733 | ||
| 734 | try test__fixtfsi(-0x1.0000000000000p+127, -0x80000000); | |
| 735 | try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); | |
| 736 | try test__fixtfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); | |
| 737 | ||
| 738 | try test__fixtfsi(-0x1.0000000000001p+63, -0x80000000); | |
| 739 | try test__fixtfsi(-0x1.0000000000000p+63, -0x80000000); | |
| 740 | try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); | |
| 741 | try test__fixtfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); | |
| 742 | ||
| 743 | try test__fixtfsi(-0x1.FFFFFEp+62, -0x80000000); | |
| 744 | try test__fixtfsi(-0x1.FFFFFCp+62, -0x80000000); | |
| 745 | ||
| 746 | try test__fixtfsi(-0x1.000000p+31, -0x80000000); | |
| 747 | try test__fixtfsi(-0x1.FFFFFFp+30, -0x7FFFFFC0); | |
| 748 | try test__fixtfsi(-0x1.FFFFFEp+30, -0x7FFFFF80); | |
| 749 | try test__fixtfsi(-0x1.FFFFFCp+30, -0x7FFFFF00); | |
| 750 | ||
| 751 | try test__fixtfsi(-2.01, -2); | |
| 752 | try test__fixtfsi(-2.0, -2); | |
| 753 | try test__fixtfsi(-1.99, -1); | |
| 754 | try test__fixtfsi(-1.0, -1); | |
| 755 | try test__fixtfsi(-0.99, 0); | |
| 756 | try test__fixtfsi(-0.5, 0); | |
| 757 | try test__fixtfsi(-math.floatMin(f32), 0); | |
| 758 | try test__fixtfsi(0.0, 0); | |
| 759 | try test__fixtfsi(math.floatMin(f32), 0); | |
| 760 | try test__fixtfsi(0.5, 0); | |
| 761 | try test__fixtfsi(0.99, 0); | |
| 762 | try test__fixtfsi(1.0, 1); | |
| 763 | try test__fixtfsi(1.5, 1); | |
| 764 | try test__fixtfsi(1.99, 1); | |
| 765 | try test__fixtfsi(2.0, 2); | |
| 766 | try test__fixtfsi(2.01, 2); | |
| 767 | ||
| 768 | try test__fixtfsi(0x1.FFFFFCp+30, 0x7FFFFF00); | |
| 769 | try test__fixtfsi(0x1.FFFFFEp+30, 0x7FFFFF80); | |
| 770 | try test__fixtfsi(0x1.FFFFFFp+30, 0x7FFFFFC0); | |
| 771 | try test__fixtfsi(0x1.000000p+31, 0x7FFFFFFF); | |
| 772 | ||
| 773 | try test__fixtfsi(0x1.FFFFFCp+62, 0x7FFFFFFF); | |
| 774 | try test__fixtfsi(0x1.FFFFFEp+62, 0x7FFFFFFF); | |
| 775 | ||
| 776 | try test__fixtfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); | |
| 777 | try test__fixtfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); | |
| 778 | try test__fixtfsi(0x1.0000000000000p+63, 0x7FFFFFFF); | |
| 779 | try test__fixtfsi(0x1.0000000000001p+63, 0x7FFFFFFF); | |
| 780 | ||
| 781 | try test__fixtfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); | |
| 782 | try test__fixtfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); | |
| 783 | try test__fixtfsi(0x1.0000000000000p+127, 0x7FFFFFFF); | |
| 784 | ||
| 785 | try test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); | |
| 786 | try test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); | |
| 787 | ||
| 788 | try test__fixtfsi(math.floatMax(f128), math.maxInt(i32)); | |
| 744 | test i32_intFromFloat_f128 { | |
| 745 | try test_i32_intFromFloat_f128(-math.floatMax(f128), math.minInt(i32)); | |
| 746 | ||
| 747 | try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); | |
| 748 | try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); | |
| 749 | ||
| 750 | try test_i32_intFromFloat_f128(-0x1.0000000000000p+127, -0x80000000); | |
| 751 | try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); | |
| 752 | try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); | |
| 753 | ||
| 754 | try test_i32_intFromFloat_f128(-0x1.0000000000001p+63, -0x80000000); | |
| 755 | try test_i32_intFromFloat_f128(-0x1.0000000000000p+63, -0x80000000); | |
| 756 | try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); | |
| 757 | try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); | |
| 758 | ||
| 759 | try test_i32_intFromFloat_f128(-0x1.FFFFFEp+62, -0x80000000); | |
| 760 | try test_i32_intFromFloat_f128(-0x1.FFFFFCp+62, -0x80000000); | |
| 761 | ||
| 762 | try test_i32_intFromFloat_f128(-0x1.000000p+31, -0x80000000); | |
| 763 | try test_i32_intFromFloat_f128(-0x1.FFFFFFp+30, -0x7FFFFFC0); | |
| 764 | try test_i32_intFromFloat_f128(-0x1.FFFFFEp+30, -0x7FFFFF80); | |
| 765 | try test_i32_intFromFloat_f128(-0x1.FFFFFCp+30, -0x7FFFFF00); | |
| 766 | ||
| 767 | try test_i32_intFromFloat_f128(-2.01, -2); | |
| 768 | try test_i32_intFromFloat_f128(-2.0, -2); | |
| 769 | try test_i32_intFromFloat_f128(-1.99, -1); | |
| 770 | try test_i32_intFromFloat_f128(-1.0, -1); | |
| 771 | try test_i32_intFromFloat_f128(-0.99, 0); | |
| 772 | try test_i32_intFromFloat_f128(-0.5, 0); | |
| 773 | try test_i32_intFromFloat_f128(-math.floatMin(f32), 0); | |
| 774 | try test_i32_intFromFloat_f128(0.0, 0); | |
| 775 | try test_i32_intFromFloat_f128(math.floatMin(f32), 0); | |
| 776 | try test_i32_intFromFloat_f128(0.5, 0); | |
| 777 | try test_i32_intFromFloat_f128(0.99, 0); | |
| 778 | try test_i32_intFromFloat_f128(1.0, 1); | |
| 779 | try test_i32_intFromFloat_f128(1.5, 1); | |
| 780 | try test_i32_intFromFloat_f128(1.99, 1); | |
| 781 | try test_i32_intFromFloat_f128(2.0, 2); | |
| 782 | try test_i32_intFromFloat_f128(2.01, 2); | |
| 783 | ||
| 784 | try test_i32_intFromFloat_f128(0x1.FFFFFCp+30, 0x7FFFFF00); | |
| 785 | try test_i32_intFromFloat_f128(0x1.FFFFFEp+30, 0x7FFFFF80); | |
| 786 | try test_i32_intFromFloat_f128(0x1.FFFFFFp+30, 0x7FFFFFC0); | |
| 787 | try test_i32_intFromFloat_f128(0x1.000000p+31, 0x7FFFFFFF); | |
| 788 | ||
| 789 | try test_i32_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFFFF); | |
| 790 | try test_i32_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFFFF); | |
| 791 | ||
| 792 | try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); | |
| 793 | try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); | |
| 794 | try test_i32_intFromFloat_f128(0x1.0000000000000p+63, 0x7FFFFFFF); | |
| 795 | try test_i32_intFromFloat_f128(0x1.0000000000001p+63, 0x7FFFFFFF); | |
| 796 | ||
| 797 | try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); | |
| 798 | try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); | |
| 799 | try test_i32_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFF); | |
| 800 | ||
| 801 | try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); | |
| 802 | try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); | |
| 803 | ||
| 804 | try test_i32_intFromFloat_f128(math.floatMax(f128), math.maxInt(i32)); | |
| 789 | 805 | } |
| 790 | 806 | |
| 791 | test "fixunstfsi" { | |
| 792 | try test__fixunstfsi(math.inf(f128), 0xffffffff); | |
| 793 | try test__fixunstfsi(0, 0x0); | |
| 794 | try test__fixunstfsi(0x1.23456789abcdefp+5, 0x24); | |
| 795 | try test__fixunstfsi(0x1.23456789abcdefp-3, 0x0); | |
| 796 | try test__fixunstfsi(0x1.23456789abcdefp+20, 0x123456); | |
| 797 | try test__fixunstfsi(0x1.23456789abcdefp+40, 0xffffffff); | |
| 798 | try test__fixunstfsi(0x1.23456789abcdefp+256, 0xffffffff); | |
| 799 | try test__fixunstfsi(-0x1.23456789abcdefp+3, 0x0); | |
| 800 | ||
| 801 | try test__fixunstfsi(0x1p+32, 0xFFFFFFFF); | |
| 807 | test u32_intFromFloat_f128 { | |
| 808 | try test_u32_intFromFloat_f128(math.inf(f128), 0xffffffff); | |
| 809 | try test_u32_intFromFloat_f128(0, 0x0); | |
| 810 | try test_u32_intFromFloat_f128(0x1.23456789abcdefp+5, 0x24); | |
| 811 | try test_u32_intFromFloat_f128(0x1.23456789abcdefp-3, 0x0); | |
| 812 | try test_u32_intFromFloat_f128(0x1.23456789abcdefp+20, 0x123456); | |
| 813 | try test_u32_intFromFloat_f128(0x1.23456789abcdefp+40, 0xffffffff); | |
| 814 | try test_u32_intFromFloat_f128(0x1.23456789abcdefp+256, 0xffffffff); | |
| 815 | try test_u32_intFromFloat_f128(-0x1.23456789abcdefp+3, 0x0); | |
| 816 | ||
| 817 | try test_u32_intFromFloat_f128(0x1p+32, 0xFFFFFFFF); | |
| 802 | 818 | } |
| 803 | 819 | |
| 804 | fn test__fixtfdi(a: f128, expected: i64) !void { | |
| 805 | const x = __fixtfdi(a); | |
| 820 | fn test_i64_intFromFloat_f128(a: f128, expected: i64) !void { | |
| 821 | const x = i64_intFromFloat_f128(a); | |
| 806 | 822 | try testing.expect(x == expected); |
| 807 | 823 | } |
| 808 | 824 | |
| 809 | fn test__fixunstfdi(a: f128, expected: u64) !void { | |
| 810 | const x = __fixunstfdi(a); | |
| 825 | fn test_u64_intFromFloat_f128(a: f128, expected: u64) !void { | |
| 826 | const x = u64_intFromFloat_f128(a); | |
| 811 | 827 | try testing.expect(x == expected); |
| 812 | 828 | } |
| 813 | 829 | |
| 814 | test "fixtfdi" { | |
| 815 | try test__fixtfdi(-math.floatMax(f128), math.minInt(i64)); | |
| 816 | ||
| 817 | try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); | |
| 818 | try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); | |
| 819 | ||
| 820 | try test__fixtfdi(-0x1.0000000000000p+127, -0x8000000000000000); | |
| 821 | try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); | |
| 822 | try test__fixtfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); | |
| 823 | ||
| 824 | try test__fixtfdi(-0x1.0000000000001p+63, -0x8000000000000000); | |
| 825 | try test__fixtfdi(-0x1.0000000000000p+63, -0x8000000000000000); | |
| 826 | try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); | |
| 827 | try test__fixtfdi(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); | |
| 828 | ||
| 829 | try test__fixtfdi(-0x1.FFFFFEp+62, -0x7FFFFF8000000000); | |
| 830 | try test__fixtfdi(-0x1.FFFFFCp+62, -0x7FFFFF0000000000); | |
| 831 | ||
| 832 | try test__fixtfdi(-0x1.000000p+31, -0x80000000); | |
| 833 | try test__fixtfdi(-0x1.FFFFFFp+30, -0x7FFFFFC0); | |
| 834 | try test__fixtfdi(-0x1.FFFFFEp+30, -0x7FFFFF80); | |
| 835 | try test__fixtfdi(-0x1.FFFFFCp+30, -0x7FFFFF00); | |
| 836 | ||
| 837 | try test__fixtfdi(-2.01, -2); | |
| 838 | try test__fixtfdi(-2.0, -2); | |
| 839 | try test__fixtfdi(-1.99, -1); | |
| 840 | try test__fixtfdi(-1.0, -1); | |
| 841 | try test__fixtfdi(-0.99, 0); | |
| 842 | try test__fixtfdi(-0.5, 0); | |
| 843 | try test__fixtfdi(-math.floatMin(f64), 0); | |
| 844 | try test__fixtfdi(0.0, 0); | |
| 845 | try test__fixtfdi(math.floatMin(f64), 0); | |
| 846 | try test__fixtfdi(0.5, 0); | |
| 847 | try test__fixtfdi(0.99, 0); | |
| 848 | try test__fixtfdi(1.0, 1); | |
| 849 | try test__fixtfdi(1.5, 1); | |
| 850 | try test__fixtfdi(1.99, 1); | |
| 851 | try test__fixtfdi(2.0, 2); | |
| 852 | try test__fixtfdi(2.01, 2); | |
| 853 | ||
| 854 | try test__fixtfdi(0x1.FFFFFCp+30, 0x7FFFFF00); | |
| 855 | try test__fixtfdi(0x1.FFFFFEp+30, 0x7FFFFF80); | |
| 856 | try test__fixtfdi(0x1.FFFFFFp+30, 0x7FFFFFC0); | |
| 857 | try test__fixtfdi(0x1.000000p+31, 0x80000000); | |
| 858 | ||
| 859 | try test__fixtfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 860 | try test__fixtfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 861 | ||
| 862 | try test__fixtfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | |
| 863 | try test__fixtfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | |
| 864 | try test__fixtfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); | |
| 865 | try test__fixtfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); | |
| 866 | ||
| 867 | try test__fixtfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); | |
| 868 | try test__fixtfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); | |
| 869 | try test__fixtfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); | |
| 870 | ||
| 871 | try test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); | |
| 872 | try test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); | |
| 873 | ||
| 874 | try test__fixtfdi(math.floatMax(f128), math.maxInt(i64)); | |
| 830 | test i64_intFromFloat_f128 { | |
| 831 | try test_i64_intFromFloat_f128(-math.floatMax(f128), math.minInt(i64)); | |
| 832 | ||
| 833 | try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); | |
| 834 | try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); | |
| 835 | ||
| 836 | try test_i64_intFromFloat_f128(-0x1.0000000000000p+127, -0x8000000000000000); | |
| 837 | try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); | |
| 838 | try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); | |
| 839 | ||
| 840 | try test_i64_intFromFloat_f128(-0x1.0000000000001p+63, -0x8000000000000000); | |
| 841 | try test_i64_intFromFloat_f128(-0x1.0000000000000p+63, -0x8000000000000000); | |
| 842 | try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); | |
| 843 | try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); | |
| 844 | ||
| 845 | try test_i64_intFromFloat_f128(-0x1.FFFFFEp+62, -0x7FFFFF8000000000); | |
| 846 | try test_i64_intFromFloat_f128(-0x1.FFFFFCp+62, -0x7FFFFF0000000000); | |
| 847 | ||
| 848 | try test_i64_intFromFloat_f128(-0x1.000000p+31, -0x80000000); | |
| 849 | try test_i64_intFromFloat_f128(-0x1.FFFFFFp+30, -0x7FFFFFC0); | |
| 850 | try test_i64_intFromFloat_f128(-0x1.FFFFFEp+30, -0x7FFFFF80); | |
| 851 | try test_i64_intFromFloat_f128(-0x1.FFFFFCp+30, -0x7FFFFF00); | |
| 852 | ||
| 853 | try test_i64_intFromFloat_f128(-2.01, -2); | |
| 854 | try test_i64_intFromFloat_f128(-2.0, -2); | |
| 855 | try test_i64_intFromFloat_f128(-1.99, -1); | |
| 856 | try test_i64_intFromFloat_f128(-1.0, -1); | |
| 857 | try test_i64_intFromFloat_f128(-0.99, 0); | |
| 858 | try test_i64_intFromFloat_f128(-0.5, 0); | |
| 859 | try test_i64_intFromFloat_f128(-math.floatMin(f64), 0); | |
| 860 | try test_i64_intFromFloat_f128(0.0, 0); | |
| 861 | try test_i64_intFromFloat_f128(math.floatMin(f64), 0); | |
| 862 | try test_i64_intFromFloat_f128(0.5, 0); | |
| 863 | try test_i64_intFromFloat_f128(0.99, 0); | |
| 864 | try test_i64_intFromFloat_f128(1.0, 1); | |
| 865 | try test_i64_intFromFloat_f128(1.5, 1); | |
| 866 | try test_i64_intFromFloat_f128(1.99, 1); | |
| 867 | try test_i64_intFromFloat_f128(2.0, 2); | |
| 868 | try test_i64_intFromFloat_f128(2.01, 2); | |
| 869 | ||
| 870 | try test_i64_intFromFloat_f128(0x1.FFFFFCp+30, 0x7FFFFF00); | |
| 871 | try test_i64_intFromFloat_f128(0x1.FFFFFEp+30, 0x7FFFFF80); | |
| 872 | try test_i64_intFromFloat_f128(0x1.FFFFFFp+30, 0x7FFFFFC0); | |
| 873 | try test_i64_intFromFloat_f128(0x1.000000p+31, 0x80000000); | |
| 874 | ||
| 875 | try test_i64_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 876 | try test_i64_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 877 | ||
| 878 | try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | |
| 879 | try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | |
| 880 | try test_i64_intFromFloat_f128(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); | |
| 881 | try test_i64_intFromFloat_f128(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); | |
| 882 | ||
| 883 | try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); | |
| 884 | try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); | |
| 885 | try test_i64_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); | |
| 886 | ||
| 887 | try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); | |
| 888 | try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); | |
| 889 | ||
| 890 | try test_i64_intFromFloat_f128(math.floatMax(f128), math.maxInt(i64)); | |
| 875 | 891 | } |
| 876 | 892 | |
| 877 | test "fixunstfdi" { | |
| 878 | try test__fixunstfdi(0.0, 0); | |
| 879 | ||
| 880 | try test__fixunstfdi(0.5, 0); | |
| 881 | try test__fixunstfdi(0.99, 0); | |
| 882 | try test__fixunstfdi(1.0, 1); | |
| 883 | try test__fixunstfdi(1.5, 1); | |
| 884 | try test__fixunstfdi(1.99, 1); | |
| 885 | try test__fixunstfdi(2.0, 2); | |
| 886 | try test__fixunstfdi(2.01, 2); | |
| 887 | try test__fixunstfdi(-0.5, 0); | |
| 888 | try test__fixunstfdi(-0.99, 0); | |
| 889 | try test__fixunstfdi(-1.0, 0); | |
| 890 | try test__fixunstfdi(-1.5, 0); | |
| 891 | try test__fixunstfdi(-1.99, 0); | |
| 892 | try test__fixunstfdi(-2.0, 0); | |
| 893 | try test__fixunstfdi(-2.01, 0); | |
| 894 | ||
| 895 | try test__fixunstfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 896 | try test__fixunstfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 897 | ||
| 898 | try test__fixunstfdi(-0x1.FFFFFEp+62, 0); | |
| 899 | try test__fixunstfdi(-0x1.FFFFFCp+62, 0); | |
| 900 | ||
| 901 | try test__fixunstfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | |
| 902 | try test__fixunstfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | |
| 903 | ||
| 904 | try test__fixunstfdi(-0x1.FFFFFFFFFFFFFp+62, 0); | |
| 905 | try test__fixunstfdi(-0x1.FFFFFFFFFFFFEp+62, 0); | |
| 906 | ||
| 907 | try test__fixunstfdi(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF); | |
| 908 | try test__fixunstfdi(0x1.0000000000000002p+63, 0x8000000000000001); | |
| 909 | try test__fixunstfdi(0x1.0000000000000000p+63, 0x8000000000000000); | |
| 910 | try test__fixunstfdi(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF); | |
| 911 | try test__fixunstfdi(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE); | |
| 912 | try test__fixunstfdi(0x1p+64, 0xFFFFFFFFFFFFFFFF); | |
| 913 | ||
| 914 | try test__fixunstfdi(-0x1.0000000000000000p+63, 0); | |
| 915 | try test__fixunstfdi(-0x1.FFFFFFFFFFFFFFFCp+62, 0); | |
| 916 | try test__fixunstfdi(-0x1.FFFFFFFFFFFFFFF8p+62, 0); | |
| 893 | test u64_intFromFloat_f128 { | |
| 894 | try test_u64_intFromFloat_f128(0.0, 0); | |
| 895 | ||
| 896 | try test_u64_intFromFloat_f128(0.5, 0); | |
| 897 | try test_u64_intFromFloat_f128(0.99, 0); | |
| 898 | try test_u64_intFromFloat_f128(1.0, 1); | |
| 899 | try test_u64_intFromFloat_f128(1.5, 1); | |
| 900 | try test_u64_intFromFloat_f128(1.99, 1); | |
| 901 | try test_u64_intFromFloat_f128(2.0, 2); | |
| 902 | try test_u64_intFromFloat_f128(2.01, 2); | |
| 903 | try test_u64_intFromFloat_f128(-0.5, 0); | |
| 904 | try test_u64_intFromFloat_f128(-0.99, 0); | |
| 905 | try test_u64_intFromFloat_f128(-1.0, 0); | |
| 906 | try test_u64_intFromFloat_f128(-1.5, 0); | |
| 907 | try test_u64_intFromFloat_f128(-1.99, 0); | |
| 908 | try test_u64_intFromFloat_f128(-2.0, 0); | |
| 909 | try test_u64_intFromFloat_f128(-2.01, 0); | |
| 910 | ||
| 911 | try test_u64_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 912 | try test_u64_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 913 | ||
| 914 | try test_u64_intFromFloat_f128(-0x1.FFFFFEp+62, 0); | |
| 915 | try test_u64_intFromFloat_f128(-0x1.FFFFFCp+62, 0); | |
| 916 | ||
| 917 | try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | |
| 918 | try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | |
| 919 | ||
| 920 | try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, 0); | |
| 921 | try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, 0); | |
| 922 | ||
| 923 | try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF); | |
| 924 | try test_u64_intFromFloat_f128(0x1.0000000000000002p+63, 0x8000000000000001); | |
| 925 | try test_u64_intFromFloat_f128(0x1.0000000000000000p+63, 0x8000000000000000); | |
| 926 | try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF); | |
| 927 | try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE); | |
| 928 | try test_u64_intFromFloat_f128(0x1p+64, 0xFFFFFFFFFFFFFFFF); | |
| 929 | ||
| 930 | try test_u64_intFromFloat_f128(-0x1.0000000000000000p+63, 0); | |
| 931 | try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFFFCp+62, 0); | |
| 932 | try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFFF8p+62, 0); | |
| 917 | 933 | } |
| 918 | 934 | |
| 919 | fn test__fixtfti(a: f128, expected: i128) !void { | |
| 920 | const x = __fixtfti(a); | |
| 935 | fn test_i128_intFromFloat_f128(a: f128, expected: i128) !void { | |
| 936 | const x = i128_intFromFloat_f128(a); | |
| 921 | 937 | try testing.expect(x == expected); |
| 922 | 938 | } |
| 923 | 939 | |
| 924 | fn test__fixunstfti(a: f128, expected: u128) !void { | |
| 925 | const x = __fixunstfti(a); | |
| 940 | fn test_u128_intFromFloat_f128(a: f128, expected: u128) !void { | |
| 941 | const x = u128_intFromFloat_f128(a); | |
| 926 | 942 | try testing.expect(x == expected); |
| 927 | 943 | } |
| 928 | 944 | |
| 929 | test "fixtfti" { | |
| 930 | try test__fixtfti(-math.floatMax(f128), math.minInt(i128)); | |
| 931 | ||
| 932 | try test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); | |
| 933 | try test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); | |
| 934 | ||
| 935 | try test__fixtfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); | |
| 936 | try test__fixtfti(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000); | |
| 937 | try test__fixtfti(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000); | |
| 938 | ||
| 939 | try test__fixtfti(-0x1.0000000000001p+63, -0x8000000000000800); | |
| 940 | try test__fixtfti(-0x1.0000000000000p+63, -0x8000000000000000); | |
| 941 | try test__fixtfti(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); | |
| 942 | try test__fixtfti(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); | |
| 943 | ||
| 944 | try test__fixtfti(-0x1.FFFFFEp+62, -0x7fffff8000000000); | |
| 945 | try test__fixtfti(-0x1.FFFFFCp+62, -0x7fffff0000000000); | |
| 946 | ||
| 947 | try test__fixtfti(-2.01, -2); | |
| 948 | try test__fixtfti(-2.0, -2); | |
| 949 | try test__fixtfti(-1.99, -1); | |
| 950 | try test__fixtfti(-1.0, -1); | |
| 951 | try test__fixtfti(-0.99, 0); | |
| 952 | try test__fixtfti(-0.5, 0); | |
| 953 | try test__fixtfti(-math.floatMin(f128), 0); | |
| 954 | try test__fixtfti(0.0, 0); | |
| 955 | try test__fixtfti(math.floatMin(f128), 0); | |
| 956 | try test__fixtfti(0.5, 0); | |
| 957 | try test__fixtfti(0.99, 0); | |
| 958 | try test__fixtfti(1.0, 1); | |
| 959 | try test__fixtfti(1.5, 1); | |
| 960 | try test__fixtfti(1.99, 1); | |
| 961 | try test__fixtfti(2.0, 2); | |
| 962 | try test__fixtfti(2.01, 2); | |
| 963 | ||
| 964 | try test__fixtfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 965 | try test__fixtfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 966 | ||
| 967 | try test__fixtfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | |
| 968 | try test__fixtfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | |
| 969 | try test__fixtfti(0x1.0000000000000p+63, 0x8000000000000000); | |
| 970 | try test__fixtfti(0x1.0000000000001p+63, 0x8000000000000800); | |
| 971 | ||
| 972 | try test__fixtfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); | |
| 973 | try test__fixtfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); | |
| 974 | try test__fixtfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 975 | ||
| 976 | try test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 977 | try test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); | |
| 978 | ||
| 979 | try test__fixtfti(math.floatMax(f128), math.maxInt(i128)); | |
| 945 | test i128_intFromFloat_f128 { | |
| 946 | try test_i128_intFromFloat_f128(-math.floatMax(f128), math.minInt(i128)); | |
| 947 | ||
| 948 | try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); | |
| 949 | try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); | |
| 950 | ||
| 951 | try test_i128_intFromFloat_f128(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); | |
| 952 | try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000); | |
| 953 | try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000); | |
| 954 | ||
| 955 | try test_i128_intFromFloat_f128(-0x1.0000000000001p+63, -0x8000000000000800); | |
| 956 | try test_i128_intFromFloat_f128(-0x1.0000000000000p+63, -0x8000000000000000); | |
| 957 | try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); | |
| 958 | try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); | |
| 959 | ||
| 960 | try test_i128_intFromFloat_f128(-0x1.FFFFFEp+62, -0x7fffff8000000000); | |
| 961 | try test_i128_intFromFloat_f128(-0x1.FFFFFCp+62, -0x7fffff0000000000); | |
| 962 | ||
| 963 | try test_i128_intFromFloat_f128(-2.01, -2); | |
| 964 | try test_i128_intFromFloat_f128(-2.0, -2); | |
| 965 | try test_i128_intFromFloat_f128(-1.99, -1); | |
| 966 | try test_i128_intFromFloat_f128(-1.0, -1); | |
| 967 | try test_i128_intFromFloat_f128(-0.99, 0); | |
| 968 | try test_i128_intFromFloat_f128(-0.5, 0); | |
| 969 | try test_i128_intFromFloat_f128(-math.floatMin(f128), 0); | |
| 970 | try test_i128_intFromFloat_f128(0.0, 0); | |
| 971 | try test_i128_intFromFloat_f128(math.floatMin(f128), 0); | |
| 972 | try test_i128_intFromFloat_f128(0.5, 0); | |
| 973 | try test_i128_intFromFloat_f128(0.99, 0); | |
| 974 | try test_i128_intFromFloat_f128(1.0, 1); | |
| 975 | try test_i128_intFromFloat_f128(1.5, 1); | |
| 976 | try test_i128_intFromFloat_f128(1.99, 1); | |
| 977 | try test_i128_intFromFloat_f128(2.0, 2); | |
| 978 | try test_i128_intFromFloat_f128(2.01, 2); | |
| 979 | ||
| 980 | try test_i128_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000); | |
| 981 | try test_i128_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000); | |
| 982 | ||
| 983 | try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); | |
| 984 | try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); | |
| 985 | try test_i128_intFromFloat_f128(0x1.0000000000000p+63, 0x8000000000000000); | |
| 986 | try test_i128_intFromFloat_f128(0x1.0000000000001p+63, 0x8000000000000800); | |
| 987 | ||
| 988 | try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); | |
| 989 | try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); | |
| 990 | try test_i128_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 991 | ||
| 992 | try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 993 | try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); | |
| 994 | ||
| 995 | try test_i128_intFromFloat_f128(math.floatMax(f128), math.maxInt(i128)); | |
| 980 | 996 | } |
| 981 | 997 | |
| 982 | test "fixunstfti" { | |
| 983 | try test__fixunstfti(math.inf(f128), 0xffffffffffffffffffffffffffffffff); | |
| 998 | test u128_intFromFloat_f128 { | |
| 999 | try test_u128_intFromFloat_f128(math.inf(f128), 0xffffffffffffffffffffffffffffffff); | |
| 984 | 1000 | |
| 985 | try test__fixunstfti(0.0, 0); | |
| 1001 | try test_u128_intFromFloat_f128(0.0, 0); | |
| 986 | 1002 | |
| 987 | try test__fixunstfti(0.5, 0); | |
| 988 | try test__fixunstfti(0.99, 0); | |
| 989 | try test__fixunstfti(1.0, 1); | |
| 990 | try test__fixunstfti(1.5, 1); | |
| 991 | try test__fixunstfti(1.99, 1); | |
| 992 | try test__fixunstfti(2.0, 2); | |
| 993 | try test__fixunstfti(2.01, 2); | |
| 994 | try test__fixunstfti(-0.01, 0); | |
| 995 | try test__fixunstfti(-0.99, 0); | |
| 1003 | try test_u128_intFromFloat_f128(0.5, 0); | |
| 1004 | try test_u128_intFromFloat_f128(0.99, 0); | |
| 1005 | try test_u128_intFromFloat_f128(1.0, 1); | |
| 1006 | try test_u128_intFromFloat_f128(1.5, 1); | |
| 1007 | try test_u128_intFromFloat_f128(1.99, 1); | |
| 1008 | try test_u128_intFromFloat_f128(2.0, 2); | |
| 1009 | try test_u128_intFromFloat_f128(2.01, 2); | |
| 1010 | try test_u128_intFromFloat_f128(-0.01, 0); | |
| 1011 | try test_u128_intFromFloat_f128(-0.99, 0); | |
| 996 | 1012 | |
| 997 | try test__fixunstfti(0x1p+128, 0xffffffffffffffffffffffffffffffff); | |
| 1013 | try test_u128_intFromFloat_f128(0x1p+128, 0xffffffffffffffffffffffffffffffff); | |
| 998 | 1014 | |
| 999 | try test__fixunstfti(0x1.FFFFFEp+126, 0x7fffff80000000000000000000000000); | |
| 1000 | try test__fixunstfti(0x1.FFFFFEp+127, 0xffffff00000000000000000000000000); | |
| 1001 | try test__fixunstfti(0x1.FFFFFEp+128, 0xffffffffffffffffffffffffffffffff); | |
| 1002 | try test__fixunstfti(0x1.FFFFFEp+129, 0xffffffffffffffffffffffffffffffff); | |
| 1015 | try test_u128_intFromFloat_f128(0x1.FFFFFEp+126, 0x7fffff80000000000000000000000000); | |
| 1016 | try test_u128_intFromFloat_f128(0x1.FFFFFEp+127, 0xffffff00000000000000000000000000); | |
| 1017 | try test_u128_intFromFloat_f128(0x1.FFFFFEp+128, 0xffffffffffffffffffffffffffffffff); | |
| 1018 | try test_u128_intFromFloat_f128(0x1.FFFFFEp+129, 0xffffffffffffffffffffffffffffffff); | |
| 1003 | 1019 | } |
| 1004 | 1020 | |
| 1005 | fn test__fixunshfti(a: f16, expected: u128) !void { | |
| 1006 | const x = __fixunshfti(a); | |
| 1021 | fn test_u128_intFromFloat_f16(a: f16, expected: u128) !void { | |
| 1022 | const x = impl.u128_intFromFloat_f16(a); | |
| 1007 | 1023 | try testing.expect(x == expected); |
| 1008 | 1024 | } |
| 1009 | 1025 | |
| 1010 | test "fixunshfti for f16" { | |
| 1011 | try test__fixunshfti(math.inf(f16), math.maxInt(u128)); | |
| 1012 | try test__fixunshfti(math.floatMax(f16), 65504); | |
| 1026 | test u128_intFromFloat_f16 { | |
| 1027 | try test_u128_intFromFloat_f16(math.inf(f16), math.maxInt(u128)); | |
| 1028 | try test_u128_intFromFloat_f16(math.floatMax(f16), 65504); | |
| 1013 | 1029 | } |
| 1014 | 1030 | |
| 1015 | fn test__fixunsxfti(a: f80, expected: u128) !void { | |
| 1016 | const x = __fixunsxfti(a); | |
| 1031 | fn test_u128_intFromFloat_f80(a: f80, expected: u128) !void { | |
| 1032 | const x = impl.u128_intFromFloat_f80(a); | |
| 1017 | 1033 | try testing.expect(x == expected); |
| 1018 | 1034 | } |
| 1019 | 1035 | |
| 1020 | test "fixunsxfti for f80" { | |
| 1021 | try test__fixunsxfti(math.inf(f80), math.maxInt(u128)); | |
| 1022 | try test__fixunsxfti(math.floatMax(f80), math.maxInt(u128)); | |
| 1023 | try test__fixunsxfti(math.maxInt(u64), math.maxInt(u64)); | |
| 1036 | test u128_intFromFloat_f80 { | |
| 1037 | try test_u128_intFromFloat_f80(math.inf(f80), math.maxInt(u128)); | |
| 1038 | try test_u128_intFromFloat_f80(math.floatMax(f80), math.maxInt(u128)); | |
| 1039 | try test_u128_intFromFloat_f80(math.maxInt(u64), math.maxInt(u64)); | |
| 1024 | 1040 | } |
lib/compiler_rt/limb64.zig+1-1| ... | ... | @@ -6,7 +6,7 @@ const minInt = std.math.minInt; |
| 6 | 6 | |
| 7 | 7 | const builtin = @import("builtin"); |
| 8 | 8 | const compiler_rt = @import("../compiler_rt.zig"); |
| 9 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 9 | const symbol = compiler_rt.symbol; | |
| 10 | 10 | |
| 11 | 11 | const endian = builtin.cpu.arch.endian(); |
| 12 | 12 |
lib/compiler_rt/log.zig+112-97| ... | ... | @@ -11,7 +11,7 @@ const expectEqual = std.testing.expectEqual; |
| 11 | 11 | const expectApproxEqRel = std.testing.expectApproxEqRel; |
| 12 | 12 | |
| 13 | 13 | const compiler_rt = @import("../compiler_rt.zig"); |
| 14 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 14 | const symbol = compiler_rt.symbol; | |
| 15 | 15 | |
| 16 | 16 | comptime { |
| 17 | 17 | symbol(&__logh, "__logh"); |
| ... | ... | @@ -25,12 +25,18 @@ comptime { |
| 25 | 25 | symbol(&logl, "logl"); |
| 26 | 26 | } |
| 27 | 27 | |
| 28 | pub fn __logh(a: f16) callconv(.c) f16 { | |
| 28 | fn __logh(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 29 | return compiler_rt.f16.toAbi(log_f16(compiler_rt.f16.fromAbi(a))); | |
| 30 | } | |
| 31 | pub fn log_f16(a: f16) f16 { | |
| 29 | 32 | // TODO: more efficient implementation |
| 30 | return @floatCast(logf(a)); | |
| 33 | return @floatCast(log_f32(a)); | |
| 31 | 34 | } |
| 32 | 35 | |
| 33 | pub fn logf(x_: f32) callconv(.c) f32 { | |
| 36 | fn logf(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 37 | return compiler_rt.f32.toAbi(log_f32(compiler_rt.f32.fromAbi(a))); | |
| 38 | } | |
| 39 | pub fn log_f32(x_: f32) f32 { | |
| 34 | 40 | const ln2_hi: f32 = 6.9313812256e-01; |
| 35 | 41 | const ln2_lo: f32 = 9.0580006145e-06; |
| 36 | 42 | const Lg1: f32 = 0xaaaaaa.0p-24; |
| ... | ... | @@ -82,7 +88,10 @@ pub fn logf(x_: f32) callconv(.c) f32 { |
| 82 | 88 | return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi; |
| 83 | 89 | } |
| 84 | 90 | |
| 85 | pub fn log(x: f64) callconv(.c) f64 { | |
| 91 | fn log(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 92 | return compiler_rt.f64.toAbi(log_f64(compiler_rt.f64.fromAbi(a))); | |
| 93 | } | |
| 94 | pub fn log_f64(x: f64) f64 { | |
| 86 | 95 | const poly1 = [_]f64{ |
| 87 | 96 | -0x1p-1, |
| 88 | 97 | 0x1.5555555555577p-2, |
| ... | ... | @@ -432,11 +441,17 @@ pub fn log(x: f64) callconv(.c) f64 { |
| 432 | 441 | return @bitCast(y); |
| 433 | 442 | } |
| 434 | 443 | |
| 435 | pub fn __logx(a: f80) callconv(.c) f80 { | |
| 444 | fn __logx(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 445 | return compiler_rt.f80.toAbi(log_f80(compiler_rt.f80.fromAbi(a))); | |
| 446 | } | |
| 447 | pub fn log_f80(a: f80) f80 { | |
| 436 | 448 | // TODO: more efficient implementation |
| 437 | return @floatCast(logq(a)); | |
| 449 | return @floatCast(log_f128(a)); | |
| 438 | 450 | } |
| 439 | 451 | |
| 452 | fn logq(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 453 | return compiler_rt.f128.toAbi(log_f128(compiler_rt.f128.fromAbi(a))); | |
| 454 | } | |
| 440 | 455 | /// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic" |
| 441 | 456 | /// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990 |
| 442 | 457 | /// |
| ... | ... | @@ -449,7 +464,7 @@ pub fn __logx(a: f80) callconv(.c) f80 { |
| 449 | 464 | /// |
| 450 | 465 | /// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case): |
| 451 | 466 | /// <= 0.5 ulp: 99.96%, worst case <= 0.528 ulp |
| 452 | pub fn logq(x: f128) callconv(.c) f128 { | |
| 467 | pub fn log_f128(x: f128) f128 { | |
| 453 | 468 | const impl = @import("log_f128.zig"); |
| 454 | 469 | |
| 455 | 470 | if (impl.specialCases(x)) |y| |
| ... | ... | @@ -626,123 +641,123 @@ pub fn logq(x: f128) callconv(.c) f128 { |
| 626 | 641 | |
| 627 | 642 | pub fn logl(x: c_longdouble) callconv(.c) c_longdouble { |
| 628 | 643 | switch (@typeInfo(c_longdouble).float.bits) { |
| 629 | 64 => return log(x), | |
| 630 | 80 => return __logx(x), | |
| 631 | 128 => return logq(x), | |
| 632 | else => @compileError("unreachable"), | |
| 644 | 64 => return log_f64(x), | |
| 645 | 80 => return log_f80(x), | |
| 646 | 128 => return log_f128(x), | |
| 647 | else => comptime unreachable, | |
| 633 | 648 | } |
| 634 | 649 | } |
| 635 | 650 | |
| 636 | 651 | test "logf() special" { |
| 637 | try expectEqual(logf(0.0), -math.inf(f32)); | |
| 638 | try expectEqual(logf(-0.0), -math.inf(f32)); | |
| 639 | try expect(math.isPositiveZero(logf(1.0))); | |
| 640 | try expectEqual(logf(math.e), 1.0); | |
| 641 | try expectEqual(logf(math.inf(f32)), math.inf(f32)); | |
| 642 | try expect(math.isNan(logf(-1.0))); | |
| 643 | try expect(math.isNan(logf(-math.inf(f32)))); | |
| 644 | try expect(math.isNan(logf(math.nan(f32)))); | |
| 645 | try expect(math.isNan(logf(math.snan(f32)))); | |
| 652 | try expectEqual(log_f32(0.0), -math.inf(f32)); | |
| 653 | try expectEqual(log_f32(-0.0), -math.inf(f32)); | |
| 654 | try expect(math.isPositiveZero(log_f32(1.0))); | |
| 655 | try expectEqual(log_f32(math.e), 1.0); | |
| 656 | try expectEqual(log_f32(math.inf(f32)), math.inf(f32)); | |
| 657 | try expect(math.isNan(log_f32(-1.0))); | |
| 658 | try expect(math.isNan(log_f32(-math.inf(f32)))); | |
| 659 | try expect(math.isNan(log_f32(math.nan(f32)))); | |
| 660 | try expect(math.isNan(log_f32(math.snan(f32)))); | |
| 646 | 661 | } |
| 647 | 662 | |
| 648 | 663 | test "logf() sanity" { |
| 649 | try expect(math.isNan(logf(-0x1.0223a0p+3))); | |
| 650 | try expectEqual(logf(0x1.161868p+2), 0x1.7815b0p+0); | |
| 651 | try expect(math.isNan(logf(-0x1.0c34b4p+3))); | |
| 652 | try expect(math.isNan(logf(-0x1.a206f0p+2))); | |
| 653 | try expectEqual(logf(0x1.288bbcp+3), 0x1.1cfcd6p+1); | |
| 654 | try expectEqual(logf(0x1.52efd0p-1), -0x1.a6694cp-2); | |
| 655 | try expect(math.isNan(logf(-0x1.a05cc8p-2))); | |
| 656 | try expectEqual(logf(0x1.1f9efap-1), -0x1.2742bap-1); | |
| 657 | try expectEqual(logf(0x1.8c5db0p-1), -0x1.062160p-2); | |
| 658 | try expect(math.isNan(logf(-0x1.5b86eap-1))); | |
| 664 | try expect(math.isNan(log_f32(-0x1.0223a0p+3))); | |
| 665 | try expectEqual(log_f32(0x1.161868p+2), 0x1.7815b0p+0); | |
| 666 | try expect(math.isNan(log_f32(-0x1.0c34b4p+3))); | |
| 667 | try expect(math.isNan(log_f32(-0x1.a206f0p+2))); | |
| 668 | try expectEqual(log_f32(0x1.288bbcp+3), 0x1.1cfcd6p+1); | |
| 669 | try expectEqual(log_f32(0x1.52efd0p-1), -0x1.a6694cp-2); | |
| 670 | try expect(math.isNan(log_f32(-0x1.a05cc8p-2))); | |
| 671 | try expectEqual(log_f32(0x1.1f9efap-1), -0x1.2742bap-1); | |
| 672 | try expectEqual(log_f32(0x1.8c5db0p-1), -0x1.062160p-2); | |
| 673 | try expect(math.isNan(log_f32(-0x1.5b86eap-1))); | |
| 659 | 674 | } |
| 660 | 675 | |
| 661 | 676 | test "logf() boundary" { |
| 662 | try expectEqual(logf(0x1.fffffep+127), 0x1.62e430p+6); // Max input value | |
| 663 | try expectEqual(logf(0x1p-149), -0x1.9d1da0p+6); // Min positive input value | |
| 664 | try expect(math.isNan(logf(-0x1p-149))); // Min negative input value | |
| 665 | try expectEqual(logf(0x1.000002p+0), 0x1.fffffep-24); // Last value before result reaches +0 | |
| 666 | try expectEqual(logf(0x1.fffffep-1), -0x1p-24); // Last value before result reaches -0 | |
| 667 | try expectEqual(logf(0x1p-126), -0x1.5d58a0p+6); // First subnormal | |
| 668 | try expect(math.isNan(logf(-0x1p-126))); // First negative subnormal | |
| 677 | try expectEqual(log_f32(0x1.fffffep+127), 0x1.62e430p+6); // Max input value | |
| 678 | try expectEqual(log_f32(0x1p-149), -0x1.9d1da0p+6); // Min positive input value | |
| 679 | try expect(math.isNan(log_f32(-0x1p-149))); // Min negative input value | |
| 680 | try expectEqual(log_f32(0x1.000002p+0), 0x1.fffffep-24); // Last value before result reaches +0 | |
| 681 | try expectEqual(log_f32(0x1.fffffep-1), -0x1p-24); // Last value before result reaches -0 | |
| 682 | try expectEqual(log_f32(0x1p-126), -0x1.5d58a0p+6); // First subnormal | |
| 683 | try expect(math.isNan(log_f32(-0x1p-126))); // First negative subnormal | |
| 669 | 684 | } |
| 670 | 685 | |
| 671 | 686 | test "log() special" { |
| 672 | try expectEqual(log(0.0), -math.inf(f64)); | |
| 673 | try expectEqual(log(-0.0), -math.inf(f64)); | |
| 674 | try expect(math.isPositiveZero(log(1.0))); | |
| 675 | try expectEqual(log(math.e), 1.0); | |
| 676 | try expectEqual(log(math.inf(f64)), math.inf(f64)); | |
| 677 | try expect(math.isNan(log(-1.0))); | |
| 678 | try expect(math.isNan(log(-math.inf(f64)))); | |
| 679 | try expect(math.isNan(log(math.nan(f64)))); | |
| 680 | try expect(math.isNan(log(math.snan(f64)))); | |
| 687 | try expectEqual(log_f64(0.0), -math.inf(f64)); | |
| 688 | try expectEqual(log_f64(-0.0), -math.inf(f64)); | |
| 689 | try expect(math.isPositiveZero(log_f64(1.0))); | |
| 690 | try expectEqual(log_f64(math.e), 1.0); | |
| 691 | try expectEqual(log_f64(math.inf(f64)), math.inf(f64)); | |
| 692 | try expect(math.isNan(log_f64(-1.0))); | |
| 693 | try expect(math.isNan(log_f64(-math.inf(f64)))); | |
| 694 | try expect(math.isNan(log_f64(math.nan(f64)))); | |
| 695 | try expect(math.isNan(log_f64(math.snan(f64)))); | |
| 681 | 696 | } |
| 682 | 697 | |
| 683 | 698 | test "log() sanity" { |
| 684 | try expect(math.isNan(log(-0x1.02239f3c6a8f1p+3))); | |
| 685 | try expectEqual(log(0x1.161868e18bc67p+2), 0x1.7815b08f99c65p+0); | |
| 686 | try expect(math.isNan(log(-0x1.0c34b3e01e6e7p+3))); | |
| 687 | try expect(math.isNan(log(-0x1.a206f0a19dcc4p+2))); | |
| 688 | try expectEqual(log(0x1.288bbb0d6a1e6p+3), 0x1.1cfcd53d72604p+1); | |
| 689 | try expectEqual(log(0x1.52efd0cd80497p-1), -0x1.a6694a4a85621p-2); | |
| 690 | try expect(math.isNan(log(-0x1.a05cc754481d1p-2))); | |
| 691 | try expectEqual(log(0x1.1f9ef934745cbp-1), -0x1.2742bc03d02ddp-1); | |
| 692 | try expectEqual(log(0x1.8c5db097f7442p-1), -0x1.06215de4a3f92p-2); | |
| 693 | try expect(math.isNan(log(-0x1.5b86ea8118a0ep-1))); | |
| 699 | try expect(math.isNan(log_f64(-0x1.02239f3c6a8f1p+3))); | |
| 700 | try expectEqual(log_f64(0x1.161868e18bc67p+2), 0x1.7815b08f99c65p+0); | |
| 701 | try expect(math.isNan(log_f64(-0x1.0c34b3e01e6e7p+3))); | |
| 702 | try expect(math.isNan(log_f64(-0x1.a206f0a19dcc4p+2))); | |
| 703 | try expectEqual(log_f64(0x1.288bbb0d6a1e6p+3), 0x1.1cfcd53d72604p+1); | |
| 704 | try expectEqual(log_f64(0x1.52efd0cd80497p-1), -0x1.a6694a4a85621p-2); | |
| 705 | try expect(math.isNan(log_f64(-0x1.a05cc754481d1p-2))); | |
| 706 | try expectEqual(log_f64(0x1.1f9ef934745cbp-1), -0x1.2742bc03d02ddp-1); | |
| 707 | try expectEqual(log_f64(0x1.8c5db097f7442p-1), -0x1.06215de4a3f92p-2); | |
| 708 | try expect(math.isNan(log_f64(-0x1.5b86ea8118a0ep-1))); | |
| 694 | 709 | } |
| 695 | 710 | |
| 696 | 711 | test "log() boundary" { |
| 697 | try expectEqual(log(0x1.fffffffffffffp+1023), 0x1.62e42fefa39efp+9); // Max input value | |
| 698 | try expectEqual(log(0x1p-1074), -0x1.74385446d71c3p+9); // Min positive input value | |
| 699 | try expect(math.isNan(log(-0x1p-1074))); // Min negative input value | |
| 700 | try expectEqual(log(0x1.0000000000001p+0), 0x1.fffffffffffffp-53); // Last value before result reaches +0 | |
| 701 | try expectEqual(log(0x1.fffffffffffffp-1), -0x1p-53); // Last value before result reaches -0 | |
| 702 | try expectEqual(log(0x1p-1022), -0x1.6232bdd7abcd2p+9); // First subnormal | |
| 703 | try expect(math.isNan(log(-0x1p-1022))); // First negative subnormal | |
| 712 | try expectEqual(log_f64(0x1.fffffffffffffp+1023), 0x1.62e42fefa39efp+9); // Max input value | |
| 713 | try expectEqual(log_f64(0x1p-1074), -0x1.74385446d71c3p+9); // Min positive input value | |
| 714 | try expect(math.isNan(log_f64(-0x1p-1074))); // Min negative input value | |
| 715 | try expectEqual(log_f64(0x1.0000000000001p+0), 0x1.fffffffffffffp-53); // Last value before result reaches +0 | |
| 716 | try expectEqual(log_f64(0x1.fffffffffffffp-1), -0x1p-53); // Last value before result reaches -0 | |
| 717 | try expectEqual(log_f64(0x1p-1022), -0x1.6232bdd7abcd2p+9); // First subnormal | |
| 718 | try expect(math.isNan(log_f64(-0x1p-1022))); // First negative subnormal | |
| 704 | 719 | } |
| 705 | 720 | |
| 706 | 721 | test "logq() special" { |
| 707 | try expectEqual(logq(0.0), -math.inf(f128)); | |
| 708 | try expectEqual(logq(-0.0), -math.inf(f128)); | |
| 709 | try expect(math.isPositiveZero(logq(1.0))); | |
| 722 | try expectEqual(log_f128(0.0), -math.inf(f128)); | |
| 723 | try expectEqual(log_f128(-0.0), -math.inf(f128)); | |
| 724 | try expect(math.isPositiveZero(log_f128(1.0))); | |
| 710 | 725 | // Sadly, the rounding gods decided that 0.9999999999999999999999999999999999 |
| 711 | // is the correctly rounded value of logq(math.e) | |
| 712 | try expectApproxEqRel(logq(math.e), 1.0, math.floatEpsAt(f128, 1.0)); | |
| 713 | try expectEqual(logq(math.inf(f128)), math.inf(f128)); | |
| 714 | try expect(math.isNan(logq(-1.0))); | |
| 715 | try expect(math.isNan(logq(-math.inf(f128)))); | |
| 716 | try expect(math.isNan(logq(math.nan(f128)))); | |
| 717 | try expect(math.isNan(logq(math.snan(f128)))); | |
| 726 | // is the correctly rounded value of log_f128(math.e) | |
| 727 | try expectApproxEqRel(log_f128(math.e), 1.0, math.floatEpsAt(f128, 1.0)); | |
| 728 | try expectEqual(log_f128(math.inf(f128)), math.inf(f128)); | |
| 729 | try expect(math.isNan(log_f128(-1.0))); | |
| 730 | try expect(math.isNan(log_f128(-math.inf(f128)))); | |
| 731 | try expect(math.isNan(log_f128(math.nan(f128)))); | |
| 732 | try expect(math.isNan(log_f128(math.snan(f128)))); | |
| 718 | 733 | } |
| 719 | 734 | |
| 720 | 735 | test "logq() boundary" { |
| 721 | try expectEqual(logq(0x1.ffffffffffffffffffffffffffffp16383), 0x1.62e42fefa39ef35793c7673007e6p13); // Max input value | |
| 722 | try expectEqual(logq(0x1p-16494), -0x1.6546282207802c89d24d65e96274p13); // Min positive input value | |
| 723 | try expect(math.isNan(logq(-0x1p-16494))); // Min negative input value | |
| 724 | try expectEqual(logq(0x1.0000000000000000000000000001p0), 0x1.ffffffffffffffffffffffffffffp-113); // Last value before result reaches +0 | |
| 725 | try expectEqual(logq(0x1.ffffffffffffffffffffffffffffp-1), -0x1p-113); // Last value before result reaches -0 | |
| 726 | try expectEqual(logq(0x1p-16382), -0x1.62d918ce2421d65ff90ac8f4ce66p13); // First subnormal | |
| 727 | try expect(math.isNan(logq(-0x1p-16382))); // First negative subnormal | |
| 736 | try expectEqual(log_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1.62e42fefa39ef35793c7673007e6p13); // Max input value | |
| 737 | try expectEqual(log_f128(0x1p-16494), -0x1.6546282207802c89d24d65e96274p13); // Min positive input value | |
| 738 | try expect(math.isNan(log_f128(-0x1p-16494))); // Min negative input value | |
| 739 | try expectEqual(log_f128(0x1.0000000000000000000000000001p0), 0x1.ffffffffffffffffffffffffffffp-113); // Last value before result reaches +0 | |
| 740 | try expectEqual(log_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1p-113); // Last value before result reaches -0 | |
| 741 | try expectEqual(log_f128(0x1p-16382), -0x1.62d918ce2421d65ff90ac8f4ce66p13); // First subnormal | |
| 742 | try expect(math.isNan(log_f128(-0x1p-16382))); // First negative subnormal | |
| 728 | 743 | } |
| 729 | 744 | |
| 730 | 745 | test "logq() sanity" { |
| 731 | try expectEqual(logq(4.151135979023751199079583784623537e-4), -7.7869583453055243113993340258295346e0); | |
| 732 | try expectEqual(logq(9.614234245933828353176667689130293e-14), -2.9972946567656004014786271559909435e1); | |
| 733 | try expectEqual(logq(1.012889803704721484375e13), 2.9946413646144315985379677542014356e1); | |
| 734 | try expectEqual(logq(2.397741857206453154086912e24), 5.613656963346284538829358703465392e1); | |
| 735 | try expectEqual(logq(3.442377567808290806386655232e27), 6.3405959896920645453203836625419693e1); | |
| 736 | try expectEqual(logq(1.0689155158234028407981544637594257e-8), -1.835403614606774451014272772421113e1); | |
| 737 | try expectEqual(logq(1.4813913545768791536741499811327596e-10), -2.263286917934202003739900705050399e1); | |
| 738 | try expectEqual(logq(4.518948965781299591064453125e10), 2.453413036705097282892685629562292e1); | |
| 739 | try expectEqual(logq(1.200355637363589375e14), 3.2418809179272977400408325788186897e1); | |
| 740 | try expectEqual(logq(6.6145398293682003021240234375e9), 2.261253606737223221601998075023261e1); | |
| 741 | try expectEqual(logq(5.16179116383965741056e20), 4.7692985503915646405875629300054525e1); | |
| 746 | try expectEqual(log_f128(4.151135979023751199079583784623537e-4), -7.7869583453055243113993340258295346e0); | |
| 747 | try expectEqual(log_f128(9.614234245933828353176667689130293e-14), -2.9972946567656004014786271559909435e1); | |
| 748 | try expectEqual(log_f128(1.012889803704721484375e13), 2.9946413646144315985379677542014356e1); | |
| 749 | try expectEqual(log_f128(2.397741857206453154086912e24), 5.613656963346284538829358703465392e1); | |
| 750 | try expectEqual(log_f128(3.442377567808290806386655232e27), 6.3405959896920645453203836625419693e1); | |
| 751 | try expectEqual(log_f128(1.0689155158234028407981544637594257e-8), -1.835403614606774451014272772421113e1); | |
| 752 | try expectEqual(log_f128(1.4813913545768791536741499811327596e-10), -2.263286917934202003739900705050399e1); | |
| 753 | try expectEqual(log_f128(4.518948965781299591064453125e10), 2.453413036705097282892685629562292e1); | |
| 754 | try expectEqual(log_f128(1.200355637363589375e14), 3.2418809179272977400408325788186897e1); | |
| 755 | try expectEqual(log_f128(6.6145398293682003021240234375e9), 2.261253606737223221601998075023261e1); | |
| 756 | try expectEqual(log_f128(5.16179116383965741056e20), 4.7692985503915646405875629300054525e1); | |
| 742 | 757 | // testing near 1 |
| 743 | try expectEqual(logq(1.026586845186097528392910049888087e0), 2.6239557099466251374193777672800004e-2); | |
| 744 | try expectEqual(logq(9.878220373715243107115568932385941e-1), -1.2252721576456821219120474521538944e-2); | |
| 745 | try expectEqual(logq(9.417921077517196685541245315675951e-1), -5.997072116986790367958922503195352e-2); | |
| 746 | try expectEqual(logq(1.043095786320424537962914257605007e0), 4.219300911769055080390811808602425e-2); | |
| 747 | try expectEqual(logq(1.019043049323190694932517175175235e0), 1.8863999985309781522599012445793722e-2); | |
| 758 | try expectEqual(log_f128(1.026586845186097528392910049888087e0), 2.6239557099466251374193777672800004e-2); | |
| 759 | try expectEqual(log_f128(9.878220373715243107115568932385941e-1), -1.2252721576456821219120474521538944e-2); | |
| 760 | try expectEqual(log_f128(9.417921077517196685541245315675951e-1), -5.997072116986790367958922503195352e-2); | |
| 761 | try expectEqual(log_f128(1.043095786320424537962914257605007e0), 4.219300911769055080390811808602425e-2); | |
| 762 | try expectEqual(log_f128(1.019043049323190694932517175175235e0), 1.8863999985309781522599012445793722e-2); | |
| 748 | 763 | } |
lib/compiler_rt/log10.zig+113-98| ... | ... | @@ -25,12 +25,18 @@ comptime { |
| 25 | 25 | symbol(&log10l, "log10l"); |
| 26 | 26 | } |
| 27 | 27 | |
| 28 | pub fn __log10h(a: f16) callconv(.c) f16 { | |
| 28 | fn __log10h(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 29 | return compiler_rt.f16.toAbi(log10_f16(compiler_rt.f16.fromAbi(a))); | |
| 30 | } | |
| 31 | pub fn log10_f16(a: f16) f16 { | |
| 29 | 32 | // TODO: more efficient implementation |
| 30 | return @floatCast(log10f(a)); | |
| 33 | return @floatCast(log10_f32(a)); | |
| 31 | 34 | } |
| 32 | 35 | |
| 33 | pub fn log10f(x_: f32) callconv(.c) f32 { | |
| 36 | fn log10f(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 37 | return compiler_rt.f32.toAbi(log10_f32(compiler_rt.f32.fromAbi(a))); | |
| 38 | } | |
| 39 | pub fn log10_f32(x_: f32) f32 { | |
| 34 | 40 | const ivln10hi: f32 = 4.3432617188e-01; |
| 35 | 41 | const ivln10lo: f32 = -3.1689971365e-05; |
| 36 | 42 | const log10_2hi: f32 = 3.0102920532e-01; |
| ... | ... | @@ -90,7 +96,10 @@ pub fn log10f(x_: f32) callconv(.c) f32 { |
| 90 | 96 | return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi; |
| 91 | 97 | } |
| 92 | 98 | |
| 93 | pub fn log10(x_: f64) callconv(.c) f64 { | |
| 99 | fn log10(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 100 | return compiler_rt.f64.toAbi(log10_f64(compiler_rt.f64.fromAbi(a))); | |
| 101 | } | |
| 102 | pub fn log10_f64(x_: f64) f64 { | |
| 94 | 103 | const ivln10hi: f64 = 4.34294481878168880939e-01; |
| 95 | 104 | const ivln10lo: f64 = 2.50829467116452752298e-11; |
| 96 | 105 | const log10_2hi: f64 = 3.01029995663611771306e-01; |
| ... | ... | @@ -165,11 +174,17 @@ pub fn log10(x_: f64) callconv(.c) f64 { |
| 165 | 174 | return val_lo + val_hi; |
| 166 | 175 | } |
| 167 | 176 | |
| 168 | pub fn __log10x(a: f80) callconv(.c) f80 { | |
| 177 | fn __log10x(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 178 | return compiler_rt.f80.toAbi(log10_f80(compiler_rt.f80.fromAbi(a))); | |
| 179 | } | |
| 180 | pub fn log10_f80(a: f80) f80 { | |
| 169 | 181 | // TODO: more efficient implementation |
| 170 | return @floatCast(log10q(a)); | |
| 182 | return @floatCast(log10_f128(a)); | |
| 171 | 183 | } |
| 172 | 184 | |
| 185 | fn log10q(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 186 | return compiler_rt.f128.toAbi(log10_f128(compiler_rt.f128.fromAbi(a))); | |
| 187 | } | |
| 173 | 188 | /// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic" |
| 174 | 189 | /// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990 |
| 175 | 190 | /// |
| ... | ... | @@ -182,7 +197,7 @@ pub fn __log10x(a: f80) callconv(.c) f80 { |
| 182 | 197 | /// |
| 183 | 198 | /// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case): |
| 184 | 199 | /// <= 0.5 ulp: 99.96%, worst case <= 0.565 ulp |
| 185 | pub fn log10q(x: f128) callconv(.c) f128 { | |
| 200 | pub fn log10_f128(x: f128) f128 { | |
| 186 | 201 | const impl = @import("log_f128.zig"); |
| 187 | 202 | |
| 188 | 203 | if (impl.specialCases(x)) |y| |
| ... | ... | @@ -359,124 +374,124 @@ pub fn log10q(x: f128) callconv(.c) f128 { |
| 359 | 374 | |
| 360 | 375 | pub fn log10l(x: c_longdouble) callconv(.c) c_longdouble { |
| 361 | 376 | switch (@typeInfo(c_longdouble).float.bits) { |
| 362 | 64 => return log10(x), | |
| 363 | 80 => return __log10x(x), | |
| 364 | 128 => return log10q(x), | |
| 365 | else => @compileError("unreachable"), | |
| 377 | 64 => return log10_f64(x), | |
| 378 | 80 => return log10_f80(x), | |
| 379 | 128 => return log10_f128(x), | |
| 380 | else => comptime unreachable, | |
| 366 | 381 | } |
| 367 | 382 | } |
| 368 | 383 | |
| 369 | 384 | test "log10f() special" { |
| 370 | try expectEqual(log10f(0.0), -math.inf(f32)); | |
| 371 | try expectEqual(log10f(-0.0), -math.inf(f32)); | |
| 372 | try expect(math.isPositiveZero(log10f(1.0))); | |
| 373 | try expectEqual(log10f(10.0), 1.0); | |
| 374 | try expectEqual(log10f(0.1), -1.0); | |
| 375 | try expectEqual(log10f(math.inf(f32)), math.inf(f32)); | |
| 376 | try expect(math.isNan(log10f(-1.0))); | |
| 377 | try expect(math.isNan(log10f(-math.inf(f32)))); | |
| 378 | try expect(math.isNan(log10f(math.nan(f32)))); | |
| 379 | try expect(math.isNan(log10f(math.snan(f32)))); | |
| 385 | try expectEqual(log10_f32(0.0), -math.inf(f32)); | |
| 386 | try expectEqual(log10_f32(-0.0), -math.inf(f32)); | |
| 387 | try expect(math.isPositiveZero(log10_f32(1.0))); | |
| 388 | try expectEqual(log10_f32(10.0), 1.0); | |
| 389 | try expectEqual(log10_f32(0.1), -1.0); | |
| 390 | try expectEqual(log10_f32(math.inf(f32)), math.inf(f32)); | |
| 391 | try expect(math.isNan(log10_f32(-1.0))); | |
| 392 | try expect(math.isNan(log10_f32(-math.inf(f32)))); | |
| 393 | try expect(math.isNan(log10_f32(math.nan(f32)))); | |
| 394 | try expect(math.isNan(log10_f32(math.snan(f32)))); | |
| 380 | 395 | } |
| 381 | 396 | |
| 382 | 397 | test "log10f() sanity" { |
| 383 | try expect(math.isNan(log10f(-0x1.0223a0p+3))); | |
| 384 | try expectEqual(log10f(0x1.161868p+2), 0x1.46a9bcp-1); | |
| 385 | try expect(math.isNan(log10f(-0x1.0c34b4p+3))); | |
| 386 | try expect(math.isNan(log10f(-0x1.a206f0p+2))); | |
| 387 | try expectEqual(log10f(0x1.288bbcp+3), 0x1.ef1300p-1); | |
| 388 | try expectEqual(log10f(0x1.52efd0p-1), -0x1.6ee6dcp-3); // Disagrees with GCC in last bit | |
| 389 | try expect(math.isNan(log10f(-0x1.a05cc8p-2))); | |
| 390 | try expectEqual(log10f(0x1.1f9efap-1), -0x1.0075ccp-2); | |
| 391 | try expectEqual(log10f(0x1.8c5db0p-1), -0x1.c75df8p-4); | |
| 392 | try expect(math.isNan(log10f(-0x1.5b86eap-1))); | |
| 398 | try expect(math.isNan(log10_f32(-0x1.0223a0p+3))); | |
| 399 | try expectEqual(log10_f32(0x1.161868p+2), 0x1.46a9bcp-1); | |
| 400 | try expect(math.isNan(log10_f32(-0x1.0c34b4p+3))); | |
| 401 | try expect(math.isNan(log10_f32(-0x1.a206f0p+2))); | |
| 402 | try expectEqual(log10_f32(0x1.288bbcp+3), 0x1.ef1300p-1); | |
| 403 | try expectEqual(log10_f32(0x1.52efd0p-1), -0x1.6ee6dcp-3); // Disagrees with GCC in last bit | |
| 404 | try expect(math.isNan(log10_f32(-0x1.a05cc8p-2))); | |
| 405 | try expectEqual(log10_f32(0x1.1f9efap-1), -0x1.0075ccp-2); | |
| 406 | try expectEqual(log10_f32(0x1.8c5db0p-1), -0x1.c75df8p-4); | |
| 407 | try expect(math.isNan(log10_f32(-0x1.5b86eap-1))); | |
| 393 | 408 | } |
| 394 | 409 | |
| 395 | 410 | test "log10f() boundary" { |
| 396 | try expectEqual(log10f(0x1.fffffep+127), 0x1.344136p+5); // Max input value | |
| 397 | try expectEqual(log10f(0x1p-149), -0x1.66d3e8p+5); // Min positive input value | |
| 398 | try expect(math.isNan(log10f(-0x1p-149))); // Min negative input value | |
| 399 | try expectEqual(log10f(0x1.000002p+0), 0x1.bcb7b0p-25); // Last value before result reaches +0 | |
| 400 | try expectEqual(log10f(0x1.fffffep-1), -0x1.bcb7b2p-26); // Last value before result reaches -0 | |
| 401 | try expectEqual(log10f(0x1p-126), -0x1.2f7030p+5); // First subnormal | |
| 402 | try expect(math.isNan(log10f(-0x1p-126))); // First negative subnormal | |
| 411 | try expectEqual(log10_f32(0x1.fffffep+127), 0x1.344136p+5); // Max input value | |
| 412 | try expectEqual(log10_f32(0x1p-149), -0x1.66d3e8p+5); // Min positive input value | |
| 413 | try expect(math.isNan(log10_f32(-0x1p-149))); // Min negative input value | |
| 414 | try expectEqual(log10_f32(0x1.000002p+0), 0x1.bcb7b0p-25); // Last value before result reaches +0 | |
| 415 | try expectEqual(log10_f32(0x1.fffffep-1), -0x1.bcb7b2p-26); // Last value before result reaches -0 | |
| 416 | try expectEqual(log10_f32(0x1p-126), -0x1.2f7030p+5); // First subnormal | |
| 417 | try expect(math.isNan(log10_f32(-0x1p-126))); // First negative subnormal | |
| 403 | 418 | } |
| 404 | 419 | |
| 405 | 420 | test "log10() special" { |
| 406 | try expectEqual(log10(0.0), -math.inf(f64)); | |
| 407 | try expectEqual(log10(-0.0), -math.inf(f64)); | |
| 408 | try expect(math.isPositiveZero(log10(1.0))); | |
| 409 | try expectEqual(log10(10.0), 1.0); | |
| 410 | try expectEqual(log10(0.1), -1.0); | |
| 411 | try expectEqual(log10(math.inf(f64)), math.inf(f64)); | |
| 412 | try expect(math.isNan(log10(-1.0))); | |
| 413 | try expect(math.isNan(log10(-math.inf(f64)))); | |
| 414 | try expect(math.isNan(log10(math.nan(f64)))); | |
| 415 | try expect(math.isNan(log10(math.snan(f64)))); | |
| 421 | try expectEqual(log10_f64(0.0), -math.inf(f64)); | |
| 422 | try expectEqual(log10_f64(-0.0), -math.inf(f64)); | |
| 423 | try expect(math.isPositiveZero(log10_f64(1.0))); | |
| 424 | try expectEqual(log10_f64(10.0), 1.0); | |
| 425 | try expectEqual(log10_f64(0.1), -1.0); | |
| 426 | try expectEqual(log10_f64(math.inf(f64)), math.inf(f64)); | |
| 427 | try expect(math.isNan(log10_f64(-1.0))); | |
| 428 | try expect(math.isNan(log10_f64(-math.inf(f64)))); | |
| 429 | try expect(math.isNan(log10_f64(math.nan(f64)))); | |
| 430 | try expect(math.isNan(log10_f64(math.snan(f64)))); | |
| 416 | 431 | } |
| 417 | 432 | |
| 418 | 433 | test "log10() sanity" { |
| 419 | try expect(math.isNan(log10(-0x1.02239f3c6a8f1p+3))); | |
| 420 | try expectEqual(log10(0x1.161868e18bc67p+2), 0x1.46a9bd1d2eb87p-1); | |
| 421 | try expect(math.isNan(log10(-0x1.0c34b3e01e6e7p+3))); | |
| 422 | try expect(math.isNan(log10(-0x1.a206f0a19dcc4p+2))); | |
| 423 | try expectEqual(log10(0x1.288bbb0d6a1e6p+3), 0x1.ef12fff994862p-1); | |
| 424 | try expectEqual(log10(0x1.52efd0cd80497p-1), -0x1.6ee6db5a155cbp-3); | |
| 425 | try expect(math.isNan(log10(-0x1.a05cc754481d1p-2))); | |
| 426 | try expectEqual(log10(0x1.1f9ef934745cbp-1), -0x1.0075cda79d321p-2); | |
| 427 | try expectEqual(log10(0x1.8c5db097f7442p-1), -0x1.c75df6442465ap-4); | |
| 428 | try expect(math.isNan(log10(-0x1.5b86ea8118a0ep-1))); | |
| 434 | try expect(math.isNan(log10_f64(-0x1.02239f3c6a8f1p+3))); | |
| 435 | try expectEqual(log10_f64(0x1.161868e18bc67p+2), 0x1.46a9bd1d2eb87p-1); | |
| 436 | try expect(math.isNan(log10_f64(-0x1.0c34b3e01e6e7p+3))); | |
| 437 | try expect(math.isNan(log10_f64(-0x1.a206f0a19dcc4p+2))); | |
| 438 | try expectEqual(log10_f64(0x1.288bbb0d6a1e6p+3), 0x1.ef12fff994862p-1); | |
| 439 | try expectEqual(log10_f64(0x1.52efd0cd80497p-1), -0x1.6ee6db5a155cbp-3); | |
| 440 | try expect(math.isNan(log10_f64(-0x1.a05cc754481d1p-2))); | |
| 441 | try expectEqual(log10_f64(0x1.1f9ef934745cbp-1), -0x1.0075cda79d321p-2); | |
| 442 | try expectEqual(log10_f64(0x1.8c5db097f7442p-1), -0x1.c75df6442465ap-4); | |
| 443 | try expect(math.isNan(log10_f64(-0x1.5b86ea8118a0ep-1))); | |
| 429 | 444 | } |
| 430 | 445 | |
| 431 | 446 | test "log10() boundary" { |
| 432 | try expectEqual(log10(0x1.fffffffffffffp+1023), 0x1.34413509f79ffp+8); // Max input value | |
| 433 | try expectEqual(log10(0x1p-1074), -0x1.434e6420f4374p+8); // Min positive input value | |
| 434 | try expect(math.isNan(log10(-0x1p-1074))); // Min negative input value | |
| 435 | try expectEqual(log10(0x1.0000000000001p+0), 0x1.bcb7b1526e50dp-54); // Last value before result reaches +0 | |
| 436 | try expectEqual(log10(0x1.fffffffffffffp-1), -0x1.bcb7b1526e50fp-55); // Last value before result reaches -0 | |
| 437 | try expectEqual(log10(0x1p-1022), -0x1.33a7146f72a42p+8); // First subnormal | |
| 438 | try expect(math.isNan(log10(-0x1p-1022))); // First negative subnormal | |
| 447 | try expectEqual(log10_f64(0x1.fffffffffffffp+1023), 0x1.34413509f79ffp+8); // Max input value | |
| 448 | try expectEqual(log10_f64(0x1p-1074), -0x1.434e6420f4374p+8); // Min positive input value | |
| 449 | try expect(math.isNan(log10_f64(-0x1p-1074))); // Min negative input value | |
| 450 | try expectEqual(log10_f64(0x1.0000000000001p+0), 0x1.bcb7b1526e50dp-54); // Last value before result reaches +0 | |
| 451 | try expectEqual(log10_f64(0x1.fffffffffffffp-1), -0x1.bcb7b1526e50fp-55); // Last value before result reaches -0 | |
| 452 | try expectEqual(log10_f64(0x1p-1022), -0x1.33a7146f72a42p+8); // First subnormal | |
| 453 | try expect(math.isNan(log10_f64(-0x1p-1022))); // First negative subnormal | |
| 439 | 454 | } |
| 440 | 455 | |
| 441 | 456 | test "log10q() special" { |
| 442 | try expectEqual(log10q(0.0), -math.inf(f128)); | |
| 443 | try expectEqual(log10q(-0.0), -math.inf(f128)); | |
| 444 | try expect(math.isPositiveZero(log10q(1.0))); | |
| 445 | try expectEqual(log10q(10.0), 1.0); | |
| 446 | try expectEqual(log10q(0.1), -1.0); | |
| 447 | try expectEqual(log10q(math.inf(f128)), math.inf(f128)); | |
| 448 | try expect(math.isNan(log10q(-1.0))); | |
| 449 | try expect(math.isNan(log10q(-math.inf(f128)))); | |
| 450 | try expect(math.isNan(log10q(math.nan(f128)))); | |
| 451 | try expect(math.isNan(log10q(math.snan(f128)))); | |
| 457 | try expectEqual(log10_f128(0.0), -math.inf(f128)); | |
| 458 | try expectEqual(log10_f128(-0.0), -math.inf(f128)); | |
| 459 | try expect(math.isPositiveZero(log10_f128(1.0))); | |
| 460 | try expectEqual(log10_f128(10.0), 1.0); | |
| 461 | try expectEqual(log10_f128(0.1), -1.0); | |
| 462 | try expectEqual(log10_f128(math.inf(f128)), math.inf(f128)); | |
| 463 | try expect(math.isNan(log10_f128(-1.0))); | |
| 464 | try expect(math.isNan(log10_f128(-math.inf(f128)))); | |
| 465 | try expect(math.isNan(log10_f128(math.nan(f128)))); | |
| 466 | try expect(math.isNan(log10_f128(math.snan(f128)))); | |
| 452 | 467 | } |
| 453 | 468 | |
| 454 | 469 | test "log10q() sanity" { |
| 455 | try expectEqual(log10q(2.1744503117482705706605762784484114e1949), 1.949337349488073972035715318447419e3); | |
| 456 | try expectEqual(log10q(2.3695331993665660983204066767386505e2150), 2.1503746627979481420243846411400265e3); | |
| 457 | try expectEqual(log10q(1.8071775728314983136779370752110857e612), 6.122570008283284411311428111991705e2); | |
| 458 | try expectEqual(log10q(2.612170297226630737309271722008693e-2629), -2.628582998513179919647069989114319e3); | |
| 459 | try expectEqual(log10q(8.485091636263895897993044621224502e-3748), -3.7470713434630800881474518447042895e3); | |
| 460 | try expectEqual(log10q(4.3668077579803801413736022136116655e-4051), -4.0503598359268068567757367259544416e3); | |
| 461 | try expectEqual(log10q(2.9321353260885285826237030859036923e4830), 4.830467184010313310864606285356782e3); | |
| 462 | try expectEqual(log10q(6.6119754254652455408442826553161645e-1417), -1.416179668769227128601620567685071e3); | |
| 463 | try expectEqual(log10q(5.2459104673488555418645321788108695e4178), 4.178719820874155944446586083585479e3); | |
| 464 | try expectEqual(log10q(7.809812890804996586377267218360886e-418), -4.1710735937091966815220294599598215e2); | |
| 470 | try expectEqual(log10_f128(2.1744503117482705706605762784484114e1949), 1.949337349488073972035715318447419e3); | |
| 471 | try expectEqual(log10_f128(2.3695331993665660983204066767386505e2150), 2.1503746627979481420243846411400265e3); | |
| 472 | try expectEqual(log10_f128(1.8071775728314983136779370752110857e612), 6.122570008283284411311428111991705e2); | |
| 473 | try expectEqual(log10_f128(2.612170297226630737309271722008693e-2629), -2.628582998513179919647069989114319e3); | |
| 474 | try expectEqual(log10_f128(8.485091636263895897993044621224502e-3748), -3.7470713434630800881474518447042895e3); | |
| 475 | try expectEqual(log10_f128(4.3668077579803801413736022136116655e-4051), -4.0503598359268068567757367259544416e3); | |
| 476 | try expectEqual(log10_f128(2.9321353260885285826237030859036923e4830), 4.830467184010313310864606285356782e3); | |
| 477 | try expectEqual(log10_f128(6.6119754254652455408442826553161645e-1417), -1.416179668769227128601620567685071e3); | |
| 478 | try expectEqual(log10_f128(5.2459104673488555418645321788108695e4178), 4.178719820874155944446586083585479e3); | |
| 479 | try expectEqual(log10_f128(7.809812890804996586377267218360886e-418), -4.1710735937091966815220294599598215e2); | |
| 465 | 480 | // testing near 1 |
| 466 | try expectEqual(log10q(1.0291437165967803055610652052109798e0), 1.2476026819466393459130418401605807e-2); | |
| 467 | try expectEqual(log10q(1.043095786320424537962914257605007e0), 1.8324191034706598279642145362763252e-2); | |
| 468 | try expectEqual(log10q(9.900264873754467234601150948947179e-1), -4.3531860417287584780652055666513634e-3); | |
| 469 | try expectEqual(log10q(1.038295346547007736348611217636062e0), 1.6320907588397540309035279023485962e-2); | |
| 470 | try expectEqual(log10q(9.821701941230028324703038578036285e-1), -7.813249520562034832371814409278784e-3); | |
| 471 | try expectEqual(log10q(9.593555263530179895381522214847791e-1), -1.8020418356217558657107271163588764e-2); | |
| 481 | try expectEqual(log10_f128(1.0291437165967803055610652052109798e0), 1.2476026819466393459130418401605807e-2); | |
| 482 | try expectEqual(log10_f128(1.043095786320424537962914257605007e0), 1.8324191034706598279642145362763252e-2); | |
| 483 | try expectEqual(log10_f128(9.900264873754467234601150948947179e-1), -4.3531860417287584780652055666513634e-3); | |
| 484 | try expectEqual(log10_f128(1.038295346547007736348611217636062e0), 1.6320907588397540309035279023485962e-2); | |
| 485 | try expectEqual(log10_f128(9.821701941230028324703038578036285e-1), -7.813249520562034832371814409278784e-3); | |
| 486 | try expectEqual(log10_f128(9.593555263530179895381522214847791e-1), -1.8020418356217558657107271163588764e-2); | |
| 472 | 487 | } |
| 473 | 488 | |
| 474 | 489 | test "log10q() boundary" { |
| 475 | try expectEqual(log10q(0x1.ffffffffffffffffffffffffffffp16383), 0x1.34413509f79fef311f12b35816f9p12); // Max input value | |
| 476 | try expectEqual(log10q(0x1p-16494), -0x1.3653051d20c18a143b801b7c5661p12); // Min positive input value | |
| 477 | try expect(math.isNan(log10q(-0x1p-16494))); // Min negative input value | |
| 478 | try expectEqual(log10q(0x1.0000000000000000000000000001p0), 0x1.bcb7b1526e50e32a6ab7555f5a67p-114); // Last value before result reaches +0 | |
| 479 | try expectEqual(log10q(0x1.ffffffffffffffffffffffffffffp-1), -0x1.bcb7b1526e50e32a6ab7555f5a68p-115); // Last value before result reaches -0 | |
| 480 | try expectEqual(log10q(0x1p-16382), -0x1.343793004f503231a589bac27c38p12); // First subnormal | |
| 481 | try expect(math.isNan(log10q(-0x1p-16382))); // First negative subnormal | |
| 490 | try expectEqual(log10_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1.34413509f79fef311f12b35816f9p12); // Max input value | |
| 491 | try expectEqual(log10_f128(0x1p-16494), -0x1.3653051d20c18a143b801b7c5661p12); // Min positive input value | |
| 492 | try expect(math.isNan(log10_f128(-0x1p-16494))); // Min negative input value | |
| 493 | try expectEqual(log10_f128(0x1.0000000000000000000000000001p0), 0x1.bcb7b1526e50e32a6ab7555f5a67p-114); // Last value before result reaches +0 | |
| 494 | try expectEqual(log10_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1.bcb7b1526e50e32a6ab7555f5a68p-115); // Last value before result reaches -0 | |
| 495 | try expectEqual(log10_f128(0x1p-16382), -0x1.343793004f503231a589bac27c38p12); // First subnormal | |
| 496 | try expect(math.isNan(log10_f128(-0x1p-16382))); // First negative subnormal | |
| 482 | 497 | } |
lib/compiler_rt/log2.zig+105-90| ... | ... | @@ -26,12 +26,18 @@ comptime { |
| 26 | 26 | symbol(&log2l, "log2l"); |
| 27 | 27 | } |
| 28 | 28 | |
| 29 | pub fn __log2h(a: f16) callconv(.c) f16 { | |
| 29 | fn __log2h(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 30 | return compiler_rt.f16.toAbi(log2_f16(compiler_rt.f16.fromAbi(a))); | |
| 31 | } | |
| 32 | pub fn log2_f16(a: f16) f16 { | |
| 30 | 33 | // TODO: more efficient implementation |
| 31 | return @floatCast(log2f(a)); | |
| 34 | return @floatCast(log2_f32(a)); | |
| 32 | 35 | } |
| 33 | 36 | |
| 34 | pub fn log2f(x_: f32) callconv(.c) f32 { | |
| 37 | fn log2f(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 38 | return compiler_rt.f32.toAbi(log2_f32(compiler_rt.f32.fromAbi(a))); | |
| 39 | } | |
| 40 | pub fn log2_f32(x_: f32) f32 { | |
| 35 | 41 | const ivln2hi: f32 = 1.4428710938e+00; |
| 36 | 42 | const ivln2lo: f32 = -1.7605285393e-04; |
| 37 | 43 | const Lg1: f32 = 0xaaaaaa.0p-24; |
| ... | ... | @@ -87,7 +93,10 @@ pub fn log2f(x_: f32) callconv(.c) f32 { |
| 87 | 93 | return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + @as(f32, @floatFromInt(k)); |
| 88 | 94 | } |
| 89 | 95 | |
| 90 | pub fn log2(x_: f64) callconv(.c) f64 { | |
| 96 | fn log2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 97 | return compiler_rt.f64.toAbi(log2_f64(compiler_rt.f64.fromAbi(a))); | |
| 98 | } | |
| 99 | pub fn log2_f64(x_: f64) f64 { | |
| 91 | 100 | const ivln2hi: f64 = 1.44269504072144627571e+00; |
| 92 | 101 | const ivln2lo: f64 = 1.67517131648865118353e-10; |
| 93 | 102 | const Lg1: f64 = 6.666666666666735130e-01; |
| ... | ... | @@ -158,11 +167,17 @@ pub fn log2(x_: f64) callconv(.c) f64 { |
| 158 | 167 | return val_lo + val_hi; |
| 159 | 168 | } |
| 160 | 169 | |
| 161 | pub fn __log2x(a: f80) callconv(.c) f80 { | |
| 170 | fn __log2x(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 171 | return compiler_rt.f80.toAbi(log2_f80(compiler_rt.f80.fromAbi(a))); | |
| 172 | } | |
| 173 | pub fn log2_f80(a: f80) f80 { | |
| 162 | 174 | // TODO: more efficient implementation |
| 163 | return @floatCast(log2q(a)); | |
| 175 | return @floatCast(log2_f128(a)); | |
| 164 | 176 | } |
| 165 | 177 | |
| 178 | fn log2q(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 179 | return compiler_rt.f128.toAbi(log2_f128(compiler_rt.f128.fromAbi(a))); | |
| 180 | } | |
| 166 | 181 | /// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic" |
| 167 | 182 | /// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990 |
| 168 | 183 | /// |
| ... | ... | @@ -175,7 +190,7 @@ pub fn __log2x(a: f80) callconv(.c) f80 { |
| 175 | 190 | /// |
| 176 | 191 | /// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case): |
| 177 | 192 | /// <= 0.5 ulp: 99.86%, worst case <= 0.546 ulp |
| 178 | pub fn log2q(x: f128) callconv(.c) f128 { | |
| 193 | pub fn log2_f128(x: f128) f128 { | |
| 179 | 194 | const impl = @import("log_f128.zig"); |
| 180 | 195 | |
| 181 | 196 | if (impl.specialCases(x)) |y| |
| ... | ... | @@ -351,117 +366,117 @@ pub fn log2q(x: f128) callconv(.c) f128 { |
| 351 | 366 | |
| 352 | 367 | pub fn log2l(x: c_longdouble) callconv(.c) c_longdouble { |
| 353 | 368 | switch (@typeInfo(c_longdouble).float.bits) { |
| 354 | 64 => return log2(x), | |
| 355 | 80 => return __log2x(x), | |
| 356 | 128 => return log2q(x), | |
| 357 | else => @compileError("unreachable"), | |
| 369 | 64 => return log2_f64(x), | |
| 370 | 80 => return log2_f80(x), | |
| 371 | 128 => return log2_f128(x), | |
| 372 | else => comptime unreachable, | |
| 358 | 373 | } |
| 359 | 374 | } |
| 360 | 375 | |
| 361 | 376 | test "log2f() special" { |
| 362 | try expectEqual(log2f(0.0), -math.inf(f32)); | |
| 363 | try expectEqual(log2f(-0.0), -math.inf(f32)); | |
| 364 | try expect(math.isPositiveZero(log2f(1.0))); | |
| 365 | try expectEqual(log2f(2.0), 1.0); | |
| 366 | try expectEqual(log2f(math.inf(f32)), math.inf(f32)); | |
| 367 | try expect(math.isNan(log2f(-1.0))); | |
| 368 | try expect(math.isNan(log2f(-math.inf(f32)))); | |
| 369 | try expect(math.isNan(log2f(math.nan(f32)))); | |
| 370 | try expect(math.isNan(log2f(math.snan(f32)))); | |
| 377 | try expectEqual(log2_f32(0.0), -math.inf(f32)); | |
| 378 | try expectEqual(log2_f32(-0.0), -math.inf(f32)); | |
| 379 | try expect(math.isPositiveZero(log2_f32(1.0))); | |
| 380 | try expectEqual(log2_f32(2.0), 1.0); | |
| 381 | try expectEqual(log2_f32(math.inf(f32)), math.inf(f32)); | |
| 382 | try expect(math.isNan(log2_f32(-1.0))); | |
| 383 | try expect(math.isNan(log2_f32(-math.inf(f32)))); | |
| 384 | try expect(math.isNan(log2_f32(math.nan(f32)))); | |
| 385 | try expect(math.isNan(log2_f32(math.snan(f32)))); | |
| 371 | 386 | } |
| 372 | 387 | |
| 373 | 388 | test "log2f() sanity" { |
| 374 | try expect(math.isNan(log2f(-0x1.0223a0p+3))); | |
| 375 | try expectEqual(log2f(0x1.161868p+2), 0x1.0f49acp+1); | |
| 376 | try expect(math.isNan(log2f(-0x1.0c34b4p+3))); | |
| 377 | try expect(math.isNan(log2f(-0x1.a206f0p+2))); | |
| 378 | try expectEqual(log2f(0x1.288bbcp+3), 0x1.9b2676p+1); | |
| 379 | try expectEqual(log2f(0x1.52efd0p-1), -0x1.30b494p-1); // Disagrees with GCC in last bit | |
| 380 | try expect(math.isNan(log2f(-0x1.a05cc8p-2))); | |
| 381 | try expectEqual(log2f(0x1.1f9efap-1), -0x1.a9f89ap-1); | |
| 382 | try expectEqual(log2f(0x1.8c5db0p-1), -0x1.7a2c96p-2); | |
| 383 | try expect(math.isNan(log2f(-0x1.5b86eap-1))); | |
| 389 | try expect(math.isNan(log2_f32(-0x1.0223a0p+3))); | |
| 390 | try expectEqual(log2_f32(0x1.161868p+2), 0x1.0f49acp+1); | |
| 391 | try expect(math.isNan(log2_f32(-0x1.0c34b4p+3))); | |
| 392 | try expect(math.isNan(log2_f32(-0x1.a206f0p+2))); | |
| 393 | try expectEqual(log2_f32(0x1.288bbcp+3), 0x1.9b2676p+1); | |
| 394 | try expectEqual(log2_f32(0x1.52efd0p-1), -0x1.30b494p-1); // Disagrees with GCC in last bit | |
| 395 | try expect(math.isNan(log2_f32(-0x1.a05cc8p-2))); | |
| 396 | try expectEqual(log2_f32(0x1.1f9efap-1), -0x1.a9f89ap-1); | |
| 397 | try expectEqual(log2_f32(0x1.8c5db0p-1), -0x1.7a2c96p-2); | |
| 398 | try expect(math.isNan(log2_f32(-0x1.5b86eap-1))); | |
| 384 | 399 | } |
| 385 | 400 | |
| 386 | 401 | test "log2f() boundary" { |
| 387 | try expectEqual(log2f(0x1.fffffep+127), 0x1p+7); // Max input value | |
| 388 | try expectEqual(log2f(0x1p-149), -0x1.2ap+7); // Min positive input value | |
| 389 | try expect(math.isNan(log2f(-0x1p-149))); // Min negative input value | |
| 390 | try expectEqual(log2f(0x1.000002p+0), 0x1.715474p-23); // Last value before result reaches +0 | |
| 391 | try expectEqual(log2f(0x1.fffffep-1), -0x1.715478p-24); // Last value before result reaches -0 | |
| 392 | try expectEqual(log2f(0x1p-126), -0x1.f8p+6); // First subnormal | |
| 393 | try expect(math.isNan(log2f(-0x1p-126))); // First negative subnormal | |
| 402 | try expectEqual(log2_f32(0x1.fffffep+127), 0x1p+7); // Max input value | |
| 403 | try expectEqual(log2_f32(0x1p-149), -0x1.2ap+7); // Min positive input value | |
| 404 | try expect(math.isNan(log2_f32(-0x1p-149))); // Min negative input value | |
| 405 | try expectEqual(log2_f32(0x1.000002p+0), 0x1.715474p-23); // Last value before result reaches +0 | |
| 406 | try expectEqual(log2_f32(0x1.fffffep-1), -0x1.715478p-24); // Last value before result reaches -0 | |
| 407 | try expectEqual(log2_f32(0x1p-126), -0x1.f8p+6); // First subnormal | |
| 408 | try expect(math.isNan(log2_f32(-0x1p-126))); // First negative subnormal | |
| 394 | 409 | |
| 395 | 410 | } |
| 396 | 411 | |
| 397 | 412 | test "log2() special" { |
| 398 | try expectEqual(log2(0.0), -math.inf(f64)); | |
| 399 | try expectEqual(log2(-0.0), -math.inf(f64)); | |
| 400 | try expect(math.isPositiveZero(log2(1.0))); | |
| 401 | try expectEqual(log2(2.0), 1.0); | |
| 402 | try expectEqual(log2(math.inf(f64)), math.inf(f64)); | |
| 403 | try expect(math.isNan(log2(-1.0))); | |
| 404 | try expect(math.isNan(log2(-math.inf(f64)))); | |
| 405 | try expect(math.isNan(log2(math.nan(f64)))); | |
| 406 | try expect(math.isNan(log2(math.snan(f64)))); | |
| 413 | try expectEqual(log2_f64(0.0), -math.inf(f64)); | |
| 414 | try expectEqual(log2_f64(-0.0), -math.inf(f64)); | |
| 415 | try expect(math.isPositiveZero(log2_f64(1.0))); | |
| 416 | try expectEqual(log2_f64(2.0), 1.0); | |
| 417 | try expectEqual(log2_f64(math.inf(f64)), math.inf(f64)); | |
| 418 | try expect(math.isNan(log2_f64(-1.0))); | |
| 419 | try expect(math.isNan(log2_f64(-math.inf(f64)))); | |
| 420 | try expect(math.isNan(log2_f64(math.nan(f64)))); | |
| 421 | try expect(math.isNan(log2_f64(math.snan(f64)))); | |
| 407 | 422 | } |
| 408 | 423 | |
| 409 | 424 | test "log2() sanity" { |
| 410 | try expect(math.isNan(log2(-0x1.02239f3c6a8f1p+3))); | |
| 411 | try expectEqual(log2(0x1.161868e18bc67p+2), 0x1.0f49ac3838580p+1); | |
| 412 | try expect(math.isNan(log2(-0x1.0c34b3e01e6e7p+3))); | |
| 413 | try expect(math.isNan(log2(-0x1.a206f0a19dcc4p+2))); | |
| 414 | try expectEqual(log2(0x1.288bbb0d6a1e6p+3), 0x1.9b26760c2a57ep+1); | |
| 415 | try expectEqual(log2(0x1.52efd0cd80497p-1), -0x1.30b490ef684c7p-1); | |
| 416 | try expect(math.isNan(log2(-0x1.a05cc754481d1p-2))); | |
| 417 | try expectEqual(log2(0x1.1f9ef934745cbp-1), -0x1.a9f89b5f5acb8p-1); | |
| 418 | try expectEqual(log2(0x1.8c5db097f7442p-1), -0x1.7a2c947173f06p-2); | |
| 419 | try expect(math.isNan(log2(-0x1.5b86ea8118a0ep-1))); | |
| 425 | try expect(math.isNan(log2_f64(-0x1.02239f3c6a8f1p+3))); | |
| 426 | try expectEqual(log2_f64(0x1.161868e18bc67p+2), 0x1.0f49ac3838580p+1); | |
| 427 | try expect(math.isNan(log2_f64(-0x1.0c34b3e01e6e7p+3))); | |
| 428 | try expect(math.isNan(log2_f64(-0x1.a206f0a19dcc4p+2))); | |
| 429 | try expectEqual(log2_f64(0x1.288bbb0d6a1e6p+3), 0x1.9b26760c2a57ep+1); | |
| 430 | try expectEqual(log2_f64(0x1.52efd0cd80497p-1), -0x1.30b490ef684c7p-1); | |
| 431 | try expect(math.isNan(log2_f64(-0x1.a05cc754481d1p-2))); | |
| 432 | try expectEqual(log2_f64(0x1.1f9ef934745cbp-1), -0x1.a9f89b5f5acb8p-1); | |
| 433 | try expectEqual(log2_f64(0x1.8c5db097f7442p-1), -0x1.7a2c947173f06p-2); | |
| 434 | try expect(math.isNan(log2_f64(-0x1.5b86ea8118a0ep-1))); | |
| 420 | 435 | } |
| 421 | 436 | |
| 422 | 437 | test "log2() boundary" { |
| 423 | try expectEqual(log2(0x1.fffffffffffffp+1023), 0x1p+10); // Max input value | |
| 424 | try expectEqual(log2(0x1p-1074), -0x1.0c8p+10); // Min positive input value | |
| 425 | try expect(math.isNan(log2(-0x1p-1074))); // Min negative input value | |
| 426 | try expectEqual(log2(0x1.0000000000001p+0), 0x1.71547652b82fdp-52); // Last value before result reaches +0 | |
| 427 | try expectEqual(log2(0x1.fffffffffffffp-1), -0x1.71547652b82fep-53); // Last value before result reaches -0 | |
| 428 | try expectEqual(log2(0x1p-1022), -0x1.ffp+9); // First subnormal | |
| 429 | try expect(math.isNan(log2(-0x1p-1022))); // First negative subnormal | |
| 438 | try expectEqual(log2_f64(0x1.fffffffffffffp+1023), 0x1p+10); // Max input value | |
| 439 | try expectEqual(log2_f64(0x1p-1074), -0x1.0c8p+10); // Min positive input value | |
| 440 | try expect(math.isNan(log2_f64(-0x1p-1074))); // Min negative input value | |
| 441 | try expectEqual(log2_f64(0x1.0000000000001p+0), 0x1.71547652b82fdp-52); // Last value before result reaches +0 | |
| 442 | try expectEqual(log2_f64(0x1.fffffffffffffp-1), -0x1.71547652b82fep-53); // Last value before result reaches -0 | |
| 443 | try expectEqual(log2_f64(0x1p-1022), -0x1.ffp+9); // First subnormal | |
| 444 | try expect(math.isNan(log2_f64(-0x1p-1022))); // First negative subnormal | |
| 430 | 445 | } |
| 431 | 446 | |
| 432 | 447 | test "log2q() special" { |
| 433 | try expectEqual(log2q(0.0), -math.inf(f128)); | |
| 434 | try expectEqual(log2q(-0.0), -math.inf(f128)); | |
| 435 | try expect(math.isPositiveZero(log2q(1.0))); | |
| 436 | try expectEqual(log2q(2.0), 1.0); | |
| 437 | try expectEqual(log2q(math.inf(f128)), math.inf(f128)); | |
| 438 | try expect(math.isNan(log2q(-1.0))); | |
| 439 | try expect(math.isNan(log2q(-math.inf(f128)))); | |
| 440 | try expect(math.isNan(log2q(math.nan(f128)))); | |
| 441 | try expect(math.isNan(log2q(math.snan(f128)))); | |
| 448 | try expectEqual(log2_f128(0.0), -math.inf(f128)); | |
| 449 | try expectEqual(log2_f128(-0.0), -math.inf(f128)); | |
| 450 | try expect(math.isPositiveZero(log2_f128(1.0))); | |
| 451 | try expectEqual(log2_f128(2.0), 1.0); | |
| 452 | try expectEqual(log2_f128(math.inf(f128)), math.inf(f128)); | |
| 453 | try expect(math.isNan(log2_f128(-1.0))); | |
| 454 | try expect(math.isNan(log2_f128(-math.inf(f128)))); | |
| 455 | try expect(math.isNan(log2_f128(math.nan(f128)))); | |
| 456 | try expect(math.isNan(log2_f128(math.snan(f128)))); | |
| 442 | 457 | } |
| 443 | 458 | |
| 444 | 459 | test "log2q() boundary" { |
| 445 | try expectEqual(log2q(0x1.ffffffffffffffffffffffffffffp16383), 0x1p14); // Max input value | |
| 446 | try expectEqual(log2q(0x1p-16494), -0x1.01b8p14); // Min positive input value | |
| 447 | try expect(math.isNan(log2q(-0x1p-16494))); // Min negative input value | |
| 448 | try expectEqual(log2q(0x1.0000000000000000000000000001p0), 0x1.71547652b82fe1777d0ffda0d23ap-112); // Last value before result reaches +0 | |
| 449 | try expectEqual(log2q(0x1.ffffffffffffffffffffffffffffp-1), -0x1.71547652b82fe1777d0ffda0d23bp-113); // Last value before result reaches -0 | |
| 450 | try expectEqual(log2q(0x1p-16382), -0x1.fffp13); // First subnormal | |
| 451 | try expect(math.isNan(log2q(-0x1p-16382))); // First negative subnormal | |
| 460 | try expectEqual(log2_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1p14); // Max input value | |
| 461 | try expectEqual(log2_f128(0x1p-16494), -0x1.01b8p14); // Min positive input value | |
| 462 | try expect(math.isNan(log2_f128(-0x1p-16494))); // Min negative input value | |
| 463 | try expectEqual(log2_f128(0x1.0000000000000000000000000001p0), 0x1.71547652b82fe1777d0ffda0d23ap-112); // Last value before result reaches +0 | |
| 464 | try expectEqual(log2_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1.71547652b82fe1777d0ffda0d23bp-113); // Last value before result reaches -0 | |
| 465 | try expectEqual(log2_f128(0x1p-16382), -0x1.fffp13); // First subnormal | |
| 466 | try expect(math.isNan(log2_f128(-0x1p-16382))); // First negative subnormal | |
| 452 | 467 | } |
| 453 | 468 | |
| 454 | 469 | test "log2q() sanity" { |
| 455 | try expectEqual(log2q(8.0965013884643408203125e11), 3.955850767769801288865582596068254e1); | |
| 456 | try expectEqual(log2q(8.346531942223744e15), 5.28900982928636641107356163006646e1); | |
| 457 | try expectEqual(log2q(9.707809913413123613777865431464565e-20), -6.315941603809020445822192336703809e1); | |
| 458 | try expectEqual(log2q(1.9179565888043380306021427656243352e-24), -7.878670421065570557450089031998522e1); | |
| 459 | try expectEqual(log2q(2.5260048200126556877075044745936796e-25), -8.17113449801679676275805009400338e1); | |
| 460 | try expectEqual(log2q(3.1170134002568967640399932861328125e7), 2.489366102143423848582774267206741e1); | |
| 470 | try expectEqual(log2_f128(8.0965013884643408203125e11), 3.955850767769801288865582596068254e1); | |
| 471 | try expectEqual(log2_f128(8.346531942223744e15), 5.28900982928636641107356163006646e1); | |
| 472 | try expectEqual(log2_f128(9.707809913413123613777865431464565e-20), -6.315941603809020445822192336703809e1); | |
| 473 | try expectEqual(log2_f128(1.9179565888043380306021427656243352e-24), -7.878670421065570557450089031998522e1); | |
| 474 | try expectEqual(log2_f128(2.5260048200126556877075044745936796e-25), -8.17113449801679676275805009400338e1); | |
| 475 | try expectEqual(log2_f128(3.1170134002568967640399932861328125e7), 2.489366102143423848582774267206741e1); | |
| 461 | 476 | // test near 1 |
| 462 | try expectEqual(log2q(1.026586845186097528392910049888087e0), 3.7855678902522753591699367969189364e-2); | |
| 463 | try expectEqual(log2q(1.0005582850578053877743656130405725e0), 8.052103367568488432896147152682078e-4); | |
| 464 | try expectEqual(log2q(1.0370174103591254835765589348284266e0), 5.244011558596899945639244281954306e-2); | |
| 465 | try expectEqual(log2q(1.0429996503525671713075162472250667e0), 6.073867421942172944687194557176633e-2); | |
| 466 | try expectEqual(log2q(1.0383384027961064621892184334228659e0), 5.4276706191956281784022630732940314e-2); | |
| 477 | try expectEqual(log2_f128(1.026586845186097528392910049888087e0), 3.7855678902522753591699367969189364e-2); | |
| 478 | try expectEqual(log2_f128(1.0005582850578053877743656130405725e0), 8.052103367568488432896147152682078e-4); | |
| 479 | try expectEqual(log2_f128(1.0370174103591254835765589348284266e0), 5.244011558596899945639244281954306e-2); | |
| 480 | try expectEqual(log2_f128(1.0429996503525671713075162472250667e0), 6.073867421942172944687194557176633e-2); | |
| 481 | try expectEqual(log2_f128(1.0383384027961064621892184334228659e0), 5.4276706191956281784022630732940314e-2); | |
| 467 | 482 | } |
lib/compiler_rt/mulc3.zig+75-10| ... | ... | @@ -3,19 +3,80 @@ const isNan = std.math.isNan; |
| 3 | 3 | const isInf = std.math.isInf; |
| 4 | 4 | const copysign = std.math.copysign; |
| 5 | 5 | |
| 6 | pub fn Complex(comptime T: type) type { | |
| 7 | return extern struct { | |
| 8 | real: T, | |
| 9 | imag: T, | |
| 10 | }; | |
| 6 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 7 | const symbol = compiler_rt.symbol; | |
| 8 | const Complex = compiler_rt.Complex; | |
| 9 | ||
| 10 | comptime { | |
| 11 | if (@import("builtin").zig_backend != .stage2_c) { | |
| 12 | symbol(&__mulhc3, "__mulhc3"); | |
| 13 | symbol(&__mulsc3, "__mulsc3"); | |
| 14 | symbol(&__muldc3, "__muldc3"); | |
| 15 | symbol(&__mulxc3, "__mulxc3"); | |
| 16 | if (compiler_rt.want_ppc_abi) { | |
| 17 | symbol(&__multc3, "__mulkc3"); | |
| 18 | } else { | |
| 19 | symbol(&__multc3, "__multc3"); | |
| 20 | } | |
| 21 | } | |
| 22 | } | |
| 23 | ||
| 24 | fn __mulhc3(lhs_real: compiler_rt.f16.Abi, lhs_imag: compiler_rt.f16.Abi, rhs_real: compiler_rt.f16.Abi, rhs_imag: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.complex.Abi { | |
| 25 | return compiler_rt.f16.complex.toAbi(mul_cf16( | |
| 26 | compiler_rt.f16.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | |
| 27 | compiler_rt.f16.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | |
| 28 | )); | |
| 29 | } | |
| 30 | pub fn mul_cf16(a: Complex(f16), b: Complex(f16)) Complex(f16) { | |
| 31 | return mulc3(f16, a, b); | |
| 32 | } | |
| 33 | ||
| 34 | fn __mulsc3(lhs_real: compiler_rt.f32.Abi, lhs_imag: compiler_rt.f32.Abi, rhs_real: compiler_rt.f32.Abi, rhs_imag: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.complex.Abi { | |
| 35 | return compiler_rt.f32.complex.toAbi(mul_cf32( | |
| 36 | compiler_rt.f32.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | |
| 37 | compiler_rt.f32.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | |
| 38 | )); | |
| 39 | } | |
| 40 | pub fn mul_cf32(a: Complex(f32), b: Complex(f32)) Complex(f32) { | |
| 41 | return mulc3(f32, a, b); | |
| 42 | } | |
| 43 | ||
| 44 | fn __muldc3(lhs_real: compiler_rt.f64.Abi, lhs_imag: compiler_rt.f64.Abi, rhs_real: compiler_rt.f64.Abi, rhs_imag: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.complex.Abi { | |
| 45 | return compiler_rt.f64.complex.toAbi(mul_cf64( | |
| 46 | compiler_rt.f64.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | |
| 47 | compiler_rt.f64.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | |
| 48 | )); | |
| 49 | } | |
| 50 | pub fn mul_cf64(a: Complex(f64), b: Complex(f64)) Complex(f64) { | |
| 51 | return mulc3(f64, a, b); | |
| 52 | } | |
| 53 | ||
| 54 | fn __mulxc3(lhs_real: compiler_rt.f80.Abi, lhs_imag: compiler_rt.f80.Abi, rhs_real: compiler_rt.f80.Abi, rhs_imag: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.complex.Abi { | |
| 55 | return compiler_rt.f80.complex.toAbi(mul_cf80( | |
| 56 | compiler_rt.f80.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | |
| 57 | compiler_rt.f80.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | |
| 58 | )); | |
| 59 | } | |
| 60 | pub fn mul_cf80(a: Complex(f80), b: Complex(f80)) Complex(f80) { | |
| 61 | return mulc3(f80, a, b); | |
| 62 | } | |
| 63 | ||
| 64 | fn __multc3(lhs_real: compiler_rt.f128.Abi, lhs_imag: compiler_rt.f128.Abi, rhs_real: compiler_rt.f128.Abi, rhs_imag: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.complex.Abi { | |
| 65 | return compiler_rt.f128.complex.toAbi(mul_cf128( | |
| 66 | compiler_rt.f128.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), | |
| 67 | compiler_rt.f128.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), | |
| 68 | )); | |
| 69 | } | |
| 70 | pub fn mul_cf128(a: Complex(f128), b: Complex(f128)) Complex(f128) { | |
| 71 | return mulc3(f128, a, b); | |
| 11 | 72 | } |
| 12 | 73 | |
| 13 | 74 | /// Implementation based on Annex G of C17 Standard (N2176) |
| 14 | pub inline fn mulc3(comptime T: type, a_in: T, b_in: T, c_in: T, d_in: T) Complex(T) { | |
| 15 | var a = a_in; | |
| 16 | var b = b_in; | |
| 17 | var c = c_in; | |
| 18 | var d = d_in; | |
| 75 | inline fn mulc3(comptime T: type, lhs: Complex(T), rhs: Complex(T)) Complex(T) { | |
| 76 | var a = lhs.real; | |
| 77 | var b = lhs.imag; | |
| 78 | var c = rhs.real; | |
| 79 | var d = rhs.imag; | |
| 19 | 80 | |
| 20 | 81 | const ac = a * c; |
| 21 | 82 | const bd = b * d; |
| ... | ... | @@ -77,3 +138,7 @@ pub inline fn mulc3(comptime T: type, a_in: T, b_in: T, c_in: T, d_in: T) Comple |
| 77 | 138 | } |
| 78 | 139 | return z; |
| 79 | 140 | } |
| 141 | ||
| 142 | test { | |
| 143 | _ = @import("mulc3_test.zig"); | |
| 144 | } |
lib/compiler_rt/mulc3_test.zig+23-42| ... | ... | @@ -2,64 +2,45 @@ const std = @import("std"); |
| 2 | 2 | const math = std.math; |
| 3 | 3 | const expect = std.testing.expect; |
| 4 | 4 | |
| 5 | const Complex = @import("./mulc3.zig").Complex; | |
| 6 | const __mulhc3 = @import("./mulhc3.zig").__mulhc3; | |
| 7 | const __mulsc3 = @import("./mulsc3.zig").__mulsc3; | |
| 8 | const __muldc3 = @import("./muldc3.zig").__muldc3; | |
| 9 | const __mulxc3 = @import("./mulxc3.zig").__mulxc3; | |
| 10 | const __multc3 = @import("./multc3.zig").__multc3; | |
| 5 | const Complex = @import("../compiler_rt.zig").Complex; | |
| 6 | const impl = @import("mulc3.zig"); | |
| 7 | const mul_cf16 = impl.mul_cf16; | |
| 8 | const mul_cf32 = impl.mul_cf32; | |
| 9 | const mul_cf64 = impl.mul_cf64; | |
| 10 | const mul_cf80 = impl.mul_cf80; | |
| 11 | const mul_cf128 = impl.mul_cf128; | |
| 11 | 12 | |
| 12 | 13 | test "mulc3" { |
| 13 | try testMul(f16, __mulhc3); | |
| 14 | try testMul(f32, __mulsc3); | |
| 15 | try testMul(f64, __muldc3); | |
| 16 | try testMul(f80, __mulxc3); | |
| 17 | try testMul(f128, __multc3); | |
| 14 | try testMul(f16, mul_cf16); | |
| 15 | try testMul(f32, mul_cf32); | |
| 16 | try testMul(f64, mul_cf64); | |
| 17 | try testMul(f80, mul_cf80); | |
| 18 | try testMul(f128, mul_cf128); | |
| 18 | 19 | } |
| 19 | 20 | |
| 20 | fn testMul(comptime T: type, comptime f: fn (T, T, T, T) callconv(.c) Complex(T)) !void { | |
| 21 | fn testMul(comptime T: type, comptime f: fn (Complex(T), Complex(T)) Complex(T)) !void { | |
| 21 | 22 | { |
| 22 | const a: T = 1.0; | |
| 23 | const b: T = 0.0; | |
| 24 | const c: T = -1.0; | |
| 25 | const d: T = 0.0; | |
| 26 | ||
| 27 | const result = f(a, b, c, d); | |
| 23 | const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -1.0, .imag = 0.0 }); | |
| 28 | 24 | try expect(result.real == -1.0); |
| 29 | try expect(result.imag == 0.0); | |
| 25 | try expect(math.isPositiveZero(result.imag)); | |
| 30 | 26 | } |
| 31 | 27 | { |
| 32 | const a: T = 1.0; | |
| 33 | const b: T = 0.0; | |
| 34 | const c: T = -4.0; | |
| 35 | const d: T = 0.0; | |
| 36 | ||
| 37 | const result = f(a, b, c, d); | |
| 28 | const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -4.0, .imag = 0.0 }); | |
| 38 | 29 | try expect(result.real == -4.0); |
| 39 | try expect(result.imag == 0.0); | |
| 30 | try expect(math.isPositiveZero(result.imag)); | |
| 40 | 31 | } |
| 41 | 32 | { |
| 42 | 33 | // if one operand is an infinity and the other operand is a nonzero finite number or an infinity, |
| 43 | 34 | // then the result of the * operator is an infinity; |
| 44 | const a: T = math.inf(T); | |
| 45 | const b: T = -math.inf(T); | |
| 46 | const c: T = 1.0; | |
| 47 | const d: T = 0.0; | |
| 48 | ||
| 49 | const result = f(a, b, c, d); | |
| 50 | try expect(result.real == math.inf(T)); | |
| 51 | try expect(result.imag == -math.inf(T)); | |
| 35 | const result = f(.{ .real = math.inf(T), .imag = -math.inf(T) }, .{ .real = 1.0, .imag = 0.0 }); | |
| 36 | try expect(math.isPositiveInf(result.real)); | |
| 37 | try expect(math.isNegativeInf(result.imag)); | |
| 52 | 38 | } |
| 53 | 39 | { |
| 54 | 40 | // if one operand is an infinity and the other operand is a nonzero finite number or an infinity, |
| 55 | 41 | // then the result of the * operator is an infinity; |
| 56 | const a: T = math.inf(T); | |
| 57 | const b: T = -1.0; | |
| 58 | const c: T = 1.0; | |
| 59 | const d: T = math.inf(T); | |
| 60 | ||
| 61 | const result = f(a, b, c, d); | |
| 62 | try expect(result.real == math.inf(T)); | |
| 63 | try expect(result.imag == math.inf(T)); | |
| 42 | const result = f(.{ .real = math.inf(T), .imag = -1.0 }, .{ .real = 1.0, .imag = math.inf(T) }); | |
| 43 | try expect(math.isPositiveInf(result.real)); | |
| 44 | try expect(math.isPositiveInf(result.imag)); | |
| 64 | 45 | } |
| 65 | 46 | } |
lib/compiler_rt/muldc3.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const mulc3 = @import("./mulc3.zig"); | |
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | ||
| 4 | comptime { | |
| 5 | if (@import("builtin").zig_backend != .stage2_c) { | |
| 6 | symbol(&__muldc3, "__muldc3"); | |
| 7 | } | |
| 8 | } | |
| 9 | ||
| 10 | pub fn __muldc3(a: f64, b: f64, c: f64, d: f64) callconv(.c) mulc3.Complex(f64) { | |
| 11 | return mulc3.mulc3(f64, a, b, c, d); | |
| 12 | } |
lib/compiler_rt/muldf3.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | const mulf3 = @import("./mulf3.zig").mulf3; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_dmul, "__aeabi_dmul"); | |
| 8 | } else { | |
| 9 | symbol(&__muldf3, "__muldf3"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | pub fn __muldf3(a: f64, b: f64) callconv(.c) f64 { | |
| 14 | return mulf3(f64, a, b); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_dmul(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 18 | return mulf3(f64, a, b); | |
| 19 | } |
lib/compiler_rt/mulf3.zig+67-1| ... | ... | @@ -2,10 +2,76 @@ const std = @import("std"); |
| 2 | 2 | const math = std.math; |
| 3 | 3 | const builtin = @import("builtin"); |
| 4 | 4 | const compiler_rt = @import("../compiler_rt.zig"); |
| 5 | const symbol = compiler_rt.symbol; | |
| 6 | ||
| 7 | comptime { | |
| 8 | symbol(&__mulhf3, "__mulhf3"); | |
| 9 | if (compiler_rt.want_aeabi) { | |
| 10 | symbol(&__aeabi_fmul, "__aeabi_fmul"); | |
| 11 | symbol(&__aeabi_dmul, "__aeabi_dmul"); | |
| 12 | } else { | |
| 13 | symbol(&__mulsf3, "__mulsf3"); | |
| 14 | symbol(&__muldf3, "__muldf3"); | |
| 15 | } | |
| 16 | symbol(&__mulxf3, "__mulxf3"); | |
| 17 | if (compiler_rt.want_ppc_abi) { | |
| 18 | symbol(&__multf3, "__mulkf3"); | |
| 19 | } else if (compiler_rt.want_sparc64_abi) { | |
| 20 | symbol(&_Qp_mul, "_Qp_mul"); | |
| 21 | } else if (compiler_rt.want_sparc32_abi) { | |
| 22 | symbol(&__multf3, "_Q_mul"); | |
| 23 | } else { | |
| 24 | symbol(&__multf3, "__multf3"); | |
| 25 | } | |
| 26 | } | |
| 27 | ||
| 28 | fn __mulhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 29 | return compiler_rt.f16.toAbi(mul_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); | |
| 30 | } | |
| 31 | pub fn mul_f16(a: f16, b: f16) f16 { | |
| 32 | return mulf3(f16, a, b); | |
| 33 | } | |
| 34 | ||
| 35 | fn __mulsf3(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 36 | return compiler_rt.f32.toAbi(mul_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); | |
| 37 | } | |
| 38 | fn __aeabi_fmul(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 39 | return mul_f32(a, b); | |
| 40 | } | |
| 41 | pub fn mul_f32(a: f32, b: f32) f32 { | |
| 42 | return mulf3(f32, a, b); | |
| 43 | } | |
| 44 | ||
| 45 | fn __muldf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 46 | return compiler_rt.f64.toAbi(mul_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); | |
| 47 | } | |
| 48 | fn __aeabi_dmul(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 49 | return mul_f64(a, b); | |
| 50 | } | |
| 51 | pub fn mul_f64(a: f64, b: f64) f64 { | |
| 52 | return mulf3(f64, a, b); | |
| 53 | } | |
| 54 | ||
| 55 | fn __mulxf3(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 56 | return compiler_rt.f80.toAbi(mul_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); | |
| 57 | } | |
| 58 | pub fn mul_f80(a: f80, b: f80) f80 { | |
| 59 | return mulf3(f80, a, b); | |
| 60 | } | |
| 61 | ||
| 62 | fn __multf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 63 | return compiler_rt.f128.toAbi(mul_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); | |
| 64 | } | |
| 65 | fn _Qp_mul(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { | |
| 66 | c.* = mul_f128(a.*, b.*); | |
| 67 | } | |
| 68 | pub fn mul_f128(a: f128, b: f128) f128 { | |
| 69 | return mulf3(f128, a, b); | |
| 70 | } | |
| 5 | 71 | |
| 6 | 72 | /// Ported from: |
| 7 | 73 | /// https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/lib/builtins/fp_mul_impl.inc |
| 8 | pub inline fn mulf3(comptime T: type, a: T, b: T) T { | |
| 74 | inline fn mulf3(comptime T: type, a: T, b: T) T { | |
| 9 | 75 | @setRuntimeSafety(compiler_rt.test_safety); |
| 10 | 76 | const typeWidth = @typeInfo(T).float.bits; |
| 11 | 77 | const significandBits = math.floatMantissaBits(T); |
lib/compiler_rt/mulf3_test.zig+48-46| ... | ... | @@ -7,10 +7,12 @@ const math = std.math; |
| 7 | 7 | const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64); |
| 8 | 8 | const inf128: f128 = @bitCast(@as(u128, 0x7fff000000000000) << 64); |
| 9 | 9 | |
| 10 | const __multf3 = @import("multf3.zig").__multf3; | |
| 11 | const __mulxf3 = @import("mulxf3.zig").__mulxf3; | |
| 12 | const __muldf3 = @import("muldf3.zig").__muldf3; | |
| 13 | const __mulsf3 = @import("mulsf3.zig").__mulsf3; | |
| 10 | const impl = @import("mulf3.zig"); | |
| 11 | const mul_f16 = impl.mul_f16; | |
| 12 | const mul_f32 = impl.mul_f32; | |
| 13 | const mul_f64 = impl.mul_f64; | |
| 14 | const mul_f80 = impl.mul_f80; | |
| 15 | const mul_f128 = impl.mul_f128; | |
| 14 | 16 | |
| 15 | 17 | // return true if equal |
| 16 | 18 | // use two 64-bit integers instead of one 128-bit integer |
| ... | ... | @@ -34,8 +36,8 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool { |
| 34 | 36 | return false; |
| 35 | 37 | } |
| 36 | 38 | |
| 37 | fn test__multf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { | |
| 38 | const x = __multf3(a, b); | |
| 39 | fn test_mul_f128(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { | |
| 40 | const x = mul_f128(a, b); | |
| 39 | 41 | |
| 40 | 42 | if (compareResultLD(x, expected_hi, expected_lo)) |
| 41 | 43 | return; |
| ... | ... | @@ -49,68 +51,68 @@ fn makeNaN128(rand: u64) f128 { |
| 49 | 51 | } |
| 50 | 52 | test "multf3" { |
| 51 | 53 | // qNaN * any = qNaN |
| 52 | try test__multf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); | |
| 54 | try test_mul_f128(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); | |
| 53 | 55 | |
| 54 | 56 | // NaN * any = NaN |
| 55 | 57 | const a = makeNaN128(0x800030000000); |
| 56 | try test__multf3(a, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); | |
| 58 | try test_mul_f128(a, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); | |
| 57 | 59 | // inf * any = inf |
| 58 | try test__multf3(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0); | |
| 60 | try test_mul_f128(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0); | |
| 59 | 61 | |
| 60 | 62 | // any * any |
| 61 | try test__multf3( | |
| 63 | try test_mul_f128( | |
| 62 | 64 | @as(f128, @bitCast(@as(u128, 0x40042eab345678439abcdefea5678234))), |
| 63 | 65 | @as(f128, @bitCast(@as(u128, 0x3ffeedcb34a235253948765432134675))), |
| 64 | 66 | 0x400423e7f9e3c9fc, |
| 65 | 67 | 0xd906c2c2a85777c4, |
| 66 | 68 | ); |
| 67 | 69 | |
| 68 | try test__multf3( | |
| 70 | try test_mul_f128( | |
| 69 | 71 | @as(f128, @bitCast(@as(u128, 0x3fcd353e45674d89abacc3a2ebf3ff50))), |
| 70 | 72 | @as(f128, @bitCast(@as(u128, 0x3ff6ed8764648369535adf4be3214568))), |
| 71 | 73 | 0x3fc52a163c6223fc, |
| 72 | 74 | 0xc94c4bf0430768b4, |
| 73 | 75 | ); |
| 74 | 76 | |
| 75 | try test__multf3( | |
| 77 | try test_mul_f128( | |
| 76 | 78 | 0x1.234425696abcad34a35eeffefdcbap+456, |
| 77 | 79 | 0x451.ed98d76e5d46e5f24323dff21ffp+600, |
| 78 | 80 | 0x44293a91de5e0e94, |
| 79 | 81 | 0xe8ed17cc2cdf64ac, |
| 80 | 82 | ); |
| 81 | 83 | |
| 82 | try test__multf3( | |
| 84 | try test_mul_f128( | |
| 83 | 85 | @as(f128, @bitCast(@as(u128, 0x3f154356473c82a9fabf2d22ace345df))), |
| 84 | 86 | @as(f128, @bitCast(@as(u128, 0x3e38eda98765476743ab21da23d45679))), |
| 85 | 87 | 0x3d4f37c1a3137cae, |
| 86 | 88 | 0xfc6807048bc2836a, |
| 87 | 89 | ); |
| 88 | 90 | |
| 89 | try test__multf3(0x1.23456734245345p-10000, 0x1.edcba524498724p-6497, 0x0, 0x0); | |
| 91 | try test_mul_f128(0x1.23456734245345p-10000, 0x1.edcba524498724p-6497, 0x0, 0x0); | |
| 90 | 92 | |
| 91 | 93 | // Denormal operands. |
| 92 | try test__multf3( | |
| 94 | try test_mul_f128( | |
| 93 | 95 | 0x0.0000000000000000000000000001p-16382, |
| 94 | 96 | 0x1p16383, |
| 95 | 97 | 0x3f90000000000000, |
| 96 | 98 | 0x0, |
| 97 | 99 | ); |
| 98 | try test__multf3( | |
| 100 | try test_mul_f128( | |
| 99 | 101 | 0x1p16383, |
| 100 | 102 | 0x0.0000000000000000000000000001p-16382, |
| 101 | 103 | 0x3f90000000000000, |
| 102 | 104 | 0x0, |
| 103 | 105 | ); |
| 104 | 106 | |
| 105 | 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_0002p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0003); | |
| 107 | try test__multf3(2.0, math.floatTrueMin(f128), 0x0000_0000_0000_0000, 0x0000_0000_0000_0002); | |
| 107 | try test_mul_f128(0x1.0000_0000_0000_0000_0000_0000_0001p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0002); | |
| 108 | try test_mul_f128(0x1.0000_0000_0000_0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0003); | |
| 109 | try test_mul_f128(2.0, math.floatTrueMin(f128), 0x0000_0000_0000_0000, 0x0000_0000_0000_0002); | |
| 108 | 110 | } |
| 109 | 111 | |
| 110 | 112 | const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1))); |
| 111 | 113 | |
| 112 | fn test__mulxf3(a: f80, b: f80, expected: u80) !void { | |
| 113 | const x = __mulxf3(a, b); | |
| 114 | fn test_mul_f80(a: f80, b: f80, expected: u80) !void { | |
| 115 | const x = mul_f80(a, b); | |
| 114 | 116 | const rep: u80 = @bitCast(x); |
| 115 | 117 | |
| 116 | 118 | if (rep == expected) |
| ... | ... | @@ -124,47 +126,47 @@ fn test__mulxf3(a: f80, b: f80, expected: u80) !void { |
| 124 | 126 | |
| 125 | 127 | test "mulxf3" { |
| 126 | 128 | // NaN * any = NaN |
| 127 | try test__mulxf3(qnan80, 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80))); | |
| 128 | try test__mulxf3(@as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80))); | |
| 129 | try test_mul_f80(qnan80, 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80))); | |
| 130 | try test_mul_f80(@as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80))); | |
| 129 | 131 | |
| 130 | 132 | // any * NaN = NaN |
| 131 | try test__mulxf3(0x1.23456789abcdefp+5, qnan80, @as(u80, @bitCast(qnan80))); | |
| 132 | try test__mulxf3(0x1.23456789abcdefp+5, @as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), @as(u80, @bitCast(qnan80))); | |
| 133 | try test_mul_f80(0x1.23456789abcdefp+5, qnan80, @as(u80, @bitCast(qnan80))); | |
| 134 | try test_mul_f80(0x1.23456789abcdefp+5, @as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), @as(u80, @bitCast(qnan80))); | |
| 133 | 135 | |
| 134 | 136 | // NaN * inf = NaN |
| 135 | try test__mulxf3(qnan80, math.inf(f80), @as(u80, @bitCast(qnan80))); | |
| 137 | try test_mul_f80(qnan80, math.inf(f80), @as(u80, @bitCast(qnan80))); | |
| 136 | 138 | |
| 137 | 139 | // inf * NaN = NaN |
| 138 | try test__mulxf3(math.inf(f80), qnan80, @as(u80, @bitCast(qnan80))); | |
| 140 | try test_mul_f80(math.inf(f80), qnan80, @as(u80, @bitCast(qnan80))); | |
| 139 | 141 | |
| 140 | 142 | // inf * inf = inf |
| 141 | try test__mulxf3(math.inf(f80), math.inf(f80), @as(u80, @bitCast(math.inf(f80)))); | |
| 143 | try test_mul_f80(math.inf(f80), math.inf(f80), @as(u80, @bitCast(math.inf(f80)))); | |
| 142 | 144 | |
| 143 | 145 | // inf * -inf = -inf |
| 144 | try test__mulxf3(math.inf(f80), -math.inf(f80), @as(u80, @bitCast(-math.inf(f80)))); | |
| 146 | try test_mul_f80(math.inf(f80), -math.inf(f80), @as(u80, @bitCast(-math.inf(f80)))); | |
| 145 | 147 | |
| 146 | 148 | // -inf + inf = -inf |
| 147 | try test__mulxf3(-math.inf(f80), math.inf(f80), @as(u80, @bitCast(-math.inf(f80)))); | |
| 149 | try test_mul_f80(-math.inf(f80), math.inf(f80), @as(u80, @bitCast(-math.inf(f80)))); | |
| 148 | 150 | |
| 149 | 151 | // inf * any = inf |
| 150 | try test__mulxf3(math.inf(f80), 0x1.2335653452436234723489432abcdefp+5, @as(u80, @bitCast(math.inf(f80)))); | |
| 152 | try test_mul_f80(math.inf(f80), 0x1.2335653452436234723489432abcdefp+5, @as(u80, @bitCast(math.inf(f80)))); | |
| 151 | 153 | |
| 152 | 154 | // any * inf = inf |
| 153 | try test__mulxf3(0x1.2335653452436234723489432abcdefp+5, math.inf(f80), @as(u80, @bitCast(math.inf(f80)))); | |
| 155 | try test_mul_f80(0x1.2335653452436234723489432abcdefp+5, math.inf(f80), @as(u80, @bitCast(math.inf(f80)))); | |
| 154 | 156 | |
| 155 | 157 | // any * any |
| 156 | try test__mulxf3(0x1.0p+0, 0x1.dcba987654321p+5, 0x4004_ee5d_4c3b_2a19_0800); | |
| 157 | try test__mulxf3(0x1.0000_0000_0000_0004p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0003); // exact | |
| 158 | ||
| 159 | try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.0p+5, 0x4004_8000_0000_0000_0001); // exact | |
| 160 | try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.7ffep+5, 0x4004_BFFF_0000_0000_0001); // round down | |
| 161 | try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0002); // round up to even | |
| 162 | try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.8002p+5, 0x4004_C001_0000_0000_0002); // round up | |
| 163 | try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.0p+6, 0x4005_8000_0000_0000_0001); // exact | |
| 164 | ||
| 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_0001_0002p+0, 0x3FFF_8000_0001_0001_0001); // round up | |
| 167 | try test__mulxf3(0x0.8000_0000_0000_0000p-16382, 2.0, 0x0001_8000_0000_0000_0000); // denormal -> normal | |
| 168 | try test__mulxf3(0x0.7fff_ffff_ffff_fffep-16382, 0x2.0000_0000_0000_0008p0, 0x0001_8000_0000_0000_0000); // denormal -> normal | |
| 169 | try test__mulxf3(0x0.7fff_ffff_ffff_fffep-16382, 0x1.0000_0000_0000_0000p0, 0x0000_3FFF_FFFF_FFFF_FFFF); // denormal -> denormal | |
| 158 | try test_mul_f80(0x1.0p+0, 0x1.dcba987654321p+5, 0x4004_ee5d_4c3b_2a19_0800); | |
| 159 | try test_mul_f80(0x1.0000_0000_0000_0004p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0003); // exact | |
| 160 | ||
| 161 | try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.0p+5, 0x4004_8000_0000_0000_0001); // exact | |
| 162 | try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.7ffep+5, 0x4004_BFFF_0000_0000_0001); // round down | |
| 163 | try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0002); // round up to even | |
| 164 | try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.8002p+5, 0x4004_C001_0000_0000_0002); // round up | |
| 165 | try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.0p+6, 0x4005_8000_0000_0000_0001); // exact | |
| 166 | ||
| 167 | try test_mul_f80(0x1.0000_0001p+0, 0x1.0000_0001p+0, 0x3FFF_8000_0001_0000_0000); // round down to even | |
| 168 | try test_mul_f80(0x1.0000_0001p+0, 0x1.0000_0001_0002p+0, 0x3FFF_8000_0001_0001_0001); // round up | |
| 169 | try test_mul_f80(0x0.8000_0000_0000_0000p-16382, 2.0, 0x0001_8000_0000_0000_0000); // denormal -> normal | |
| 170 | try test_mul_f80(0x0.7fff_ffff_ffff_fffep-16382, 0x2.0000_0000_0000_0008p0, 0x0001_8000_0000_0000_0000); // denormal -> normal | |
| 171 | try test_mul_f80(0x0.7fff_ffff_ffff_fffep-16382, 0x1.0000_0000_0000_0000p0, 0x0000_3FFF_FFFF_FFFF_FFFF); // denormal -> denormal | |
| 170 | 172 | } |
lib/compiler_rt/mulhc3.zig deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const mulc3 = @import("./mulc3.zig"); | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | |
| 7 | symbol(&__mulhc3, "__mulhc3"); | |
| 8 | } | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __mulhc3(a: f16, b: f16, c: f16, d: f16) callconv(.c) mulc3.Complex(f16) { | |
| 12 | return mulc3.mulc3(f16, a, b, c, d); | |
| 13 | } |
lib/compiler_rt/mulhf3.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const mulf3 = @import("./mulf3.zig").mulf3; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__mulhf3, "__mulhf3"); | |
| 7 | } | |
| 8 | ||
| 9 | pub fn __mulhf3(a: f16, b: f16) callconv(.c) f16 { | |
| 10 | return mulf3(f16, a, b); | |
| 11 | } |
lib/compiler_rt/mulsc3.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 2 | const mulc3 = @import("./mulc3.zig"); | |
| 3 | ||
| 4 | comptime { | |
| 5 | if (@import("builtin").zig_backend != .stage2_c) { | |
| 6 | symbol(&__mulsc3, "__mulsc3"); | |
| 7 | } | |
| 8 | } | |
| 9 | ||
| 10 | pub fn __mulsc3(a: f32, b: f32, c: f32, d: f32) callconv(.c) mulc3.Complex(f32) { | |
| 11 | return mulc3.mulc3(f32, a, b, c, d); | |
| 12 | } |
lib/compiler_rt/mulsf3.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const mulf3 = @import("./mulf3.zig").mulf3; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_fmul, "__aeabi_fmul"); | |
| 8 | } else { | |
| 9 | symbol(&__mulsf3, "__mulsf3"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | pub fn __mulsf3(a: f32, b: f32) callconv(.c) f32 { | |
| 14 | return mulf3(f32, a, b); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_fmul(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 18 | return mulf3(f32, a, b); | |
| 19 | } |
lib/compiler_rt/multc3.zig deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | const mulc3 = @import("./mulc3.zig"); | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | |
| 7 | if (compiler_rt.want_ppc_abi) | |
| 8 | symbol(&__multc3, "__mulkc3"); | |
| 9 | symbol(&__multc3, "__multc3"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | pub fn __multc3(a: f128, b: f128, c: f128, d: f128) callconv(.c) mulc3.Complex(f128) { | |
| 14 | return mulc3.mulc3(f128, a, b, c, d); | |
| 15 | } |
lib/compiler_rt/multf3.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const mulf3 = @import("./mulf3.zig").mulf3; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) { | |
| 7 | symbol(&__multf3, "__mulkf3"); | |
| 8 | } else if (compiler_rt.want_sparc64_abi) { | |
| 9 | symbol(&_Qp_mul, "_Qp_mul"); | |
| 10 | } else if (compiler_rt.want_sparc32_abi) { | |
| 11 | symbol(&__multf3, "_Q_mul"); | |
| 12 | } | |
| 13 | symbol(&__multf3, "__multf3"); | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __multf3(a: f128, b: f128) callconv(.c) f128 { | |
| 17 | return mulf3(f128, a, b); | |
| 18 | } | |
| 19 | ||
| 20 | fn _Qp_mul(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { | |
| 21 | c.* = mulf3(f128, a.*, b.*); | |
| 22 | } |
lib/compiler_rt/mulvsi3.zig+3-2| ... | ... | @@ -1,7 +1,8 @@ |
| 1 | 1 | const testing = @import("std").testing; |
| 2 | 2 | |
| 3 | 3 | const mulv = @import("mulo.zig"); |
| 4 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 5 | const symbol = compiler_rt.symbol; | |
| 5 | 6 | |
| 6 | 7 | comptime { |
| 7 | 8 | symbol(&__mulvsi3, "__mulvsi3"); |
| ... | ... | @@ -10,7 +11,7 @@ comptime { |
| 10 | 11 | pub fn __mulvsi3(a: i32, b: i32) callconv(.c) i32 { |
| 11 | 12 | var overflow: c_int = 0; |
| 12 | 13 | const sum = mulv.__mulosi4(a, b, &overflow); |
| 13 | if (overflow != 0) @panic("compiler-rt: integer overflow"); | |
| 14 | if (overflow != 0) @panic("integer overflow"); | |
| 14 | 15 | return sum; |
| 15 | 16 | } |
| 16 | 17 |
lib/compiler_rt/mulxc3.zig deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const mulc3 = @import("./mulc3.zig"); | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (@import("builtin").zig_backend != .stage2_c) { | |
| 7 | symbol(&__mulxc3, "__mulxc3"); | |
| 8 | } | |
| 9 | } | |
| 10 | ||
| 11 | pub fn __mulxc3(a: f80, b: f80, c: f80, d: f80) callconv(.c) mulc3.Complex(f80) { | |
| 12 | return mulc3.mulc3(f80, a, b, c, d); | |
| 13 | } |
lib/compiler_rt/mulxf3.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const mulf3 = @import("./mulf3.zig").mulf3; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__mulxf3, "__mulxf3"); | |
| 7 | } | |
| 8 | ||
| 9 | pub fn __mulxf3(a: f80, b: f80) callconv(.c) f80 { | |
| 10 | return mulf3(f80, a, b); | |
| 11 | } |
lib/compiler_rt/negv.zig+1-2| ... | ... | @@ -33,8 +33,7 @@ inline fn negvXi(comptime ST: type, a: ST) ST { |
| 33 | 33 | }; |
| 34 | 34 | const N: UT = @bitSizeOf(ST); |
| 35 | 35 | const min: ST = @as(ST, @bitCast((@as(UT, 1) << (N - 1)))); |
| 36 | if (a == min) | |
| 37 | @panic("compiler_rt negv: overflow"); | |
| 36 | if (a == min) @panic("integer overflow"); | |
| 38 | 37 | return -a; |
| 39 | 38 | } |
| 40 | 39 |
lib/compiler_rt/os_version_check.zig-1| ... | ... | @@ -3,7 +3,6 @@ const testing = std.testing; |
| 3 | 3 | const builtin = @import("builtin"); |
| 4 | 4 | const compiler_rt = @import("../compiler_rt.zig"); |
| 5 | 5 | const symbol = compiler_rt.symbol; |
| 6 | const panic = @import("../compiler_rt.zig").panic; | |
| 7 | 6 | |
| 8 | 7 | const have_availability_version_check = builtin.os.tag.isDarwin() and |
| 9 | 8 | builtin.os.version_range.semver.min.order(.{ .major = 10, .minor = 15, .patch = 0 }).compare(.gte); |
lib/compiler_rt/parity.zig+2-1| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | //! parity - if number of bits set is even => 0, else => 1 |
| 2 | 2 | //! - pariytXi2_generic for big and little endian |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 4 | 5 | |
| 5 | 6 | comptime { |
| 6 | 7 | symbol(&__paritysi2, "__paritysi2"); |
lib/compiler_rt/popcount.zig+2-1| ... | ... | @@ -6,7 +6,8 @@ |
| 6 | 6 | //! TAOCP: Combinational Algorithms, Bitwise Tricks And Techniques, |
| 7 | 7 | //! subsubsection "Working with the rightmost bits" and "Sideways addition". |
| 8 | 8 | |
| 9 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 9 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 10 | const symbol = compiler_rt.symbol; | |
| 10 | 11 | |
| 11 | 12 | comptime { |
| 12 | 13 | symbol(&__popcountsi2, "__popcountsi2"); |
lib/compiler_rt/powiXf2.zig+28-11| ... | ... | @@ -4,16 +4,18 @@ |
| 4 | 4 | //! error propagation and this method is optimized for performance, not accuracy. |
| 5 | 5 | |
| 6 | 6 | const compiler_rt = @import("../compiler_rt.zig"); |
| 7 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 7 | const symbol = compiler_rt.symbol; | |
| 8 | 8 | |
| 9 | 9 | comptime { |
| 10 | 10 | symbol(&__powihf2, "__powihf2"); |
| 11 | 11 | symbol(&__powisf2, "__powisf2"); |
| 12 | 12 | symbol(&__powidf2, "__powidf2"); |
| 13 | if (compiler_rt.want_ppc_abi) | |
| 14 | symbol(&__powitf2, "__powikf2"); | |
| 15 | symbol(&__powitf2, "__powitf2"); | |
| 16 | 13 | symbol(&__powixf2, "__powixf2"); |
| 14 | if (compiler_rt.want_ppc_abi) { | |
| 15 | symbol(&__powitf2, "__powikf2"); | |
| 16 | } else { | |
| 17 | symbol(&__powitf2, "__powitf2"); | |
| 18 | } | |
| 17 | 19 | } |
| 18 | 20 | |
| 19 | 21 | inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT { |
| ... | ... | @@ -32,26 +34,41 @@ inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT { |
| 32 | 34 | return if (is_recip) 1 / r else r; |
| 33 | 35 | } |
| 34 | 36 | |
| 35 | pub fn __powihf2(a: f16, b: i32) callconv(.c) f16 { | |
| 37 | fn __powihf2(a: compiler_rt.f16.Abi, b: i32) callconv(.c) compiler_rt.f16.Abi { | |
| 38 | return compiler_rt.f16.toAbi(powi_f16(compiler_rt.f16.fromAbi(a), b)); | |
| 39 | } | |
| 40 | pub fn powi_f16(a: f16, b: i32) f16 { | |
| 36 | 41 | return powiXf2(f16, a, b); |
| 37 | 42 | } |
| 38 | 43 | |
| 39 | pub fn __powisf2(a: f32, b: i32) callconv(.c) f32 { | |
| 44 | fn __powisf2(a: compiler_rt.f32.Abi, b: i32) callconv(.c) compiler_rt.f32.Abi { | |
| 45 | return compiler_rt.f32.toAbi(powi_f32(compiler_rt.f32.fromAbi(a), b)); | |
| 46 | } | |
| 47 | pub fn powi_f32(a: f32, b: i32) f32 { | |
| 40 | 48 | return powiXf2(f32, a, b); |
| 41 | 49 | } |
| 42 | 50 | |
| 43 | pub fn __powidf2(a: f64, b: i32) callconv(.c) f64 { | |
| 51 | fn __powidf2(a: compiler_rt.f64.Abi, b: i32) callconv(.c) compiler_rt.f64.Abi { | |
| 52 | return compiler_rt.f64.toAbi(powi_f64(compiler_rt.f64.fromAbi(a), b)); | |
| 53 | } | |
| 54 | pub fn powi_f64(a: f64, b: i32) f64 { | |
| 44 | 55 | return powiXf2(f64, a, b); |
| 45 | 56 | } |
| 46 | 57 | |
| 47 | pub fn __powitf2(a: f128, b: i32) callconv(.c) f128 { | |
| 48 | return powiXf2(f128, a, b); | |
| 58 | fn __powixf2(a: compiler_rt.f80.Abi, b: i32) callconv(.c) compiler_rt.f80.Abi { | |
| 59 | return compiler_rt.f80.toAbi(powi_f80(compiler_rt.f80.fromAbi(a), b)); | |
| 49 | 60 | } |
| 50 | ||
| 51 | pub fn __powixf2(a: f80, b: i32) callconv(.c) f80 { | |
| 61 | pub fn powi_f80(a: f80, b: i32) f80 { | |
| 52 | 62 | return powiXf2(f80, a, b); |
| 53 | 63 | } |
| 54 | 64 | |
| 65 | fn __powitf2(a: compiler_rt.f128.Abi, b: i32) callconv(.c) compiler_rt.f128.Abi { | |
| 66 | return compiler_rt.f128.toAbi(powi_f128(compiler_rt.f128.fromAbi(a), b)); | |
| 67 | } | |
| 68 | pub fn powi_f128(a: f128, b: i32) f128 { | |
| 69 | return powiXf2(f128, a, b); | |
| 70 | } | |
| 71 | ||
| 55 | 72 | test { |
| 56 | 73 | _ = @import("powiXf2_test.zig"); |
| 57 | 74 | } |
lib/compiler_rt/powiXf2_test.zig+531-525| ... | ... | @@ -2,562 +2,568 @@ |
| 2 | 2 | // powisf2_test.c, powidf2_test.c, powitf2_test.c, powixf2_test.c |
| 3 | 3 | // powihf2 adapted from powisf2 tests |
| 4 | 4 | |
| 5 | const powiXf2 = @import("powiXf2.zig"); | |
| 6 | 5 | const std = @import("std"); |
| 7 | const builtin = @import("builtin"); | |
| 8 | 6 | const testing = std.testing; |
| 9 | 7 | const math = std.math; |
| 10 | 8 | |
| 11 | fn test__powihf2(a: f16, b: i32, expected: f16) !void { | |
| 12 | const result = powiXf2.__powihf2(a, b); | |
| 9 | const impl = @import("powiXf2.zig"); | |
| 10 | ||
| 11 | const powi_f16 = impl.powi_f16; | |
| 12 | const powi_f32 = impl.powi_f32; | |
| 13 | const powi_f64 = impl.powi_f64; | |
| 14 | const powi_f80 = impl.powi_f80; | |
| 15 | const powi_f128 = impl.powi_f128; | |
| 16 | ||
| 17 | fn test_powi_f16(a: f16, b: i32, expected: f16) !void { | |
| 18 | const result = powi_f16(a, b); | |
| 13 | 19 | try testing.expectEqual(expected, result); |
| 14 | 20 | } |
| 15 | 21 | |
| 16 | fn test__powisf2(a: f32, b: i32, expected: f32) !void { | |
| 17 | const result = powiXf2.__powisf2(a, b); | |
| 22 | fn test_powi_f32(a: f32, b: i32, expected: f32) !void { | |
| 23 | const result = powi_f32(a, b); | |
| 18 | 24 | try testing.expectEqual(expected, result); |
| 19 | 25 | } |
| 20 | 26 | |
| 21 | fn test__powidf2(a: f64, b: i32, expected: f64) !void { | |
| 22 | const result = powiXf2.__powidf2(a, b); | |
| 27 | fn test_powi_f64(a: f64, b: i32, expected: f64) !void { | |
| 28 | const result = powi_f64(a, b); | |
| 23 | 29 | try testing.expectEqual(expected, result); |
| 24 | 30 | } |
| 25 | 31 | |
| 26 | fn test__powitf2(a: f128, b: i32, expected: f128) !void { | |
| 27 | const result = powiXf2.__powitf2(a, b); | |
| 32 | fn test_powi_f80(a: f80, b: i32, expected: f80) !void { | |
| 33 | const result = powi_f80(a, b); | |
| 28 | 34 | try testing.expectEqual(expected, result); |
| 29 | 35 | } |
| 30 | 36 | |
| 31 | fn test__powixf2(a: f80, b: i32, expected: f80) !void { | |
| 32 | const result = powiXf2.__powixf2(a, b); | |
| 37 | fn test_powi_f128(a: f128, b: i32, expected: f128) !void { | |
| 38 | const result = powi_f128(a, b); | |
| 33 | 39 | try testing.expectEqual(expected, result); |
| 34 | 40 | } |
| 35 | 41 | |
| 36 | test "powihf2" { | |
| 42 | test powi_f16 { | |
| 37 | 43 | const inf_f16 = math.inf(f16); |
| 38 | try test__powisf2(0, 0, 1); | |
| 39 | try test__powihf2(1, 0, 1); | |
| 40 | try test__powihf2(1.5, 0, 1); | |
| 41 | try test__powihf2(2, 0, 1); | |
| 42 | try test__powihf2(inf_f16, 0, 1); | |
| 43 | ||
| 44 | try test__powihf2(-0.0, 0, 1); | |
| 45 | try test__powihf2(-1, 0, 1); | |
| 46 | try test__powihf2(-1.5, 0, 1); | |
| 47 | try test__powihf2(-2, 0, 1); | |
| 48 | try test__powihf2(-inf_f16, 0, 1); | |
| 49 | ||
| 50 | try test__powihf2(0, 1, 0); | |
| 51 | try test__powihf2(0, 2, 0); | |
| 52 | try test__powihf2(0, 3, 0); | |
| 53 | try test__powihf2(0, 4, 0); | |
| 54 | try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 55 | try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); | |
| 56 | ||
| 57 | try test__powihf2(-0.0, 1, -0.0); | |
| 58 | try test__powihf2(-0.0, 2, 0); | |
| 59 | try test__powihf2(-0.0, 3, -0.0); | |
| 60 | try test__powihf2(-0.0, 4, 0); | |
| 61 | try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 62 | try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); | |
| 63 | ||
| 64 | try test__powihf2(1, 1, 1); | |
| 65 | try test__powihf2(1, 2, 1); | |
| 66 | try test__powihf2(1, 3, 1); | |
| 67 | try test__powihf2(1, 4, 1); | |
| 68 | try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); | |
| 69 | try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); | |
| 70 | ||
| 71 | try test__powihf2(inf_f16, 1, inf_f16); | |
| 72 | try test__powihf2(inf_f16, 2, inf_f16); | |
| 73 | try test__powihf2(inf_f16, 3, inf_f16); | |
| 74 | try test__powihf2(inf_f16, 4, inf_f16); | |
| 75 | try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16); | |
| 76 | try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f16); | |
| 77 | ||
| 78 | try test__powihf2(-inf_f16, 1, -inf_f16); | |
| 79 | try test__powihf2(-inf_f16, 2, inf_f16); | |
| 80 | try test__powihf2(-inf_f16, 3, -inf_f16); | |
| 81 | try test__powihf2(-inf_f16, 4, inf_f16); | |
| 82 | try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16); | |
| 83 | try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f16); | |
| 44 | try test_powi_f16(0, 0, 1); | |
| 45 | try test_powi_f16(1, 0, 1); | |
| 46 | try test_powi_f16(1.5, 0, 1); | |
| 47 | try test_powi_f16(2, 0, 1); | |
| 48 | try test_powi_f16(inf_f16, 0, 1); | |
| 49 | ||
| 50 | try test_powi_f16(-0.0, 0, 1); | |
| 51 | try test_powi_f16(-1, 0, 1); | |
| 52 | try test_powi_f16(-1.5, 0, 1); | |
| 53 | try test_powi_f16(-2, 0, 1); | |
| 54 | try test_powi_f16(-inf_f16, 0, 1); | |
| 55 | ||
| 56 | try test_powi_f16(0, 1, 0); | |
| 57 | try test_powi_f16(0, 2, 0); | |
| 58 | try test_powi_f16(0, 3, 0); | |
| 59 | try test_powi_f16(0, 4, 0); | |
| 60 | try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 61 | try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); | |
| 62 | ||
| 63 | try test_powi_f16(-0.0, 1, -0.0); | |
| 64 | try test_powi_f16(-0.0, 2, 0); | |
| 65 | try test_powi_f16(-0.0, 3, -0.0); | |
| 66 | try test_powi_f16(-0.0, 4, 0); | |
| 67 | try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 68 | try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); | |
| 69 | ||
| 70 | try test_powi_f16(1, 1, 1); | |
| 71 | try test_powi_f16(1, 2, 1); | |
| 72 | try test_powi_f16(1, 3, 1); | |
| 73 | try test_powi_f16(1, 4, 1); | |
| 74 | try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); | |
| 75 | try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); | |
| 76 | ||
| 77 | try test_powi_f16(inf_f16, 1, inf_f16); | |
| 78 | try test_powi_f16(inf_f16, 2, inf_f16); | |
| 79 | try test_powi_f16(inf_f16, 3, inf_f16); | |
| 80 | try test_powi_f16(inf_f16, 4, inf_f16); | |
| 81 | try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16); | |
| 82 | try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f16); | |
| 83 | ||
| 84 | try test_powi_f16(-inf_f16, 1, -inf_f16); | |
| 85 | try test_powi_f16(-inf_f16, 2, inf_f16); | |
| 86 | try test_powi_f16(-inf_f16, 3, -inf_f16); | |
| 87 | try test_powi_f16(-inf_f16, 4, inf_f16); | |
| 88 | try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16); | |
| 89 | try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f16); | |
| 84 | 90 | // |
| 85 | try test__powihf2(0, -1, inf_f16); | |
| 86 | try test__powihf2(0, -2, inf_f16); | |
| 87 | try test__powihf2(0, -3, inf_f16); | |
| 88 | try test__powihf2(0, -4, inf_f16); | |
| 89 | try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // 0 ^ anything = +inf | |
| 90 | try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f16); | |
| 91 | try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16); | |
| 92 | ||
| 93 | try test__powihf2(-0.0, -1, -inf_f16); | |
| 94 | try test__powihf2(-0.0, -2, inf_f16); | |
| 95 | try test__powihf2(-0.0, -3, -inf_f16); | |
| 96 | try test__powihf2(-0.0, -4, inf_f16); | |
| 97 | try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // -0 ^ anything even = +inf | |
| 98 | try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f16); // -0 ^ anything odd = -inf | |
| 99 | try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16); | |
| 100 | ||
| 101 | try test__powihf2(1, -1, 1); | |
| 102 | try test__powihf2(1, -2, 1); | |
| 103 | try test__powihf2(1, -3, 1); | |
| 104 | try test__powihf2(1, -4, 1); | |
| 105 | try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); // 1.0 ^ anything = 1 | |
| 106 | try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); | |
| 107 | try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); | |
| 108 | ||
| 109 | try test__powihf2(inf_f16, -1, 0); | |
| 110 | try test__powihf2(inf_f16, -2, 0); | |
| 111 | try test__powihf2(inf_f16, -3, 0); | |
| 112 | try test__powihf2(inf_f16, -4, 0); | |
| 113 | try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 114 | try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); | |
| 115 | try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 91 | try test_powi_f16(0, -1, inf_f16); | |
| 92 | try test_powi_f16(0, -2, inf_f16); | |
| 93 | try test_powi_f16(0, -3, inf_f16); | |
| 94 | try test_powi_f16(0, -4, inf_f16); | |
| 95 | try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // 0 ^ anything = +inf | |
| 96 | try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f16); | |
| 97 | try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16); | |
| 98 | ||
| 99 | try test_powi_f16(-0.0, -1, -inf_f16); | |
| 100 | try test_powi_f16(-0.0, -2, inf_f16); | |
| 101 | try test_powi_f16(-0.0, -3, -inf_f16); | |
| 102 | try test_powi_f16(-0.0, -4, inf_f16); | |
| 103 | try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // -0 ^ anything even = +inf | |
| 104 | try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f16); // -0 ^ anything odd = -inf | |
| 105 | try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16); | |
| 106 | ||
| 107 | try test_powi_f16(1, -1, 1); | |
| 108 | try test_powi_f16(1, -2, 1); | |
| 109 | try test_powi_f16(1, -3, 1); | |
| 110 | try test_powi_f16(1, -4, 1); | |
| 111 | try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); // 1.0 ^ anything = 1 | |
| 112 | try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); | |
| 113 | try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); | |
| 114 | ||
| 115 | try test_powi_f16(inf_f16, -1, 0); | |
| 116 | try test_powi_f16(inf_f16, -2, 0); | |
| 117 | try test_powi_f16(inf_f16, -3, 0); | |
| 118 | try test_powi_f16(inf_f16, -4, 0); | |
| 119 | try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 120 | try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); | |
| 121 | try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 116 | 122 | // |
| 117 | try test__powihf2(-inf_f16, -1, -0.0); | |
| 118 | try test__powihf2(-inf_f16, -2, 0); | |
| 119 | try test__powihf2(-inf_f16, -3, -0.0); | |
| 120 | try test__powihf2(-inf_f16, -4, 0); | |
| 121 | try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 122 | try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); | |
| 123 | try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 124 | ||
| 125 | try test__powihf2(2, 10, 1024.0); | |
| 126 | try test__powihf2(-2, 10, 1024.0); | |
| 127 | try test__powihf2(2, -10, 1.0 / 1024.0); | |
| 128 | try test__powihf2(-2, -10, 1.0 / 1024.0); | |
| 129 | ||
| 130 | try test__powihf2(2, 14, 16384.0); | |
| 131 | try test__powihf2(-2, 14, 16384.0); | |
| 132 | try test__powihf2(2, 15, 32768.0); | |
| 133 | try test__powihf2(-2, 15, -32768.0); | |
| 134 | try test__powihf2(2, 16, inf_f16); | |
| 135 | try test__powihf2(-2, 16, inf_f16); | |
| 136 | ||
| 137 | try test__powihf2(2, -13, 1.0 / 8192.0); | |
| 138 | try test__powihf2(-2, -13, -1.0 / 8192.0); | |
| 139 | try test__powihf2(2, -15, 1.0 / 32768.0); | |
| 140 | try test__powihf2(-2, -15, -1.0 / 32768.0); | |
| 141 | try test__powihf2(2, -16, 0.0); // expected = 0.0 = 1/(-2**16) | |
| 142 | try test__powihf2(-2, -16, 0.0); // expected = 0.0 = 1/(2**16) | |
| 123 | try test_powi_f16(-inf_f16, -1, -0.0); | |
| 124 | try test_powi_f16(-inf_f16, -2, 0); | |
| 125 | try test_powi_f16(-inf_f16, -3, -0.0); | |
| 126 | try test_powi_f16(-inf_f16, -4, 0); | |
| 127 | try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 128 | try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); | |
| 129 | try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 130 | ||
| 131 | try test_powi_f16(2, 10, 1024.0); | |
| 132 | try test_powi_f16(-2, 10, 1024.0); | |
| 133 | try test_powi_f16(2, -10, 1.0 / 1024.0); | |
| 134 | try test_powi_f16(-2, -10, 1.0 / 1024.0); | |
| 135 | ||
| 136 | try test_powi_f16(2, 14, 16384.0); | |
| 137 | try test_powi_f16(-2, 14, 16384.0); | |
| 138 | try test_powi_f16(2, 15, 32768.0); | |
| 139 | try test_powi_f16(-2, 15, -32768.0); | |
| 140 | try test_powi_f16(2, 16, inf_f16); | |
| 141 | try test_powi_f16(-2, 16, inf_f16); | |
| 142 | ||
| 143 | try test_powi_f16(2, -13, 1.0 / 8192.0); | |
| 144 | try test_powi_f16(-2, -13, -1.0 / 8192.0); | |
| 145 | try test_powi_f16(2, -15, 1.0 / 32768.0); | |
| 146 | try test_powi_f16(-2, -15, -1.0 / 32768.0); | |
| 147 | try test_powi_f16(2, -16, 0.0); // expected = 0.0 = 1/(-2**16) | |
| 148 | try test_powi_f16(-2, -16, 0.0); // expected = 0.0 = 1/(2**16) | |
| 143 | 149 | } |
| 144 | 150 | |
| 145 | test "powisf2" { | |
| 151 | test powi_f32 { | |
| 146 | 152 | const inf_f32 = math.inf(f32); |
| 147 | try test__powisf2(0, 0, 1); | |
| 148 | try test__powisf2(1, 0, 1); | |
| 149 | try test__powisf2(1.5, 0, 1); | |
| 150 | try test__powisf2(2, 0, 1); | |
| 151 | try test__powisf2(inf_f32, 0, 1); | |
| 152 | ||
| 153 | try test__powisf2(-0.0, 0, 1); | |
| 154 | try test__powisf2(-1, 0, 1); | |
| 155 | try test__powisf2(-1.5, 0, 1); | |
| 156 | try test__powisf2(-2, 0, 1); | |
| 157 | try test__powisf2(-inf_f32, 0, 1); | |
| 158 | ||
| 159 | try test__powisf2(0, 1, 0); | |
| 160 | try test__powisf2(0, 2, 0); | |
| 161 | try test__powisf2(0, 3, 0); | |
| 162 | try test__powisf2(0, 4, 0); | |
| 163 | try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 164 | try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); | |
| 165 | ||
| 166 | try test__powisf2(-0.0, 1, -0.0); | |
| 167 | try test__powisf2(-0.0, 2, 0); | |
| 168 | try test__powisf2(-0.0, 3, -0.0); | |
| 169 | try test__powisf2(-0.0, 4, 0); | |
| 170 | try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 171 | try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); | |
| 172 | ||
| 173 | try test__powisf2(1, 1, 1); | |
| 174 | try test__powisf2(1, 2, 1); | |
| 175 | try test__powisf2(1, 3, 1); | |
| 176 | try test__powisf2(1, 4, 1); | |
| 177 | try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); | |
| 178 | try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); | |
| 179 | ||
| 180 | try test__powisf2(inf_f32, 1, inf_f32); | |
| 181 | try test__powisf2(inf_f32, 2, inf_f32); | |
| 182 | try test__powisf2(inf_f32, 3, inf_f32); | |
| 183 | try test__powisf2(inf_f32, 4, inf_f32); | |
| 184 | try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32); | |
| 185 | try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f32); | |
| 186 | ||
| 187 | try test__powisf2(-inf_f32, 1, -inf_f32); | |
| 188 | try test__powisf2(-inf_f32, 2, inf_f32); | |
| 189 | try test__powisf2(-inf_f32, 3, -inf_f32); | |
| 190 | try test__powisf2(-inf_f32, 4, inf_f32); | |
| 191 | try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32); | |
| 192 | try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f32); | |
| 193 | ||
| 194 | try test__powisf2(0, -1, inf_f32); | |
| 195 | try test__powisf2(0, -2, inf_f32); | |
| 196 | try test__powisf2(0, -3, inf_f32); | |
| 197 | try test__powisf2(0, -4, inf_f32); | |
| 198 | try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32); | |
| 199 | try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f32); | |
| 200 | try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32); | |
| 201 | ||
| 202 | try test__powisf2(-0.0, -1, -inf_f32); | |
| 203 | try test__powisf2(-0.0, -2, inf_f32); | |
| 204 | try test__powisf2(-0.0, -3, -inf_f32); | |
| 205 | try test__powisf2(-0.0, -4, inf_f32); | |
| 206 | try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32); | |
| 207 | try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f32); | |
| 208 | try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32); | |
| 209 | ||
| 210 | try test__powisf2(1, -1, 1); | |
| 211 | try test__powisf2(1, -2, 1); | |
| 212 | try test__powisf2(1, -3, 1); | |
| 213 | try test__powisf2(1, -4, 1); | |
| 214 | try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); | |
| 215 | try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); | |
| 216 | try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); | |
| 217 | ||
| 218 | try test__powisf2(inf_f32, -1, 0); | |
| 219 | try test__powisf2(inf_f32, -2, 0); | |
| 220 | try test__powisf2(inf_f32, -3, 0); | |
| 221 | try test__powisf2(inf_f32, -4, 0); | |
| 222 | try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 223 | try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); | |
| 224 | try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 225 | ||
| 226 | try test__powisf2(-inf_f32, -1, -0.0); | |
| 227 | try test__powisf2(-inf_f32, -2, 0); | |
| 228 | try test__powisf2(-inf_f32, -3, -0.0); | |
| 229 | try test__powisf2(-inf_f32, -4, 0); | |
| 230 | try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 231 | try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); | |
| 232 | try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 233 | ||
| 234 | try test__powisf2(2.0, 10, 1024.0); | |
| 235 | try test__powisf2(-2, 10, 1024.0); | |
| 236 | try test__powisf2(2, -10, 1.0 / 1024.0); | |
| 237 | try test__powisf2(-2, -10, 1.0 / 1024.0); | |
| 153 | try test_powi_f32(0, 0, 1); | |
| 154 | try test_powi_f32(1, 0, 1); | |
| 155 | try test_powi_f32(1.5, 0, 1); | |
| 156 | try test_powi_f32(2, 0, 1); | |
| 157 | try test_powi_f32(inf_f32, 0, 1); | |
| 158 | ||
| 159 | try test_powi_f32(-0.0, 0, 1); | |
| 160 | try test_powi_f32(-1, 0, 1); | |
| 161 | try test_powi_f32(-1.5, 0, 1); | |
| 162 | try test_powi_f32(-2, 0, 1); | |
| 163 | try test_powi_f32(-inf_f32, 0, 1); | |
| 164 | ||
| 165 | try test_powi_f32(0, 1, 0); | |
| 166 | try test_powi_f32(0, 2, 0); | |
| 167 | try test_powi_f32(0, 3, 0); | |
| 168 | try test_powi_f32(0, 4, 0); | |
| 169 | try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 170 | try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); | |
| 171 | ||
| 172 | try test_powi_f32(-0.0, 1, -0.0); | |
| 173 | try test_powi_f32(-0.0, 2, 0); | |
| 174 | try test_powi_f32(-0.0, 3, -0.0); | |
| 175 | try test_powi_f32(-0.0, 4, 0); | |
| 176 | try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 177 | try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); | |
| 178 | ||
| 179 | try test_powi_f32(1, 1, 1); | |
| 180 | try test_powi_f32(1, 2, 1); | |
| 181 | try test_powi_f32(1, 3, 1); | |
| 182 | try test_powi_f32(1, 4, 1); | |
| 183 | try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); | |
| 184 | try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); | |
| 185 | ||
| 186 | try test_powi_f32(inf_f32, 1, inf_f32); | |
| 187 | try test_powi_f32(inf_f32, 2, inf_f32); | |
| 188 | try test_powi_f32(inf_f32, 3, inf_f32); | |
| 189 | try test_powi_f32(inf_f32, 4, inf_f32); | |
| 190 | try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32); | |
| 191 | try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f32); | |
| 192 | ||
| 193 | try test_powi_f32(-inf_f32, 1, -inf_f32); | |
| 194 | try test_powi_f32(-inf_f32, 2, inf_f32); | |
| 195 | try test_powi_f32(-inf_f32, 3, -inf_f32); | |
| 196 | try test_powi_f32(-inf_f32, 4, inf_f32); | |
| 197 | try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32); | |
| 198 | try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f32); | |
| 199 | ||
| 200 | try test_powi_f32(0, -1, inf_f32); | |
| 201 | try test_powi_f32(0, -2, inf_f32); | |
| 202 | try test_powi_f32(0, -3, inf_f32); | |
| 203 | try test_powi_f32(0, -4, inf_f32); | |
| 204 | try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32); | |
| 205 | try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f32); | |
| 206 | try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32); | |
| 207 | ||
| 208 | try test_powi_f32(-0.0, -1, -inf_f32); | |
| 209 | try test_powi_f32(-0.0, -2, inf_f32); | |
| 210 | try test_powi_f32(-0.0, -3, -inf_f32); | |
| 211 | try test_powi_f32(-0.0, -4, inf_f32); | |
| 212 | try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32); | |
| 213 | try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f32); | |
| 214 | try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32); | |
| 215 | ||
| 216 | try test_powi_f32(1, -1, 1); | |
| 217 | try test_powi_f32(1, -2, 1); | |
| 218 | try test_powi_f32(1, -3, 1); | |
| 219 | try test_powi_f32(1, -4, 1); | |
| 220 | try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); | |
| 221 | try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); | |
| 222 | try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); | |
| 223 | ||
| 224 | try test_powi_f32(inf_f32, -1, 0); | |
| 225 | try test_powi_f32(inf_f32, -2, 0); | |
| 226 | try test_powi_f32(inf_f32, -3, 0); | |
| 227 | try test_powi_f32(inf_f32, -4, 0); | |
| 228 | try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 229 | try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); | |
| 230 | try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 231 | ||
| 232 | try test_powi_f32(-inf_f32, -1, -0.0); | |
| 233 | try test_powi_f32(-inf_f32, -2, 0); | |
| 234 | try test_powi_f32(-inf_f32, -3, -0.0); | |
| 235 | try test_powi_f32(-inf_f32, -4, 0); | |
| 236 | try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 237 | try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); | |
| 238 | try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 239 | ||
| 240 | try test_powi_f32(2.0, 10, 1024.0); | |
| 241 | try test_powi_f32(-2, 10, 1024.0); | |
| 242 | try test_powi_f32(2, -10, 1.0 / 1024.0); | |
| 243 | try test_powi_f32(-2, -10, 1.0 / 1024.0); | |
| 238 | 244 | // |
| 239 | try test__powisf2(2, 19, 524288.0); | |
| 240 | try test__powisf2(-2, 19, -524288.0); | |
| 241 | try test__powisf2(2, -19, 1.0 / 524288.0); | |
| 242 | try test__powisf2(-2, -19, -1.0 / 524288.0); | |
| 243 | ||
| 244 | try test__powisf2(2, 31, 2147483648.0); | |
| 245 | try test__powisf2(-2, 31, -2147483648.0); | |
| 246 | try test__powisf2(2, -31, 1.0 / 2147483648.0); | |
| 247 | try test__powisf2(-2, -31, -1.0 / 2147483648.0); | |
| 245 | try test_powi_f32(2, 19, 524288.0); | |
| 246 | try test_powi_f32(-2, 19, -524288.0); | |
| 247 | try test_powi_f32(2, -19, 1.0 / 524288.0); | |
| 248 | try test_powi_f32(-2, -19, -1.0 / 524288.0); | |
| 249 | ||
| 250 | try test_powi_f32(2, 31, 2147483648.0); | |
| 251 | try test_powi_f32(-2, 31, -2147483648.0); | |
| 252 | try test_powi_f32(2, -31, 1.0 / 2147483648.0); | |
| 253 | try test_powi_f32(-2, -31, -1.0 / 2147483648.0); | |
| 248 | 254 | } |
| 249 | 255 | |
| 250 | test "powidf2" { | |
| 256 | test powi_f64 { | |
| 251 | 257 | const inf_f64 = math.inf(f64); |
| 252 | try test__powidf2(0, 0, 1); | |
| 253 | try test__powidf2(1, 0, 1); | |
| 254 | try test__powidf2(1.5, 0, 1); | |
| 255 | try test__powidf2(2, 0, 1); | |
| 256 | try test__powidf2(inf_f64, 0, 1); | |
| 257 | ||
| 258 | try test__powidf2(-0.0, 0, 1); | |
| 259 | try test__powidf2(-1, 0, 1); | |
| 260 | try test__powidf2(-1.5, 0, 1); | |
| 261 | try test__powidf2(-2, 0, 1); | |
| 262 | try test__powidf2(-inf_f64, 0, 1); | |
| 263 | ||
| 264 | try test__powidf2(0, 1, 0); | |
| 265 | try test__powidf2(0, 2, 0); | |
| 266 | try test__powidf2(0, 3, 0); | |
| 267 | try test__powidf2(0, 4, 0); | |
| 268 | try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 269 | try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); | |
| 270 | ||
| 271 | try test__powidf2(-0.0, 1, -0.0); | |
| 272 | try test__powidf2(-0.0, 2, 0); | |
| 273 | try test__powidf2(-0.0, 3, -0.0); | |
| 274 | try test__powidf2(-0.0, 4, 0); | |
| 275 | try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 276 | try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); | |
| 277 | ||
| 278 | try test__powidf2(1, 1, 1); | |
| 279 | try test__powidf2(1, 2, 1); | |
| 280 | try test__powidf2(1, 3, 1); | |
| 281 | try test__powidf2(1, 4, 1); | |
| 282 | try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); | |
| 283 | try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); | |
| 284 | ||
| 285 | try test__powidf2(inf_f64, 1, inf_f64); | |
| 286 | try test__powidf2(inf_f64, 2, inf_f64); | |
| 287 | try test__powidf2(inf_f64, 3, inf_f64); | |
| 288 | try test__powidf2(inf_f64, 4, inf_f64); | |
| 289 | try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64); | |
| 290 | try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f64); | |
| 291 | ||
| 292 | try test__powidf2(-inf_f64, 1, -inf_f64); | |
| 293 | try test__powidf2(-inf_f64, 2, inf_f64); | |
| 294 | try test__powidf2(-inf_f64, 3, -inf_f64); | |
| 295 | try test__powidf2(-inf_f64, 4, inf_f64); | |
| 296 | try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64); | |
| 297 | try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f64); | |
| 298 | ||
| 299 | try test__powidf2(0, -1, inf_f64); | |
| 300 | try test__powidf2(0, -2, inf_f64); | |
| 301 | try test__powidf2(0, -3, inf_f64); | |
| 302 | try test__powidf2(0, -4, inf_f64); | |
| 303 | try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64); | |
| 304 | try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f64); | |
| 305 | try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64); | |
| 306 | ||
| 307 | try test__powidf2(-0.0, -1, -inf_f64); | |
| 308 | try test__powidf2(-0.0, -2, inf_f64); | |
| 309 | try test__powidf2(-0.0, -3, -inf_f64); | |
| 310 | try test__powidf2(-0.0, -4, inf_f64); | |
| 311 | try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64); | |
| 312 | try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f64); | |
| 313 | try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64); | |
| 314 | ||
| 315 | try test__powidf2(1, -1, 1); | |
| 316 | try test__powidf2(1, -2, 1); | |
| 317 | try test__powidf2(1, -3, 1); | |
| 318 | try test__powidf2(1, -4, 1); | |
| 319 | try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); | |
| 320 | try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); | |
| 321 | try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); | |
| 322 | ||
| 323 | try test__powidf2(inf_f64, -1, 0); | |
| 324 | try test__powidf2(inf_f64, -2, 0); | |
| 325 | try test__powidf2(inf_f64, -3, 0); | |
| 326 | try test__powidf2(inf_f64, -4, 0); | |
| 327 | try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 328 | try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); | |
| 329 | try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 330 | ||
| 331 | try test__powidf2(-inf_f64, -1, -0.0); | |
| 332 | try test__powidf2(-inf_f64, -2, 0); | |
| 333 | try test__powidf2(-inf_f64, -3, -0.0); | |
| 334 | try test__powidf2(-inf_f64, -4, 0); | |
| 335 | try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 336 | try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); | |
| 337 | try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 338 | ||
| 339 | try test__powidf2(2, 10, 1024.0); | |
| 340 | try test__powidf2(-2, 10, 1024.0); | |
| 341 | try test__powidf2(2, -10, 1.0 / 1024.0); | |
| 342 | try test__powidf2(-2, -10, 1.0 / 1024.0); | |
| 343 | ||
| 344 | try test__powidf2(2, 19, 524288.0); | |
| 345 | try test__powidf2(-2, 19, -524288.0); | |
| 346 | try test__powidf2(2, -19, 1.0 / 524288.0); | |
| 347 | try test__powidf2(-2, -19, -1.0 / 524288.0); | |
| 348 | ||
| 349 | try test__powidf2(2, 31, 2147483648.0); | |
| 350 | try test__powidf2(-2, 31, -2147483648.0); | |
| 351 | try test__powidf2(2, -31, 1.0 / 2147483648.0); | |
| 352 | try test__powidf2(-2, -31, -1.0 / 2147483648.0); | |
| 258 | try test_powi_f64(0, 0, 1); | |
| 259 | try test_powi_f64(1, 0, 1); | |
| 260 | try test_powi_f64(1.5, 0, 1); | |
| 261 | try test_powi_f64(2, 0, 1); | |
| 262 | try test_powi_f64(inf_f64, 0, 1); | |
| 263 | ||
| 264 | try test_powi_f64(-0.0, 0, 1); | |
| 265 | try test_powi_f64(-1, 0, 1); | |
| 266 | try test_powi_f64(-1.5, 0, 1); | |
| 267 | try test_powi_f64(-2, 0, 1); | |
| 268 | try test_powi_f64(-inf_f64, 0, 1); | |
| 269 | ||
| 270 | try test_powi_f64(0, 1, 0); | |
| 271 | try test_powi_f64(0, 2, 0); | |
| 272 | try test_powi_f64(0, 3, 0); | |
| 273 | try test_powi_f64(0, 4, 0); | |
| 274 | try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 275 | try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); | |
| 276 | ||
| 277 | try test_powi_f64(-0.0, 1, -0.0); | |
| 278 | try test_powi_f64(-0.0, 2, 0); | |
| 279 | try test_powi_f64(-0.0, 3, -0.0); | |
| 280 | try test_powi_f64(-0.0, 4, 0); | |
| 281 | try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 282 | try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); | |
| 283 | ||
| 284 | try test_powi_f64(1, 1, 1); | |
| 285 | try test_powi_f64(1, 2, 1); | |
| 286 | try test_powi_f64(1, 3, 1); | |
| 287 | try test_powi_f64(1, 4, 1); | |
| 288 | try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); | |
| 289 | try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); | |
| 290 | ||
| 291 | try test_powi_f64(inf_f64, 1, inf_f64); | |
| 292 | try test_powi_f64(inf_f64, 2, inf_f64); | |
| 293 | try test_powi_f64(inf_f64, 3, inf_f64); | |
| 294 | try test_powi_f64(inf_f64, 4, inf_f64); | |
| 295 | try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64); | |
| 296 | try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f64); | |
| 297 | ||
| 298 | try test_powi_f64(-inf_f64, 1, -inf_f64); | |
| 299 | try test_powi_f64(-inf_f64, 2, inf_f64); | |
| 300 | try test_powi_f64(-inf_f64, 3, -inf_f64); | |
| 301 | try test_powi_f64(-inf_f64, 4, inf_f64); | |
| 302 | try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64); | |
| 303 | try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f64); | |
| 304 | ||
| 305 | try test_powi_f64(0, -1, inf_f64); | |
| 306 | try test_powi_f64(0, -2, inf_f64); | |
| 307 | try test_powi_f64(0, -3, inf_f64); | |
| 308 | try test_powi_f64(0, -4, inf_f64); | |
| 309 | try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64); | |
| 310 | try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f64); | |
| 311 | try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64); | |
| 312 | ||
| 313 | try test_powi_f64(-0.0, -1, -inf_f64); | |
| 314 | try test_powi_f64(-0.0, -2, inf_f64); | |
| 315 | try test_powi_f64(-0.0, -3, -inf_f64); | |
| 316 | try test_powi_f64(-0.0, -4, inf_f64); | |
| 317 | try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64); | |
| 318 | try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f64); | |
| 319 | try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64); | |
| 320 | ||
| 321 | try test_powi_f64(1, -1, 1); | |
| 322 | try test_powi_f64(1, -2, 1); | |
| 323 | try test_powi_f64(1, -3, 1); | |
| 324 | try test_powi_f64(1, -4, 1); | |
| 325 | try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); | |
| 326 | try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); | |
| 327 | try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); | |
| 328 | ||
| 329 | try test_powi_f64(inf_f64, -1, 0); | |
| 330 | try test_powi_f64(inf_f64, -2, 0); | |
| 331 | try test_powi_f64(inf_f64, -3, 0); | |
| 332 | try test_powi_f64(inf_f64, -4, 0); | |
| 333 | try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 334 | try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); | |
| 335 | try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 336 | ||
| 337 | try test_powi_f64(-inf_f64, -1, -0.0); | |
| 338 | try test_powi_f64(-inf_f64, -2, 0); | |
| 339 | try test_powi_f64(-inf_f64, -3, -0.0); | |
| 340 | try test_powi_f64(-inf_f64, -4, 0); | |
| 341 | try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 342 | try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); | |
| 343 | try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 344 | ||
| 345 | try test_powi_f64(2, 10, 1024.0); | |
| 346 | try test_powi_f64(-2, 10, 1024.0); | |
| 347 | try test_powi_f64(2, -10, 1.0 / 1024.0); | |
| 348 | try test_powi_f64(-2, -10, 1.0 / 1024.0); | |
| 349 | ||
| 350 | try test_powi_f64(2, 19, 524288.0); | |
| 351 | try test_powi_f64(-2, 19, -524288.0); | |
| 352 | try test_powi_f64(2, -19, 1.0 / 524288.0); | |
| 353 | try test_powi_f64(-2, -19, -1.0 / 524288.0); | |
| 354 | ||
| 355 | try test_powi_f64(2, 31, 2147483648.0); | |
| 356 | try test_powi_f64(-2, 31, -2147483648.0); | |
| 357 | try test_powi_f64(2, -31, 1.0 / 2147483648.0); | |
| 358 | try test_powi_f64(-2, -31, -1.0 / 2147483648.0); | |
| 353 | 359 | } |
| 354 | 360 | |
| 355 | test "powitf2" { | |
| 356 | const inf_f128 = math.inf(f128); | |
| 357 | try test__powitf2(0, 0, 1); | |
| 358 | try test__powitf2(1, 0, 1); | |
| 359 | try test__powitf2(1.5, 0, 1); | |
| 360 | try test__powitf2(2, 0, 1); | |
| 361 | try test__powitf2(inf_f128, 0, 1); | |
| 362 | ||
| 363 | try test__powitf2(-0.0, 0, 1); | |
| 364 | try test__powitf2(-1, 0, 1); | |
| 365 | try test__powitf2(-1.5, 0, 1); | |
| 366 | try test__powitf2(-2, 0, 1); | |
| 367 | try test__powitf2(-inf_f128, 0, 1); | |
| 368 | ||
| 369 | try test__powitf2(0, 1, 0); | |
| 370 | try test__powitf2(0, 2, 0); | |
| 371 | try test__powitf2(0, 3, 0); | |
| 372 | try test__powitf2(0, 4, 0); | |
| 373 | try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 374 | try test__powitf2(0, 0x7FFFFFFF, 0); | |
| 375 | ||
| 376 | try test__powitf2(-0.0, 1, -0.0); | |
| 377 | try test__powitf2(-0.0, 2, 0); | |
| 378 | try test__powitf2(-0.0, 3, -0.0); | |
| 379 | try test__powitf2(-0.0, 4, 0); | |
| 380 | try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 381 | try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); | |
| 382 | ||
| 383 | try test__powitf2(1, 1, 1); | |
| 384 | try test__powitf2(1, 2, 1); | |
| 385 | try test__powitf2(1, 3, 1); | |
| 386 | try test__powitf2(1, 4, 1); | |
| 387 | try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); | |
| 388 | try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); | |
| 389 | ||
| 390 | try test__powitf2(inf_f128, 1, inf_f128); | |
| 391 | try test__powitf2(inf_f128, 2, inf_f128); | |
| 392 | try test__powitf2(inf_f128, 3, inf_f128); | |
| 393 | try test__powitf2(inf_f128, 4, inf_f128); | |
| 394 | try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128); | |
| 395 | try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f128); | |
| 396 | ||
| 397 | try test__powitf2(-inf_f128, 1, -inf_f128); | |
| 398 | try test__powitf2(-inf_f128, 2, inf_f128); | |
| 399 | try test__powitf2(-inf_f128, 3, -inf_f128); | |
| 400 | try test__powitf2(-inf_f128, 4, inf_f128); | |
| 401 | try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128); | |
| 402 | try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f128); | |
| 403 | ||
| 404 | try test__powitf2(0, -1, inf_f128); | |
| 405 | try test__powitf2(0, -2, inf_f128); | |
| 406 | try test__powitf2(0, -3, inf_f128); | |
| 407 | try test__powitf2(0, -4, inf_f128); | |
| 408 | try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128); | |
| 409 | try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f128); | |
| 410 | try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128); | |
| 411 | ||
| 412 | try test__powitf2(-0.0, -1, -inf_f128); | |
| 413 | try test__powitf2(-0.0, -2, inf_f128); | |
| 414 | try test__powitf2(-0.0, -3, -inf_f128); | |
| 415 | try test__powitf2(-0.0, -4, inf_f128); | |
| 416 | try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128); | |
| 417 | try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f128); | |
| 418 | try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128); | |
| 419 | ||
| 420 | try test__powitf2(1, -1, 1); | |
| 421 | try test__powitf2(1, -2, 1); | |
| 422 | try test__powitf2(1, -3, 1); | |
| 423 | try test__powitf2(1, -4, 1); | |
| 424 | try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); | |
| 425 | try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); | |
| 426 | try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); | |
| 427 | ||
| 428 | try test__powitf2(inf_f128, -1, 0); | |
| 429 | try test__powitf2(inf_f128, -2, 0); | |
| 430 | try test__powitf2(inf_f128, -3, 0); | |
| 431 | try test__powitf2(inf_f128, -4, 0); | |
| 432 | try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 433 | try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); | |
| 434 | try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 435 | ||
| 436 | try test__powitf2(-inf_f128, -1, -0.0); | |
| 437 | try test__powitf2(-inf_f128, -2, 0); | |
| 438 | try test__powitf2(-inf_f128, -3, -0.0); | |
| 439 | try test__powitf2(-inf_f128, -4, 0); | |
| 440 | try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 441 | try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); | |
| 442 | try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 443 | ||
| 444 | try test__powitf2(2, 10, 1024.0); | |
| 445 | try test__powitf2(-2, 10, 1024.0); | |
| 446 | try test__powitf2(2, -10, 1.0 / 1024.0); | |
| 447 | try test__powitf2(-2, -10, 1.0 / 1024.0); | |
| 448 | ||
| 449 | try test__powitf2(2, 19, 524288.0); | |
| 450 | try test__powitf2(-2, 19, -524288.0); | |
| 451 | try test__powitf2(2, -19, 1.0 / 524288.0); | |
| 452 | try test__powitf2(-2, -19, -1.0 / 524288.0); | |
| 453 | ||
| 454 | try test__powitf2(2, 31, 2147483648.0); | |
| 455 | try test__powitf2(-2, 31, -2147483648.0); | |
| 456 | try test__powitf2(2, -31, 1.0 / 2147483648.0); | |
| 457 | try test__powitf2(-2, -31, -1.0 / 2147483648.0); | |
| 361 | test powi_f80 { | |
| 362 | const inf_f80 = math.inf(f80); | |
| 363 | try test_powi_f80(0, 0, 1); | |
| 364 | try test_powi_f80(1, 0, 1); | |
| 365 | try test_powi_f80(1.5, 0, 1); | |
| 366 | try test_powi_f80(2, 0, 1); | |
| 367 | try test_powi_f80(inf_f80, 0, 1); | |
| 368 | ||
| 369 | try test_powi_f80(-0.0, 0, 1); | |
| 370 | try test_powi_f80(-1, 0, 1); | |
| 371 | try test_powi_f80(-1.5, 0, 1); | |
| 372 | try test_powi_f80(-2, 0, 1); | |
| 373 | try test_powi_f80(-inf_f80, 0, 1); | |
| 374 | ||
| 375 | try test_powi_f80(0, 1, 0); | |
| 376 | try test_powi_f80(0, 2, 0); | |
| 377 | try test_powi_f80(0, 3, 0); | |
| 378 | try test_powi_f80(0, 4, 0); | |
| 379 | try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 380 | try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); | |
| 381 | ||
| 382 | try test_powi_f80(-0.0, 1, -0.0); | |
| 383 | try test_powi_f80(-0.0, 2, 0); | |
| 384 | try test_powi_f80(-0.0, 3, -0.0); | |
| 385 | try test_powi_f80(-0.0, 4, 0); | |
| 386 | try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 387 | try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); | |
| 388 | ||
| 389 | try test_powi_f80(1, 1, 1); | |
| 390 | try test_powi_f80(1, 2, 1); | |
| 391 | try test_powi_f80(1, 3, 1); | |
| 392 | try test_powi_f80(1, 4, 1); | |
| 393 | try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); | |
| 394 | try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); | |
| 395 | ||
| 396 | try test_powi_f80(inf_f80, 1, inf_f80); | |
| 397 | try test_powi_f80(inf_f80, 2, inf_f80); | |
| 398 | try test_powi_f80(inf_f80, 3, inf_f80); | |
| 399 | try test_powi_f80(inf_f80, 4, inf_f80); | |
| 400 | try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80); | |
| 401 | try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f80); | |
| 402 | ||
| 403 | try test_powi_f80(-inf_f80, 1, -inf_f80); | |
| 404 | try test_powi_f80(-inf_f80, 2, inf_f80); | |
| 405 | try test_powi_f80(-inf_f80, 3, -inf_f80); | |
| 406 | try test_powi_f80(-inf_f80, 4, inf_f80); | |
| 407 | try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80); | |
| 408 | try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f80); | |
| 409 | ||
| 410 | try test_powi_f80(0, -1, inf_f80); | |
| 411 | try test_powi_f80(0, -2, inf_f80); | |
| 412 | try test_powi_f80(0, -3, inf_f80); | |
| 413 | try test_powi_f80(0, -4, inf_f80); | |
| 414 | try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80); | |
| 415 | try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f80); | |
| 416 | try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80); | |
| 417 | ||
| 418 | try test_powi_f80(-0.0, -1, -inf_f80); | |
| 419 | try test_powi_f80(-0.0, -2, inf_f80); | |
| 420 | try test_powi_f80(-0.0, -3, -inf_f80); | |
| 421 | try test_powi_f80(-0.0, -4, inf_f80); | |
| 422 | try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80); | |
| 423 | try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f80); | |
| 424 | try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80); | |
| 425 | ||
| 426 | try test_powi_f80(1, -1, 1); | |
| 427 | try test_powi_f80(1, -2, 1); | |
| 428 | try test_powi_f80(1, -3, 1); | |
| 429 | try test_powi_f80(1, -4, 1); | |
| 430 | try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); | |
| 431 | try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); | |
| 432 | try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); | |
| 433 | ||
| 434 | try test_powi_f80(inf_f80, -1, 0); | |
| 435 | try test_powi_f80(inf_f80, -2, 0); | |
| 436 | try test_powi_f80(inf_f80, -3, 0); | |
| 437 | try test_powi_f80(inf_f80, -4, 0); | |
| 438 | try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 439 | try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); | |
| 440 | try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 441 | ||
| 442 | try test_powi_f80(-inf_f80, -1, -0.0); | |
| 443 | try test_powi_f80(-inf_f80, -2, 0); | |
| 444 | try test_powi_f80(-inf_f80, -3, -0.0); | |
| 445 | try test_powi_f80(-inf_f80, -4, 0); | |
| 446 | try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 447 | try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); | |
| 448 | try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 449 | ||
| 450 | try test_powi_f80(2, 10, 1024.0); | |
| 451 | try test_powi_f80(-2, 10, 1024.0); | |
| 452 | try test_powi_f80(2, -10, 1.0 / 1024.0); | |
| 453 | try test_powi_f80(-2, -10, 1.0 / 1024.0); | |
| 454 | ||
| 455 | try test_powi_f80(2, 19, 524288.0); | |
| 456 | try test_powi_f80(-2, 19, -524288.0); | |
| 457 | try test_powi_f80(2, -19, 1.0 / 524288.0); | |
| 458 | try test_powi_f80(-2, -19, -1.0 / 524288.0); | |
| 459 | ||
| 460 | try test_powi_f80(2, 31, 2147483648.0); | |
| 461 | try test_powi_f80(-2, 31, -2147483648.0); | |
| 462 | try test_powi_f80(2, -31, 1.0 / 2147483648.0); | |
| 463 | try test_powi_f80(-2, -31, -1.0 / 2147483648.0); | |
| 458 | 464 | } |
| 459 | 465 | |
| 460 | test "powixf2" { | |
| 461 | const inf_f80 = math.inf(f80); | |
| 462 | try test__powixf2(0, 0, 1); | |
| 463 | try test__powixf2(1, 0, 1); | |
| 464 | try test__powixf2(1.5, 0, 1); | |
| 465 | try test__powixf2(2, 0, 1); | |
| 466 | try test__powixf2(inf_f80, 0, 1); | |
| 467 | ||
| 468 | try test__powixf2(-0.0, 0, 1); | |
| 469 | try test__powixf2(-1, 0, 1); | |
| 470 | try test__powixf2(-1.5, 0, 1); | |
| 471 | try test__powixf2(-2, 0, 1); | |
| 472 | try test__powixf2(-inf_f80, 0, 1); | |
| 473 | ||
| 474 | try test__powixf2(0, 1, 0); | |
| 475 | try test__powixf2(0, 2, 0); | |
| 476 | try test__powixf2(0, 3, 0); | |
| 477 | try test__powixf2(0, 4, 0); | |
| 478 | try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 479 | try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); | |
| 480 | ||
| 481 | try test__powixf2(-0.0, 1, -0.0); | |
| 482 | try test__powixf2(-0.0, 2, 0); | |
| 483 | try test__powixf2(-0.0, 3, -0.0); | |
| 484 | try test__powixf2(-0.0, 4, 0); | |
| 485 | try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 486 | try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); | |
| 487 | ||
| 488 | try test__powixf2(1, 1, 1); | |
| 489 | try test__powixf2(1, 2, 1); | |
| 490 | try test__powixf2(1, 3, 1); | |
| 491 | try test__powixf2(1, 4, 1); | |
| 492 | try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); | |
| 493 | try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); | |
| 494 | ||
| 495 | try test__powixf2(inf_f80, 1, inf_f80); | |
| 496 | try test__powixf2(inf_f80, 2, inf_f80); | |
| 497 | try test__powixf2(inf_f80, 3, inf_f80); | |
| 498 | try test__powixf2(inf_f80, 4, inf_f80); | |
| 499 | try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80); | |
| 500 | try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f80); | |
| 501 | ||
| 502 | try test__powixf2(-inf_f80, 1, -inf_f80); | |
| 503 | try test__powixf2(-inf_f80, 2, inf_f80); | |
| 504 | try test__powixf2(-inf_f80, 3, -inf_f80); | |
| 505 | try test__powixf2(-inf_f80, 4, inf_f80); | |
| 506 | try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80); | |
| 507 | try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f80); | |
| 508 | ||
| 509 | try test__powixf2(0, -1, inf_f80); | |
| 510 | try test__powixf2(0, -2, inf_f80); | |
| 511 | try test__powixf2(0, -3, inf_f80); | |
| 512 | try test__powixf2(0, -4, inf_f80); | |
| 513 | try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80); | |
| 514 | try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f80); | |
| 515 | try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80); | |
| 516 | ||
| 517 | try test__powixf2(-0.0, -1, -inf_f80); | |
| 518 | try test__powixf2(-0.0, -2, inf_f80); | |
| 519 | try test__powixf2(-0.0, -3, -inf_f80); | |
| 520 | try test__powixf2(-0.0, -4, inf_f80); | |
| 521 | try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80); | |
| 522 | try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f80); | |
| 523 | try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80); | |
| 524 | ||
| 525 | try test__powixf2(1, -1, 1); | |
| 526 | try test__powixf2(1, -2, 1); | |
| 527 | try test__powixf2(1, -3, 1); | |
| 528 | try test__powixf2(1, -4, 1); | |
| 529 | try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); | |
| 530 | try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); | |
| 531 | try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); | |
| 532 | ||
| 533 | try test__powixf2(inf_f80, -1, 0); | |
| 534 | try test__powixf2(inf_f80, -2, 0); | |
| 535 | try test__powixf2(inf_f80, -3, 0); | |
| 536 | try test__powixf2(inf_f80, -4, 0); | |
| 537 | try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 538 | try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); | |
| 539 | try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 540 | ||
| 541 | try test__powixf2(-inf_f80, -1, -0.0); | |
| 542 | try test__powixf2(-inf_f80, -2, 0); | |
| 543 | try test__powixf2(-inf_f80, -3, -0.0); | |
| 544 | try test__powixf2(-inf_f80, -4, 0); | |
| 545 | try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 546 | try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); | |
| 547 | try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 548 | ||
| 549 | try test__powixf2(2, 10, 1024.0); | |
| 550 | try test__powixf2(-2, 10, 1024.0); | |
| 551 | try test__powixf2(2, -10, 1.0 / 1024.0); | |
| 552 | try test__powixf2(-2, -10, 1.0 / 1024.0); | |
| 553 | ||
| 554 | try test__powixf2(2, 19, 524288.0); | |
| 555 | try test__powixf2(-2, 19, -524288.0); | |
| 556 | try test__powixf2(2, -19, 1.0 / 524288.0); | |
| 557 | try test__powixf2(-2, -19, -1.0 / 524288.0); | |
| 558 | ||
| 559 | try test__powixf2(2, 31, 2147483648.0); | |
| 560 | try test__powixf2(-2, 31, -2147483648.0); | |
| 561 | try test__powixf2(2, -31, 1.0 / 2147483648.0); | |
| 562 | try test__powixf2(-2, -31, -1.0 / 2147483648.0); | |
| 466 | test powi_f128 { | |
| 467 | const inf_f128 = math.inf(f128); | |
| 468 | try test_powi_f128(0, 0, 1); | |
| 469 | try test_powi_f128(1, 0, 1); | |
| 470 | try test_powi_f128(1.5, 0, 1); | |
| 471 | try test_powi_f128(2, 0, 1); | |
| 472 | try test_powi_f128(inf_f128, 0, 1); | |
| 473 | ||
| 474 | try test_powi_f128(-0.0, 0, 1); | |
| 475 | try test_powi_f128(-1, 0, 1); | |
| 476 | try test_powi_f128(-1.5, 0, 1); | |
| 477 | try test_powi_f128(-2, 0, 1); | |
| 478 | try test_powi_f128(-inf_f128, 0, 1); | |
| 479 | ||
| 480 | try test_powi_f128(0, 1, 0); | |
| 481 | try test_powi_f128(0, 2, 0); | |
| 482 | try test_powi_f128(0, 3, 0); | |
| 483 | try test_powi_f128(0, 4, 0); | |
| 484 | try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 485 | try test_powi_f128(0, 0x7FFFFFFF, 0); | |
| 486 | ||
| 487 | try test_powi_f128(-0.0, 1, -0.0); | |
| 488 | try test_powi_f128(-0.0, 2, 0); | |
| 489 | try test_powi_f128(-0.0, 3, -0.0); | |
| 490 | try test_powi_f128(-0.0, 4, 0); | |
| 491 | try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); | |
| 492 | try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); | |
| 493 | ||
| 494 | try test_powi_f128(1, 1, 1); | |
| 495 | try test_powi_f128(1, 2, 1); | |
| 496 | try test_powi_f128(1, 3, 1); | |
| 497 | try test_powi_f128(1, 4, 1); | |
| 498 | try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); | |
| 499 | try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); | |
| 500 | ||
| 501 | try test_powi_f128(inf_f128, 1, inf_f128); | |
| 502 | try test_powi_f128(inf_f128, 2, inf_f128); | |
| 503 | try test_powi_f128(inf_f128, 3, inf_f128); | |
| 504 | try test_powi_f128(inf_f128, 4, inf_f128); | |
| 505 | try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128); | |
| 506 | try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f128); | |
| 507 | ||
| 508 | try test_powi_f128(-inf_f128, 1, -inf_f128); | |
| 509 | try test_powi_f128(-inf_f128, 2, inf_f128); | |
| 510 | try test_powi_f128(-inf_f128, 3, -inf_f128); | |
| 511 | try test_powi_f128(-inf_f128, 4, inf_f128); | |
| 512 | try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128); | |
| 513 | try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f128); | |
| 514 | ||
| 515 | try test_powi_f128(0, -1, inf_f128); | |
| 516 | try test_powi_f128(0, -2, inf_f128); | |
| 517 | try test_powi_f128(0, -3, inf_f128); | |
| 518 | try test_powi_f128(0, -4, inf_f128); | |
| 519 | try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128); | |
| 520 | try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f128); | |
| 521 | try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128); | |
| 522 | ||
| 523 | try test_powi_f128(-0.0, -1, -inf_f128); | |
| 524 | try test_powi_f128(-0.0, -2, inf_f128); | |
| 525 | try test_powi_f128(-0.0, -3, -inf_f128); | |
| 526 | try test_powi_f128(-0.0, -4, inf_f128); | |
| 527 | try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128); | |
| 528 | try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f128); | |
| 529 | try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128); | |
| 530 | ||
| 531 | try test_powi_f128(1, -1, 1); | |
| 532 | try test_powi_f128(1, -2, 1); | |
| 533 | try test_powi_f128(1, -3, 1); | |
| 534 | try test_powi_f128(1, -4, 1); | |
| 535 | try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); | |
| 536 | try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); | |
| 537 | try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); | |
| 538 | ||
| 539 | try test_powi_f128(inf_f128, -1, 0); | |
| 540 | try test_powi_f128(inf_f128, -2, 0); | |
| 541 | try test_powi_f128(inf_f128, -3, 0); | |
| 542 | try test_powi_f128(inf_f128, -4, 0); | |
| 543 | try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 544 | try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); | |
| 545 | try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 546 | ||
| 547 | try test_powi_f128(-inf_f128, -1, -0.0); | |
| 548 | try test_powi_f128(-inf_f128, -2, 0); | |
| 549 | try test_powi_f128(-inf_f128, -3, -0.0); | |
| 550 | try test_powi_f128(-inf_f128, -4, 0); | |
| 551 | try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); | |
| 552 | try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); | |
| 553 | try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); | |
| 554 | ||
| 555 | try test_powi_f128(2, 10, 1024.0); | |
| 556 | try test_powi_f128(-2, 10, 1024.0); | |
| 557 | try test_powi_f128(2, -10, 1.0 / 1024.0); | |
| 558 | try test_powi_f128(-2, -10, 1.0 / 1024.0); | |
| 559 | ||
| 560 | try test_powi_f128(2, 19, 524288.0); | |
| 561 | try test_powi_f128(-2, 19, -524288.0); | |
| 562 | try test_powi_f128(2, -19, 1.0 / 524288.0); | |
| 563 | try test_powi_f128(-2, -19, -1.0 / 524288.0); | |
| 564 | ||
| 565 | try test_powi_f128(2, 31, 2147483648.0); | |
| 566 | try test_powi_f128(-2, 31, -2147483648.0); | |
| 567 | try test_powi_f128(2, -31, 1.0 / 2147483648.0); | |
| 568 | try test_powi_f128(-2, -31, -1.0 / 2147483648.0); | |
| 563 | 569 | } |
lib/compiler_rt/round.zig+87-49| ... | ... | @@ -18,19 +18,23 @@ comptime { |
| 18 | 18 | symbol(&roundf, "roundf"); |
| 19 | 19 | symbol(&round, "round"); |
| 20 | 20 | symbol(&__roundx, "__roundx"); |
| 21 | if (compiler_rt.want_ppc_abi) { | |
| 22 | symbol(&roundq, "roundf128"); | |
| 23 | } | |
| 21 | if (compiler_rt.want_ppc_abi) symbol(&roundq, "roundf128"); | |
| 24 | 22 | symbol(&roundq, "roundq"); |
| 25 | 23 | symbol(&roundl, "roundl"); |
| 26 | 24 | } |
| 27 | 25 | |
| 28 | pub fn __roundh(x: f16) callconv(.c) f16 { | |
| 26 | fn __roundh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 27 | return compiler_rt.f16.toAbi(round_f16(compiler_rt.f16.fromAbi(x))); | |
| 28 | } | |
| 29 | pub fn round_f16(x: f16) f16 { | |
| 29 | 30 | // TODO: more efficient implementation |
| 30 | return @floatCast(roundf(x)); | |
| 31 | return @floatCast(round_f32(x)); | |
| 31 | 32 | } |
| 32 | 33 | |
| 33 | pub fn roundf(x_: f32) callconv(.c) f32 { | |
| 34 | fn roundf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 35 | return compiler_rt.f32.toAbi(round_f32(compiler_rt.f32.fromAbi(x))); | |
| 36 | } | |
| 37 | pub fn round_f32(x_: f32) f32 { | |
| 34 | 38 | const f32_toint = 1.0 / math.floatEps(f32); |
| 35 | 39 | |
| 36 | 40 | var x = x_; |
| ... | ... | @@ -65,7 +69,10 @@ pub fn roundf(x_: f32) callconv(.c) f32 { |
| 65 | 69 | } |
| 66 | 70 | } |
| 67 | 71 | |
| 68 | pub fn round(x_: f64) callconv(.c) f64 { | |
| 72 | fn round(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 73 | return compiler_rt.f64.toAbi(round_f64(compiler_rt.f64.fromAbi(x))); | |
| 74 | } | |
| 75 | pub fn round_f64(x_: f64) f64 { | |
| 69 | 76 | const f64_toint = 1.0 / math.floatEps(f64); |
| 70 | 77 | |
| 71 | 78 | var x = x_; |
| ... | ... | @@ -100,12 +107,18 @@ pub fn round(x_: f64) callconv(.c) f64 { |
| 100 | 107 | } |
| 101 | 108 | } |
| 102 | 109 | |
| 103 | pub fn __roundx(x: f80) callconv(.c) f80 { | |
| 110 | fn __roundx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 111 | return compiler_rt.f80.toAbi(round_f80(compiler_rt.f80.fromAbi(x))); | |
| 112 | } | |
| 113 | pub fn round_f80(x: f80) f80 { | |
| 104 | 114 | // TODO: more efficient implementation |
| 105 | return @floatCast(roundq(x)); | |
| 115 | return @floatCast(round_f128(x)); | |
| 106 | 116 | } |
| 107 | 117 | |
| 108 | pub fn roundq(x_: f128) callconv(.c) f128 { | |
| 118 | fn roundq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 119 | return compiler_rt.f128.toAbi(round_f128(compiler_rt.f128.fromAbi(x))); | |
| 120 | } | |
| 121 | pub fn round_f128(x_: f128) f128 { | |
| 109 | 122 | const f128_toint = 1.0 / math.floatEps(f128); |
| 110 | 123 | |
| 111 | 124 | var x = x_; |
| ... | ... | @@ -142,54 +155,79 @@ pub fn roundq(x_: f128) callconv(.c) f128 { |
| 142 | 155 | |
| 143 | 156 | pub fn roundl(x: c_longdouble) callconv(.c) c_longdouble { |
| 144 | 157 | switch (@typeInfo(c_longdouble).float.bits) { |
| 145 | 64 => return round(x), | |
| 146 | 80 => return __roundx(x), | |
| 147 | 128 => return roundq(x), | |
| 148 | else => @compileError("unreachable"), | |
| 158 | 64 => return round_f64(x), | |
| 159 | 80 => return round_f80(x), | |
| 160 | 128 => return round_f128(x), | |
| 161 | else => comptime unreachable, | |
| 149 | 162 | } |
| 150 | 163 | } |
| 151 | 164 | |
| 152 | test "round32" { | |
| 153 | try expect(roundf(1.3) == 1.0); | |
| 154 | try expect(roundf(-1.3) == -1.0); | |
| 155 | try expect(roundf(0.2) == 0.0); | |
| 156 | try expect(roundf(1.8) == 2.0); | |
| 157 | } | |
| 158 | ||
| 159 | test "round64" { | |
| 160 | try expect(round(1.3) == 1.0); | |
| 161 | try expect(round(-1.3) == -1.0); | |
| 162 | try expect(round(0.2) == 0.0); | |
| 163 | try expect(round(1.8) == 2.0); | |
| 165 | test round_f16 { | |
| 166 | try expect(round_f16(1.3) == 1.0); | |
| 167 | try expect(round_f16(-1.3) == -1.0); | |
| 168 | try expect(round_f16(1.8) == 2.0); | |
| 169 | try expect(round_f16(-1.8) == -2.0); | |
| 170 | try expect(math.isPositiveZero(round_f16(0.2))); | |
| 171 | try expect(math.isNegativeZero(round_f16(-0.2))); | |
| 172 | try expect(math.isPositiveZero(round_f16(0.0))); | |
| 173 | try expect(math.isNegativeZero(round_f16(-0.0))); | |
| 174 | try expect(math.isPositiveInf(round_f16(math.inf(f32)))); | |
| 175 | try expect(math.isNegativeInf(round_f16(-math.inf(f32)))); | |
| 176 | try expect(math.isNan(round_f16(math.nan(f32)))); | |
| 164 | 177 | } |
| 165 | 178 | |
| 166 | test "round128" { | |
| 167 | try expect(roundq(1.3) == 1.0); | |
| 168 | try expect(roundq(-1.3) == -1.0); | |
| 169 | try expect(roundq(0.2) == 0.0); | |
| 170 | try expect(roundq(1.8) == 2.0); | |
| 179 | test round_f32 { | |
| 180 | try expect(round_f32(1.3) == 1.0); | |
| 181 | try expect(round_f32(-1.3) == -1.0); | |
| 182 | try expect(round_f32(1.8) == 2.0); | |
| 183 | try expect(round_f32(-1.8) == -2.0); | |
| 184 | try expect(math.isPositiveZero(round_f32(0.2))); | |
| 185 | try expect(math.isNegativeZero(round_f32(-0.2))); | |
| 186 | try expect(math.isPositiveZero(round_f32(0.0))); | |
| 187 | try expect(math.isNegativeZero(round_f32(-0.0))); | |
| 188 | try expect(math.isPositiveInf(round_f32(math.inf(f32)))); | |
| 189 | try expect(math.isNegativeInf(round_f32(-math.inf(f32)))); | |
| 190 | try expect(math.isNan(round_f32(math.nan(f32)))); | |
| 171 | 191 | } |
| 172 | 192 | |
| 173 | test "round32.special" { | |
| 174 | try expect(roundf(0.0) == 0.0); | |
| 175 | try expect(roundf(-0.0) == -0.0); | |
| 176 | try expect(math.isPositiveInf(roundf(math.inf(f32)))); | |
| 177 | try expect(math.isNegativeInf(roundf(-math.inf(f32)))); | |
| 178 | try expect(math.isNan(roundf(math.nan(f32)))); | |
| 193 | test round_f64 { | |
| 194 | try expect(round_f64(1.3) == 1.0); | |
| 195 | try expect(round_f64(-1.3) == -1.0); | |
| 196 | try expect(round_f64(1.8) == 2.0); | |
| 197 | try expect(round_f64(-1.8) == -2.0); | |
| 198 | try expect(math.isPositiveZero(round_f64(0.2))); | |
| 199 | try expect(math.isNegativeZero(round_f64(-0.2))); | |
| 200 | try expect(math.isPositiveZero(round_f64(0.0))); | |
| 201 | try expect(math.isNegativeZero(round_f64(-0.0))); | |
| 202 | try expect(math.isPositiveInf(round_f64(math.inf(f64)))); | |
| 203 | try expect(math.isNegativeInf(round_f64(-math.inf(f64)))); | |
| 204 | try expect(math.isNan(round_f64(math.nan(f64)))); | |
| 179 | 205 | } |
| 180 | 206 | |
| 181 | test "round64.special" { | |
| 182 | try expect(round(0.0) == 0.0); | |
| 183 | try expect(round(-0.0) == -0.0); | |
| 184 | try expect(math.isPositiveInf(round(math.inf(f64)))); | |
| 185 | try expect(math.isNegativeInf(round(-math.inf(f64)))); | |
| 186 | try expect(math.isNan(round(math.nan(f64)))); | |
| 207 | test round_f80 { | |
| 208 | try expect(round_f80(1.3) == 1.0); | |
| 209 | try expect(round_f80(-1.3) == -1.0); | |
| 210 | try expect(round_f80(1.8) == 2.0); | |
| 211 | try expect(round_f80(-1.8) == -2.0); | |
| 212 | try expect(math.isPositiveZero(round_f80(0.2))); | |
| 213 | try expect(math.isNegativeZero(round_f80(-0.2))); | |
| 214 | try expect(math.isPositiveZero(round_f80(0.0))); | |
| 215 | try expect(math.isNegativeZero(round_f80(-0.0))); | |
| 216 | try expect(math.isPositiveInf(round_f80(math.inf(f64)))); | |
| 217 | try expect(math.isNegativeInf(round_f80(-math.inf(f64)))); | |
| 218 | try expect(math.isNan(round_f80(math.nan(f64)))); | |
| 187 | 219 | } |
| 188 | 220 | |
| 189 | test "round128.special" { | |
| 190 | try expect(roundq(0.0) == 0.0); | |
| 191 | try expect(roundq(-0.0) == -0.0); | |
| 192 | try expect(math.isPositiveInf(roundq(math.inf(f128)))); | |
| 193 | try expect(math.isNegativeInf(roundq(-math.inf(f128)))); | |
| 194 | try expect(math.isNan(roundq(math.nan(f128)))); | |
| 221 | test round_f128 { | |
| 222 | try expect(round_f128(1.3) == 1.0); | |
| 223 | try expect(round_f128(-1.3) == -1.0); | |
| 224 | try expect(round_f128(1.8) == 2.0); | |
| 225 | try expect(round_f128(-1.8) == -2.0); | |
| 226 | try expect(math.isPositiveZero(round_f128(0.2))); | |
| 227 | try expect(math.isNegativeZero(round_f128(-0.2))); | |
| 228 | try expect(math.isPositiveZero(round_f128(0.0))); | |
| 229 | try expect(math.isNegativeZero(round_f128(-0.0))); | |
| 230 | try expect(math.isPositiveInf(round_f128(math.inf(f128)))); | |
| 231 | try expect(math.isNegativeInf(round_f128(-math.inf(f128)))); | |
| 232 | try expect(math.isNan(round_f128(math.nan(f128)))); | |
| 195 | 233 | } |
lib/compiler_rt/sin.zig+65-49| ... | ... | @@ -13,31 +13,37 @@ const expect = std.testing.expect; |
| 13 | 13 | const expectApproxEqAbs = std.testing.expectApproxEqAbs; |
| 14 | 14 | |
| 15 | 15 | const compiler_rt = @import("../compiler_rt.zig"); |
| 16 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 16 | const symbol = compiler_rt.symbol; | |
| 17 | 17 | const trig = @import("trig.zig"); |
| 18 | 18 | const rem_pio2 = @import("rem_pio2.zig").rem_pio2; |
| 19 | 19 | const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; |
| 20 | 20 | const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; |
| 21 | 21 | |
| 22 | 22 | comptime { |
| 23 | symbol(&sinh, "__sinh"); | |
| 24 | symbol(&sinl, "__sinl"); | |
| 23 | symbol(&__sinh, "__sinh"); | |
| 25 | 24 | symbol(&sinf, "sinf"); |
| 26 | 25 | symbol(&sin, "sin"); |
| 27 | symbol(&sinx, "__sinx"); | |
| 26 | symbol(&__sinx, "__sinx"); | |
| 28 | 27 | if (compiler_rt.want_ppc_abi) { |
| 29 | 28 | symbol(&sinq, "sinf128"); |
| 30 | 29 | } |
| 31 | 30 | symbol(&sinq, "sinq"); |
| 32 | 31 | symbol(&sinl, "sinl"); |
| 32 | symbol(&sinl, "__sinl"); // required by musl | |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | pub fn sinh(x: f16) callconv(.c) f16 { | |
| 35 | fn __sinh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 36 | return compiler_rt.f16.toAbi(sin_f16(compiler_rt.f16.fromAbi(x))); | |
| 37 | } | |
| 38 | pub fn sin_f16(x: f16) f16 { | |
| 36 | 39 | // TODO: more efficient implementation |
| 37 | return @floatCast(sinf(x)); | |
| 40 | return @floatCast(sin_f32(x)); | |
| 38 | 41 | } |
| 39 | 42 | |
| 40 | pub fn sinf(x: f32) callconv(.c) f32 { | |
| 43 | fn sinf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 44 | return compiler_rt.f32.toAbi(sin_f32(compiler_rt.f32.fromAbi(x))); | |
| 45 | } | |
| 46 | pub fn sin_f32(x: f32) f32 { | |
| 41 | 47 | // Small multiples of pi/2 rounded to double precision. |
| 42 | 48 | const s1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 |
| 43 | 49 | const s2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 |
| ... | ... | @@ -98,7 +104,10 @@ pub fn sinf(x: f32) callconv(.c) f32 { |
| 98 | 104 | }; |
| 99 | 105 | } |
| 100 | 106 | |
| 101 | pub fn sin(x: f64) callconv(.c) f64 { | |
| 107 | fn sin(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 108 | return compiler_rt.f64.toAbi(sin_f64(compiler_rt.f64.fromAbi(x))); | |
| 109 | } | |
| 110 | pub fn sin_f64(x: f64) f64 { | |
| 102 | 111 | var ix = @as(u64, @bitCast(x)) >> 32; |
| 103 | 112 | ix &= 0x7fffffff; |
| 104 | 113 | |
| ... | ... | @@ -133,7 +142,10 @@ pub fn sin(x: f64) callconv(.c) f64 { |
| 133 | 142 | }; |
| 134 | 143 | } |
| 135 | 144 | |
| 136 | fn sinx(x: f80) callconv(.c) f80 { | |
| 145 | fn __sinx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 146 | return compiler_rt.f80.toAbi(sin_f80(compiler_rt.f80.fromAbi(x))); | |
| 147 | } | |
| 148 | pub fn sin_f80(x: f80) f80 { | |
| 137 | 149 | const se = ld.signExponent(x) & 0x7fff; |
| 138 | 150 | if (se == 0x7fff) { |
| 139 | 151 | return x - x; |
| ... | ... | @@ -160,7 +172,10 @@ fn sinx(x: f80) callconv(.c) f80 { |
| 160 | 172 | }; |
| 161 | 173 | } |
| 162 | 174 | |
| 163 | pub fn sinq(x: f128) callconv(.c) f128 { | |
| 175 | fn sinq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 176 | return compiler_rt.f128.toAbi(sin_f128(compiler_rt.f128.fromAbi(x))); | |
| 177 | } | |
| 178 | pub fn sin_f128(x: f128) f128 { | |
| 164 | 179 | const se = ld.signExponent(x) & 0x7fff; |
| 165 | 180 | if (se == 0x7fff) { |
| 166 | 181 | return x - x; |
| ... | ... | @@ -189,20 +204,21 @@ pub fn sinq(x: f128) callconv(.c) f128 { |
| 189 | 204 | |
| 190 | 205 | pub fn sinl(x: c_longdouble) callconv(.c) c_longdouble { |
| 191 | 206 | switch (@typeInfo(c_longdouble).float.bits) { |
| 192 | 64 => return sin(x), | |
| 193 | 80 => return sinx(x), | |
| 194 | 128 => return sinq(x), | |
| 195 | else => @compileError("unreachable"), | |
| 207 | 64 => return sin_f64(x), | |
| 208 | 80 => return sin_f80(x), | |
| 209 | 128 => return sin_f128(x), | |
| 210 | else => comptime unreachable, | |
| 196 | 211 | } |
| 197 | 212 | } |
| 198 | 213 | |
| 199 | 214 | fn testSinSpecial(comptime T: type) !void { |
| 200 | 215 | const f = switch (T) { |
| 201 | f32 => sinf, | |
| 202 | f64 => sin, | |
| 203 | f80 => sinx, | |
| 204 | f128 => sinq, | |
| 205 | else => @compileError("unimplemented"), | |
| 216 | f16 => sin_f16, | |
| 217 | f32 => sin_f32, | |
| 218 | f64 => sin_f64, | |
| 219 | f80 => sin_f80, | |
| 220 | f128 => sin_f128, | |
| 221 | else => comptime unreachable, | |
| 206 | 222 | }; |
| 207 | 223 | |
| 208 | 224 | try expect(math.isPositiveZero(f(0.0))); |
| ... | ... | @@ -214,13 +230,13 @@ fn testSinSpecial(comptime T: type) !void { |
| 214 | 230 | |
| 215 | 231 | test "sin32.normal" { |
| 216 | 232 | const epsilon = math.floatEps(f32); |
| 217 | try expectApproxEqAbs(@as(f32, 0.0), sinf(0.0), epsilon); | |
| 218 | try expectApproxEqAbs(@as(f32, 0.19866933), sinf(0.2), epsilon); | |
| 219 | try expectApproxEqAbs(@as(f32, 0.77851737), sinf(0.8923), epsilon); | |
| 220 | try expectApproxEqAbs(@as(f32, 0.997495), sinf(1.5), epsilon); | |
| 221 | try expectApproxEqAbs(@as(f32, -0.997495), sinf(-1.5), epsilon); | |
| 222 | try expectApproxEqAbs(@as(f32, -0.24654257), sinf(37.45), epsilon); | |
| 223 | try expectApproxEqAbs(@as(f32, 0.9161657), sinf(89.123), epsilon); | |
| 233 | try expectApproxEqAbs(@as(f32, 0.0), sin_f32(0.0), epsilon); | |
| 234 | try expectApproxEqAbs(@as(f32, 0.19866933), sin_f32(0.2), epsilon); | |
| 235 | try expectApproxEqAbs(@as(f32, 0.77851737), sin_f32(0.8923), epsilon); | |
| 236 | try expectApproxEqAbs(@as(f32, 0.997495), sin_f32(1.5), epsilon); | |
| 237 | try expectApproxEqAbs(@as(f32, -0.997495), sin_f32(-1.5), epsilon); | |
| 238 | try expectApproxEqAbs(@as(f32, -0.24654257), sin_f32(37.45), epsilon); | |
| 239 | try expectApproxEqAbs(@as(f32, 0.9161657), sin_f32(89.123), epsilon); | |
| 224 | 240 | } |
| 225 | 241 | |
| 226 | 242 | test "sin32.special" { |
| ... | ... | @@ -229,13 +245,13 @@ test "sin32.special" { |
| 229 | 245 | |
| 230 | 246 | test "sin64.normal" { |
| 231 | 247 | const epsilon = math.floatEps(f64); |
| 232 | try expectApproxEqAbs(@as(f64, 0.0), sin(0.0), epsilon); | |
| 233 | try expectApproxEqAbs(@as(f64, 0.19866933079506122), sin(0.2), epsilon); | |
| 234 | try expectApproxEqAbs(@as(f64, 0.7785173385577349), sin(0.8923), epsilon); | |
| 235 | try expectApproxEqAbs(@as(f64, 0.9974949866040544), sin(1.5), epsilon); | |
| 236 | try expectApproxEqAbs(@as(f64, -0.9974949866040544), sin(-1.5), epsilon); | |
| 237 | try expectApproxEqAbs(@as(f64, -0.24654331551411082), sin(37.45), epsilon); | |
| 238 | try expectApproxEqAbs(@as(f64, 0.9161652766622714), sin(89.123), epsilon); | |
| 248 | try expectApproxEqAbs(@as(f64, 0.0), sin_f64(0.0), epsilon); | |
| 249 | try expectApproxEqAbs(@as(f64, 0.19866933079506122), sin_f64(0.2), epsilon); | |
| 250 | try expectApproxEqAbs(@as(f64, 0.7785173385577349), sin_f64(0.8923), epsilon); | |
| 251 | try expectApproxEqAbs(@as(f64, 0.9974949866040544), sin_f64(1.5), epsilon); | |
| 252 | try expectApproxEqAbs(@as(f64, -0.9974949866040544), sin_f64(-1.5), epsilon); | |
| 253 | try expectApproxEqAbs(@as(f64, -0.24654331551411082), sin_f64(37.45), epsilon); | |
| 254 | try expectApproxEqAbs(@as(f64, 0.9161652766622714), sin_f64(89.123), epsilon); | |
| 239 | 255 | } |
| 240 | 256 | |
| 241 | 257 | test "sin64.special" { |
| ... | ... | @@ -244,13 +260,13 @@ test "sin64.special" { |
| 244 | 260 | |
| 245 | 261 | test "sin80.normal" { |
| 246 | 262 | const epsilon = math.floatEps(f80); |
| 247 | try expectApproxEqAbs(@as(f80, 0.0), sinx(0.0), epsilon); | |
| 248 | try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), sinx(0.2), epsilon); | |
| 249 | try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), sinx(0.8923), epsilon); | |
| 250 | try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), sinx(1.5), epsilon); | |
| 251 | try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), sinx(-1.5), epsilon); | |
| 252 | try expectApproxEqAbs(@as(f80, -0.24654331551411356504), sinx(37.45), epsilon); | |
| 253 | try expectApproxEqAbs(@as(f80, 0.91616527666226951006), sinx(89.123), epsilon); | |
| 263 | try expectApproxEqAbs(@as(f80, 0.0), sin_f80(0.0), epsilon); | |
| 264 | try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), sin_f80(0.2), epsilon); | |
| 265 | try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), sin_f80(0.8923), epsilon); | |
| 266 | try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), sin_f80(1.5), epsilon); | |
| 267 | try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), sin_f80(-1.5), epsilon); | |
| 268 | try expectApproxEqAbs(@as(f80, -0.24654331551411356504), sin_f80(37.45), epsilon); | |
| 269 | try expectApproxEqAbs(@as(f80, 0.91616527666226951006), sin_f80(89.123), epsilon); | |
| 254 | 270 | } |
| 255 | 271 | |
| 256 | 272 | test "sin80.special" { |
| ... | ... | @@ -259,13 +275,13 @@ test "sin80.special" { |
| 259 | 275 | |
| 260 | 276 | test "sin128.normal" { |
| 261 | 277 | const epsilon = math.floatEps(f128); |
| 262 | try expectApproxEqAbs(@as(f128, 0.0), sinq(0.0), epsilon); | |
| 263 | try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), sinq(0.2), epsilon); | |
| 264 | try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), sinq(0.8923), epsilon); | |
| 265 | try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), sinq(1.5), epsilon); | |
| 266 | try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), sinq(-1.5), epsilon); | |
| 267 | try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), sinq(37.45), epsilon); | |
| 268 | try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), sinq(89.123), epsilon); | |
| 278 | try expectApproxEqAbs(@as(f128, 0.0), sin_f128(0.0), epsilon); | |
| 279 | try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), sin_f128(0.2), epsilon); | |
| 280 | try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), sin_f128(0.8923), epsilon); | |
| 281 | try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), sin_f128(1.5), epsilon); | |
| 282 | try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), sin_f128(-1.5), epsilon); | |
| 283 | try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), sin_f128(37.45), epsilon); | |
| 284 | try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), sin_f128(89.123), epsilon); | |
| 269 | 285 | } |
| 270 | 286 | |
| 271 | 287 | test "sin128.special" { |
| ... | ... | @@ -274,10 +290,10 @@ test "sin128.special" { |
| 274 | 290 | |
| 275 | 291 | test "sin32 #9901" { |
| 276 | 292 | const float: f32 = @bitCast(@as(u32, 0b11100011111111110000000000000000)); |
| 277 | _ = sinf(float); | |
| 293 | _ = sin_f32(float); | |
| 278 | 294 | } |
| 279 | 295 | |
| 280 | 296 | test "sin64 #9901" { |
| 281 | 297 | const float: f64 = @bitCast(@as(u64, 0b1111111101000001000000001111110111111111100000000000000000000001)); |
| 282 | _ = sin(float); | |
| 298 | _ = sin_f64(float); | |
| 283 | 299 | } |
lib/compiler_rt/sincos.zig+124-177| ... | ... | @@ -25,16 +25,23 @@ comptime { |
| 25 | 25 | symbol(&sincosl, "sincosl"); |
| 26 | 26 | } |
| 27 | 27 | |
| 28 | pub fn sincosh(x: f16, r_sin: *f16, r_cos: *f16) callconv(.c) void { | |
| 28 | fn sincosh(x: compiler_rt.f16.Abi, r_sin: *compiler_rt.f16.Abi, r_cos: *compiler_rt.f16.Abi) callconv(.c) void { | |
| 29 | const s, const c = sincos_f16(compiler_rt.f16.fromAbi(x)); | |
| 30 | r_sin.* = compiler_rt.f16.toAbi(s); | |
| 31 | r_cos.* = compiler_rt.f16.toAbi(c); | |
| 32 | } | |
| 33 | pub fn sincos_f16(x: f16) struct { f16, f16 } { | |
| 29 | 34 | // TODO: more efficient implementation |
| 30 | var big_sin: f32 = undefined; | |
| 31 | var big_cos: f32 = undefined; | |
| 32 | sincosf(x, &big_sin, &big_cos); | |
| 33 | r_sin.* = @as(f16, @floatCast(big_sin)); | |
| 34 | r_cos.* = @as(f16, @floatCast(big_cos)); | |
| 35 | const s, const c = sincos_f32(x); | |
| 36 | return .{ @floatCast(s), @floatCast(c) }; | |
| 35 | 37 | } |
| 36 | 38 | |
| 37 | pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { | |
| 39 | fn sincosf(x: compiler_rt.f32.Abi, r_sin: *compiler_rt.f32.Abi, r_cos: *compiler_rt.f32.Abi) callconv(.c) void { | |
| 40 | const s, const c = sincos_f32(compiler_rt.f32.fromAbi(x)); | |
| 41 | r_sin.* = compiler_rt.f32.toAbi(s); | |
| 42 | r_cos.* = compiler_rt.f32.toAbi(c); | |
| 43 | } | |
| 44 | pub fn sincos_f32(x: f32) struct { f32, f32 } { | |
| 38 | 45 | const sc1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 |
| 39 | 46 | const sc2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 |
| 40 | 47 | const sc3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D2 |
| ... | ... | @@ -56,13 +63,9 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { |
| 56 | 63 | mem.doNotOptimizeAway(x + 0x1p120); |
| 57 | 64 | } |
| 58 | 65 | } |
| 59 | r_sin.* = x; | |
| 60 | r_cos.* = 1.0; | |
| 61 | return; | |
| 66 | return .{ x, 1.0 }; | |
| 62 | 67 | } |
| 63 | r_sin.* = trig.sindf(x); | |
| 64 | r_cos.* = trig.cosdf(x); | |
| 65 | return; | |
| 68 | return .{ trig.sindf(x), trig.cosdf(x) }; | |
| 66 | 69 | } |
| 67 | 70 | |
| 68 | 71 | // |x| ~<= 5*pi/4 |
| ... | ... | @@ -70,18 +73,16 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { |
| 70 | 73 | // |x| ~<= 3pi/4 |
| 71 | 74 | if (ix <= 0x4016cbe3) { |
| 72 | 75 | if (sign) { |
| 73 | r_sin.* = -trig.cosdf(x + sc1pio2); | |
| 74 | r_cos.* = trig.sindf(x + sc1pio2); | |
| 76 | return .{ -trig.cosdf(x + sc1pio2), trig.sindf(x + sc1pio2) }; | |
| 75 | 77 | } else { |
| 76 | r_sin.* = trig.cosdf(sc1pio2 - x); | |
| 77 | r_cos.* = trig.sindf(sc1pio2 - x); | |
| 78 | return .{ trig.cosdf(sc1pio2 - x), trig.sindf(sc1pio2 - x) }; | |
| 78 | 79 | } |
| 79 | return; | |
| 80 | 80 | } |
| 81 | 81 | // -sin(x+c) is not correct if x+c could be 0: -0 vs +0 |
| 82 | r_sin.* = -trig.sindf(if (sign) x + sc2pio2 else x - sc2pio2); | |
| 83 | r_cos.* = -trig.cosdf(if (sign) x + sc2pio2 else x - sc2pio2); | |
| 84 | return; | |
| 82 | return .{ | |
| 83 | -trig.sindf(if (sign) x + sc2pio2 else x - sc2pio2), | |
| 84 | -trig.cosdf(if (sign) x + sc2pio2 else x - sc2pio2), | |
| 85 | }; | |
| 85 | 86 | } |
| 86 | 87 | |
| 87 | 88 | // |x| ~<= 9*pi/4 |
| ... | ... | @@ -89,25 +90,21 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { |
| 89 | 90 | // |x| ~<= 7*pi/4 |
| 90 | 91 | if (ix <= 0x40afeddf) { |
| 91 | 92 | if (sign) { |
| 92 | r_sin.* = trig.cosdf(x + sc3pio2); | |
| 93 | r_cos.* = -trig.sindf(x + sc3pio2); | |
| 93 | return .{ trig.cosdf(x + sc3pio2), -trig.sindf(x + sc3pio2) }; | |
| 94 | 94 | } else { |
| 95 | r_sin.* = -trig.cosdf(x - sc3pio2); | |
| 96 | r_cos.* = trig.sindf(x - sc3pio2); | |
| 95 | return .{ -trig.cosdf(x - sc3pio2), trig.sindf(x - sc3pio2) }; | |
| 97 | 96 | } |
| 98 | return; | |
| 99 | 97 | } |
| 100 | r_sin.* = trig.sindf(if (sign) x + sc4pio2 else x - sc4pio2); | |
| 101 | r_cos.* = trig.cosdf(if (sign) x + sc4pio2 else x - sc4pio2); | |
| 102 | return; | |
| 98 | return .{ | |
| 99 | trig.sindf(if (sign) x + sc4pio2 else x - sc4pio2), | |
| 100 | trig.cosdf(if (sign) x + sc4pio2 else x - sc4pio2), | |
| 101 | }; | |
| 103 | 102 | } |
| 104 | 103 | |
| 105 | 104 | // sin(Inf or NaN) is NaN |
| 106 | 105 | if (ix >= 0x7f800000) { |
| 107 | 106 | const result = x - x; |
| 108 | r_sin.* = result; | |
| 109 | r_cos.* = result; | |
| 110 | return; | |
| 107 | return .{ result, result }; | |
| 111 | 108 | } |
| 112 | 109 | |
| 113 | 110 | // general argument reduction needed |
| ... | ... | @@ -115,27 +112,20 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { |
| 115 | 112 | const n = rem_pio2f(x, &y); |
| 116 | 113 | const s = trig.sindf(y); |
| 117 | 114 | const c = trig.cosdf(y); |
| 118 | switch (n & 3) { | |
| 119 | 0 => { | |
| 120 | r_sin.* = s; | |
| 121 | r_cos.* = c; | |
| 122 | }, | |
| 123 | 1 => { | |
| 124 | r_sin.* = c; | |
| 125 | r_cos.* = -s; | |
| 126 | }, | |
| 127 | 2 => { | |
| 128 | r_sin.* = -s; | |
| 129 | r_cos.* = -c; | |
| 130 | }, | |
| 131 | else => { | |
| 132 | r_sin.* = -c; | |
| 133 | r_cos.* = s; | |
| 134 | }, | |
| 135 | } | |
| 115 | return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) { | |
| 116 | 0 => .{ s, c }, | |
| 117 | 1 => .{ c, -s }, | |
| 118 | 2 => .{ -s, -c }, | |
| 119 | 3 => .{ -c, s }, | |
| 120 | }; | |
| 136 | 121 | } |
| 137 | 122 | |
| 138 | pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { | |
| 123 | fn sincos(x: compiler_rt.f64.Abi, r_sin: *compiler_rt.f64.Abi, r_cos: *compiler_rt.f64.Abi) callconv(.c) void { | |
| 124 | const s, const c = sincos_f64(compiler_rt.f64.fromAbi(x)); | |
| 125 | r_sin.* = compiler_rt.f64.toAbi(s); | |
| 126 | r_cos.* = compiler_rt.f64.toAbi(c); | |
| 127 | } | |
| 128 | pub fn sincos_f64(x: f64) struct { f64, f64 } { | |
| 139 | 129 | const ix = @as(u32, @truncate(@as(u64, @bitCast(x)) >> 32)) & 0x7fffffff; |
| 140 | 130 | |
| 141 | 131 | // |x| ~< pi/4 |
| ... | ... | @@ -150,21 +140,15 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { |
| 150 | 140 | mem.doNotOptimizeAway(x + 0x1p120); |
| 151 | 141 | } |
| 152 | 142 | } |
| 153 | r_sin.* = x; | |
| 154 | r_cos.* = 1.0; | |
| 155 | return; | |
| 143 | return .{ x, 1.0 }; | |
| 156 | 144 | } |
| 157 | r_sin.* = trig.sin(x, 0.0, 0); | |
| 158 | r_cos.* = trig.cos(x, 0.0); | |
| 159 | return; | |
| 145 | return .{ trig.sin(x, 0.0, 0), trig.cos(x, 0.0) }; | |
| 160 | 146 | } |
| 161 | 147 | |
| 162 | 148 | // sincos(Inf or NaN) is NaN |
| 163 | 149 | if (ix >= 0x7ff00000) { |
| 164 | 150 | const result = x - x; |
| 165 | r_sin.* = result; | |
| 166 | r_cos.* = result; | |
| 167 | return; | |
| 151 | return .{ result, result }; | |
| 168 | 152 | } |
| 169 | 153 | |
| 170 | 154 | // argument reduction needed |
| ... | ... | @@ -172,33 +156,24 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { |
| 172 | 156 | const n = rem_pio2(x, &y); |
| 173 | 157 | const s = trig.sin(y[0], y[1], 1); |
| 174 | 158 | const c = trig.cos(y[0], y[1]); |
| 175 | switch (n & 3) { | |
| 176 | 0 => { | |
| 177 | r_sin.* = s; | |
| 178 | r_cos.* = c; | |
| 179 | }, | |
| 180 | 1 => { | |
| 181 | r_sin.* = c; | |
| 182 | r_cos.* = -s; | |
| 183 | }, | |
| 184 | 2 => { | |
| 185 | r_sin.* = -s; | |
| 186 | r_cos.* = -c; | |
| 187 | }, | |
| 188 | else => { | |
| 189 | r_sin.* = -c; | |
| 190 | r_cos.* = s; | |
| 191 | }, | |
| 192 | } | |
| 159 | return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) { | |
| 160 | 0 => .{ s, c }, | |
| 161 | 1 => .{ c, -s }, | |
| 162 | 2 => .{ -s, -c }, | |
| 163 | 3 => .{ -c, s }, | |
| 164 | }; | |
| 193 | 165 | } |
| 194 | 166 | |
| 195 | pub fn sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void { | |
| 167 | fn sincosx(x: compiler_rt.f80.Abi, r_sin: *compiler_rt.f80.Abi, r_cos: *compiler_rt.f80.Abi) callconv(.c) void { | |
| 168 | const s, const c = sincos_f80(compiler_rt.f80.fromAbi(x)); | |
| 169 | r_sin.* = compiler_rt.f80.toAbi(s); | |
| 170 | r_cos.* = compiler_rt.f80.toAbi(c); | |
| 171 | } | |
| 172 | pub fn sincos_f80(x: f80) struct { f80, f80 } { | |
| 196 | 173 | const se = ld.signExponent(x) & 0x7fff; |
| 197 | 174 | if (se == 0x7fff) { |
| 198 | 175 | const result = x - x; |
| 199 | r_sin.* = result; | |
| 200 | r_cos.* = result; | |
| 201 | return; | |
| 176 | return .{ result, result }; | |
| 202 | 177 | } |
| 203 | 178 | |
| 204 | 179 | if (@abs(x) < trig.pi_4) { |
| ... | ... | @@ -207,47 +182,34 @@ pub fn sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void { |
| 207 | 182 | if (compiler_rt.want_float_exceptions and se == 0) { |
| 208 | 183 | mem.doNotOptimizeAway(x * 0x1p-120); |
| 209 | 184 | } |
| 210 | r_sin.* = x; | |
| 211 | 185 | // raise inexact if x!=0 |
| 212 | r_cos.* = 1.0 + x; | |
| 213 | return; | |
| 186 | return .{ x, 1.0 + x }; | |
| 214 | 187 | } |
| 215 | r_sin.* = trig.sinx(x, 0.0, 0); | |
| 216 | r_cos.* = trig.cosx(x, 0.0); | |
| 217 | return; | |
| 188 | return .{ trig.sinx(x, 0.0, 0), trig.cosx(x, 0.0) }; | |
| 218 | 189 | } |
| 219 | 190 | |
| 220 | 191 | var y: [2]f80 = undefined; |
| 221 | 192 | const n = rem_pio2l(f80, x, &y); |
| 222 | 193 | const s = trig.sinx(y[0], y[1], 1); |
| 223 | 194 | const c = trig.cosx(y[0], y[1]); |
| 224 | switch (n & 3) { | |
| 225 | 0 => { | |
| 226 | r_sin.* = s; | |
| 227 | r_cos.* = c; | |
| 228 | }, | |
| 229 | 1 => { | |
| 230 | r_sin.* = c; | |
| 231 | r_cos.* = -s; | |
| 232 | }, | |
| 233 | 2 => { | |
| 234 | r_sin.* = -s; | |
| 235 | r_cos.* = -c; | |
| 236 | }, | |
| 237 | else => { | |
| 238 | r_sin.* = -c; | |
| 239 | r_cos.* = s; | |
| 240 | }, | |
| 241 | } | |
| 195 | return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) { | |
| 196 | 0 => .{ s, c }, | |
| 197 | 1 => .{ c, -s }, | |
| 198 | 2 => .{ -s, -c }, | |
| 199 | 3 => .{ -c, s }, | |
| 200 | }; | |
| 242 | 201 | } |
| 243 | 202 | |
| 244 | pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void { | |
| 203 | fn sincosq(x: compiler_rt.f128.Abi, r_sin: *compiler_rt.f128.Abi, r_cos: *compiler_rt.f128.Abi) callconv(.c) void { | |
| 204 | const s, const c = sincos_f128(compiler_rt.f128.fromAbi(x)); | |
| 205 | r_sin.* = compiler_rt.f128.toAbi(s); | |
| 206 | r_cos.* = compiler_rt.f128.toAbi(c); | |
| 207 | } | |
| 208 | pub fn sincos_f128(x: f128) struct { f128, f128 } { | |
| 245 | 209 | const se = ld.signExponent(x) & 0x7fff; |
| 246 | 210 | if (se == 0x7fff) { |
| 247 | 211 | const result = x - x; |
| 248 | r_sin.* = result; | |
| 249 | r_cos.* = result; | |
| 250 | return; | |
| 212 | return .{ result, result }; | |
| 251 | 213 | } |
| 252 | 214 | |
| 253 | 215 | if (@abs(x) < trig.pi_4) { |
| ... | ... | @@ -256,78 +218,63 @@ pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void { |
| 256 | 218 | if (compiler_rt.want_float_exceptions and se == 0) { |
| 257 | 219 | mem.doNotOptimizeAway(x * 0x1p-120); |
| 258 | 220 | } |
| 259 | r_sin.* = x; | |
| 260 | 221 | // raise inexact if x!=0 |
| 261 | r_cos.* = 1.0 + x; | |
| 262 | return; | |
| 222 | return .{ x, 1.0 + x }; | |
| 263 | 223 | } |
| 264 | r_sin.* = trig.sinq(x, 0.0, 0); | |
| 265 | r_cos.* = trig.cosq(x, 0.0); | |
| 266 | return; | |
| 224 | return .{ trig.sinq(x, 0.0, 0), trig.cosq(x, 0.0) }; | |
| 267 | 225 | } |
| 268 | 226 | |
| 269 | 227 | var y: [2]f128 = undefined; |
| 270 | 228 | const n = rem_pio2l(f128, x, &y); |
| 271 | 229 | const s = trig.sinq(y[0], y[1], 1); |
| 272 | 230 | const c = trig.cosq(y[0], y[1]); |
| 273 | switch (n & 3) { | |
| 274 | 0 => { | |
| 275 | r_sin.* = s; | |
| 276 | r_cos.* = c; | |
| 277 | }, | |
| 278 | 1 => { | |
| 279 | r_sin.* = c; | |
| 280 | r_cos.* = -s; | |
| 281 | }, | |
| 282 | 2 => { | |
| 283 | r_sin.* = -s; | |
| 284 | r_cos.* = -c; | |
| 285 | }, | |
| 286 | else => { | |
| 287 | r_sin.* = -c; | |
| 288 | r_cos.* = s; | |
| 289 | }, | |
| 290 | } | |
| 231 | return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) { | |
| 232 | 0 => .{ s, c }, | |
| 233 | 1 => .{ c, -s }, | |
| 234 | 2 => .{ -s, -c }, | |
| 235 | 3 => .{ -c, s }, | |
| 236 | }; | |
| 291 | 237 | } |
| 292 | 238 | |
| 293 | 239 | pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.c) void { |
| 294 | switch (@typeInfo(c_longdouble).float.bits) { | |
| 295 | 64 => return sincos(x, r_sin, r_cos), | |
| 296 | 80 => return sincosx(x, r_sin, r_cos), | |
| 297 | 128 => return sincosq(x, r_sin, r_cos), | |
| 298 | else => @compileError("unreachable"), | |
| 299 | } | |
| 240 | r_sin.*, r_cos.* = switch (@typeInfo(c_longdouble).float.bits) { | |
| 241 | 64 => sincos_f64(x), | |
| 242 | 80 => sincos_f80(x), | |
| 243 | 128 => sincos_f128(x), | |
| 244 | else => comptime unreachable, | |
| 245 | }; | |
| 300 | 246 | } |
| 301 | 247 | |
| 302 | 248 | fn testSincosSpecial(comptime T: type) !void { |
| 303 | 249 | const f = switch (T) { |
| 304 | f32 => sincosf, | |
| 305 | f64 => sincos, | |
| 306 | f80 => sincosx, | |
| 307 | f128 => sincosq, | |
| 250 | f16 => sincos_f16, | |
| 251 | f32 => sincos_f32, | |
| 252 | f64 => sincos_f64, | |
| 253 | f80 => sincos_f80, | |
| 254 | f128 => sincos_f128, | |
| 308 | 255 | else => @compileError("unimplemented"), |
| 309 | 256 | }; |
| 310 | 257 | |
| 311 | 258 | var s: T = undefined; |
| 312 | 259 | var c: T = undefined; |
| 313 | 260 | |
| 314 | f(0.0, &s, &c); | |
| 261 | s, c = f(0.0); | |
| 315 | 262 | try expect(math.isPositiveZero(s)); |
| 316 | 263 | try expect(c == 1.0); |
| 317 | 264 | |
| 318 | f(-0.0, &s, &c); | |
| 265 | s, c = f(-0.0); | |
| 319 | 266 | try expect(math.isNegativeZero(s)); |
| 320 | 267 | try expect(c == 1.0); |
| 321 | 268 | |
| 322 | f(math.inf(T), &s, &c); | |
| 269 | s, c = f(math.inf(T)); | |
| 323 | 270 | try expect(math.isNan(s)); |
| 324 | 271 | try expect(math.isNan(c)); |
| 325 | 272 | |
| 326 | f(-math.inf(T), &s, &c); | |
| 273 | s, c = f(-math.inf(T)); | |
| 327 | 274 | try expect(math.isNan(s)); |
| 328 | 275 | try expect(math.isNan(c)); |
| 329 | 276 | |
| 330 | f(math.nan(T), &s, &c); | |
| 277 | s, c = f(math.nan(T)); | |
| 331 | 278 | try expect(math.isNan(s)); |
| 332 | 279 | try expect(math.isNan(c)); |
| 333 | 280 | } |
| ... | ... | @@ -337,31 +284,31 @@ test "sincos32.normal" { |
| 337 | 284 | var s: f32 = undefined; |
| 338 | 285 | var c: f32 = undefined; |
| 339 | 286 | |
| 340 | sincosf(0.0, &s, &c); | |
| 287 | s, c = sincos_f32(0.0); | |
| 341 | 288 | try expectApproxEqAbs(@as(f32, 0.0), s, epsilon); |
| 342 | 289 | try expectApproxEqAbs(@as(f32, 1.0), c, epsilon); |
| 343 | 290 | |
| 344 | sincosf(0.2, &s, &c); | |
| 291 | s, c = sincos_f32(0.2); | |
| 345 | 292 | try expectApproxEqAbs(@as(f32, 0.19866933), s, epsilon); |
| 346 | 293 | try expectApproxEqAbs(@as(f32, 0.9800666), c, epsilon); |
| 347 | 294 | |
| 348 | sincosf(0.8923, &s, &c); | |
| 295 | s, c = sincos_f32(0.8923); | |
| 349 | 296 | try expectApproxEqAbs(@as(f32, 0.77851737), s, epsilon); |
| 350 | 297 | try expectApproxEqAbs(@as(f32, 0.6276231), c, epsilon); |
| 351 | 298 | |
| 352 | sincosf(1.5, &s, &c); | |
| 299 | s, c = sincos_f32(1.5); | |
| 353 | 300 | try expectApproxEqAbs(@as(f32, 0.997495), s, epsilon); |
| 354 | 301 | try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon); |
| 355 | 302 | |
| 356 | sincosf(-1.5, &s, &c); | |
| 303 | s, c = sincos_f32(-1.5); | |
| 357 | 304 | try expectApproxEqAbs(@as(f32, -0.997495), s, epsilon); |
| 358 | 305 | try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon); |
| 359 | 306 | |
| 360 | sincosf(37.45, &s, &c); | |
| 307 | s, c = sincos_f32(37.45); | |
| 361 | 308 | try expectApproxEqAbs(@as(f32, -0.24654257), s, epsilon); |
| 362 | 309 | try expectApproxEqAbs(@as(f32, 0.96913195), c, epsilon); |
| 363 | 310 | |
| 364 | sincosf(89.123, &s, &c); | |
| 311 | s, c = sincos_f32(89.123); | |
| 365 | 312 | try expectApproxEqAbs(@as(f32, 0.9161657), s, epsilon); |
| 366 | 313 | try expectApproxEqAbs(@as(f32, 0.40079966), c, epsilon); |
| 367 | 314 | } |
| ... | ... | @@ -375,31 +322,31 @@ test "sincos64.normal" { |
| 375 | 322 | var s: f64 = undefined; |
| 376 | 323 | var c: f64 = undefined; |
| 377 | 324 | |
| 378 | sincos(0.0, &s, &c); | |
| 325 | s, c = sincos_f64(0.0); | |
| 379 | 326 | try expectApproxEqAbs(@as(f64, 0.0), s, epsilon); |
| 380 | 327 | try expectApproxEqAbs(@as(f64, 1.0), c, epsilon); |
| 381 | 328 | |
| 382 | sincos(0.2, &s, &c); | |
| 329 | s, c = sincos_f64(0.2); | |
| 383 | 330 | try expectApproxEqAbs(@as(f64, 0.19866933079506122), s, epsilon); |
| 384 | 331 | try expectApproxEqAbs(@as(f64, 0.9800665778412416), c, epsilon); |
| 385 | 332 | |
| 386 | sincos(0.8923, &s, &c); | |
| 333 | s, c = sincos_f64(0.8923); | |
| 387 | 334 | try expectApproxEqAbs(@as(f64, 0.7785173385577349), s, epsilon); |
| 388 | 335 | try expectApproxEqAbs(@as(f64, 0.6276230983360804), c, epsilon); |
| 389 | 336 | |
| 390 | sincos(1.5, &s, &c); | |
| 337 | s, c = sincos_f64(1.5); | |
| 391 | 338 | try expectApproxEqAbs(@as(f64, 0.9974949866040544), s, epsilon); |
| 392 | 339 | try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon); |
| 393 | 340 | |
| 394 | sincos(-1.5, &s, &c); | |
| 341 | s, c = sincos_f64(-1.5); | |
| 395 | 342 | try expectApproxEqAbs(@as(f64, -0.9974949866040544), s, epsilon); |
| 396 | 343 | try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon); |
| 397 | 344 | |
| 398 | sincos(37.45, &s, &c); | |
| 345 | s, c = sincos_f64(37.45); | |
| 399 | 346 | try expectApproxEqAbs(@as(f64, -0.24654331551411082), s, epsilon); |
| 400 | 347 | try expectApproxEqAbs(@as(f64, 0.9691317730707778), c, epsilon); |
| 401 | 348 | |
| 402 | sincos(89.123, &s, &c); | |
| 349 | s, c = sincos_f64(89.123); | |
| 403 | 350 | try expectApproxEqAbs(@as(f64, 0.9161652766622714), s, epsilon); |
| 404 | 351 | try expectApproxEqAbs(@as(f64, 0.4008006809354791), c, epsilon); |
| 405 | 352 | } |
| ... | ... | @@ -413,31 +360,31 @@ test "sincos80.normal" { |
| 413 | 360 | var s: f80 = undefined; |
| 414 | 361 | var c: f80 = undefined; |
| 415 | 362 | |
| 416 | sincosx(0.0, &s, &c); | |
| 363 | s, c = sincos_f80(0.0); | |
| 417 | 364 | try expectApproxEqAbs(@as(f80, 0.0), s, epsilon); |
| 418 | 365 | try expectApproxEqAbs(@as(f80, 1.0), c, epsilon); |
| 419 | 366 | |
| 420 | sincosx(0.2, &s, &c); | |
| 367 | s, c = sincos_f80(0.2); | |
| 421 | 368 | try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), s, epsilon); |
| 422 | 369 | try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), c, epsilon); |
| 423 | 370 | |
| 424 | sincosx(0.8923, &s, &c); | |
| 371 | s, c = sincos_f80(0.8923); | |
| 425 | 372 | try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), s, epsilon); |
| 426 | 373 | try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), c, epsilon); |
| 427 | 374 | |
| 428 | sincosx(1.5, &s, &c); | |
| 375 | s, c = sincos_f80(1.5); | |
| 429 | 376 | try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), s, epsilon); |
| 430 | 377 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon); |
| 431 | 378 | |
| 432 | sincosx(-1.5, &s, &c); | |
| 379 | s, c = sincos_f80(-1.5); | |
| 433 | 380 | try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), s, epsilon); |
| 434 | 381 | try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon); |
| 435 | 382 | |
| 436 | sincosx(37.45, &s, &c); | |
| 383 | s, c = sincos_f80(37.45); | |
| 437 | 384 | try expectApproxEqAbs(@as(f80, -0.24654331551411356504), s, epsilon); |
| 438 | 385 | try expectApproxEqAbs(@as(f80, 0.9691317730707771246), c, epsilon); |
| 439 | 386 | |
| 440 | sincosx(89.123, &s, &c); | |
| 387 | s, c = sincos_f80(89.123); | |
| 441 | 388 | try expectApproxEqAbs(@as(f80, 0.91616527666226951006), s, epsilon); |
| 442 | 389 | try expectApproxEqAbs(@as(f80, 0.4008006809354834001), c, epsilon); |
| 443 | 390 | } |
| ... | ... | @@ -451,31 +398,31 @@ test "sincos128.normal" { |
| 451 | 398 | var s: f128 = undefined; |
| 452 | 399 | var c: f128 = undefined; |
| 453 | 400 | |
| 454 | sincosq(0.0, &s, &c); | |
| 401 | s, c = sincos_f128(0.0); | |
| 455 | 402 | try expectApproxEqAbs(@as(f128, 0.0), s, epsilon); |
| 456 | 403 | try expectApproxEqAbs(@as(f128, 1.0), c, epsilon); |
| 457 | 404 | |
| 458 | sincosq(0.2, &s, &c); | |
| 405 | s, c = sincos_f128(0.2); | |
| 459 | 406 | try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), s, epsilon); |
| 460 | 407 | try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), c, epsilon); |
| 461 | 408 | |
| 462 | sincosq(0.8923, &s, &c); | |
| 409 | s, c = sincos_f128(0.8923); | |
| 463 | 410 | try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), s, epsilon); |
| 464 | 411 | try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), c, epsilon); |
| 465 | 412 | |
| 466 | sincosq(1.5, &s, &c); | |
| 413 | s, c = sincos_f128(1.5); | |
| 467 | 414 | try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), s, epsilon); |
| 468 | 415 | try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon); |
| 469 | 416 | |
| 470 | sincosq(-1.5, &s, &c); | |
| 417 | s, c = sincos_f128(-1.5); | |
| 471 | 418 | try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), s, epsilon); |
| 472 | 419 | try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon); |
| 473 | 420 | |
| 474 | sincosq(37.45, &s, &c); | |
| 421 | s, c = sincos_f128(37.45); | |
| 475 | 422 | try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), s, epsilon); |
| 476 | 423 | try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), c, epsilon); |
| 477 | 424 | |
| 478 | sincosq(89.123, &s, &c); | |
| 425 | s, c = sincos_f128(89.123); | |
| 479 | 426 | try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), s, epsilon); |
| 480 | 427 | try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), c, epsilon); |
| 481 | 428 | } |
lib/compiler_rt/sqrt.zig+148-133| ... | ... | @@ -28,7 +28,10 @@ comptime { |
| 28 | 28 | symbol(&sqrtl, "sqrtl"); |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | pub fn __sqrth(x: f16) callconv(.c) f16 { | |
| 31 | fn __sqrth(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 32 | return compiler_rt.f16.toAbi(sqrt_f16(compiler_rt.f16.fromAbi(x))); | |
| 33 | } | |
| 34 | pub fn sqrt_f16(x: f16) f16 { | |
| 32 | 35 | var ix: u16 = @bitCast(x); |
| 33 | 36 | var top = ix >> 10; |
| 34 | 37 | |
| ... | ... | @@ -93,7 +96,10 @@ pub fn __sqrth(x: f16) callconv(.c) f16 { |
| 93 | 96 | return y; |
| 94 | 97 | } |
| 95 | 98 | |
| 96 | pub fn sqrtf(x: f32) callconv(.c) f32 { | |
| 99 | fn sqrtf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 100 | return compiler_rt.f32.toAbi(sqrt_f32(compiler_rt.f32.fromAbi(x))); | |
| 101 | } | |
| 102 | pub fn sqrt_f32(x: f32) f32 { | |
| 97 | 103 | var ix: u32 = @bitCast(x); |
| 98 | 104 | |
| 99 | 105 | if (ix < @as(u32, @bitCast(@as(f32, 0x1p-126))) or @as(u32, @bitCast(std.math.inf(f32))) <= ix) { |
| ... | ... | @@ -147,7 +153,10 @@ pub fn sqrtf(x: f32) callconv(.c) f32 { |
| 147 | 153 | return y + t; |
| 148 | 154 | } |
| 149 | 155 | |
| 150 | pub fn sqrt(x: f64) callconv(.c) f64 { | |
| 156 | fn sqrt(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 157 | return compiler_rt.f64.toAbi(sqrt_f64(compiler_rt.f64.fromAbi(x))); | |
| 158 | } | |
| 159 | pub fn sqrt_f64(x: f64) f64 { | |
| 151 | 160 | var ix: u64 = @bitCast(x); |
| 152 | 161 | var top = ix >> 52; |
| 153 | 162 | |
| ... | ... | @@ -284,7 +293,10 @@ pub fn sqrt(x: f64) callconv(.c) f64 { |
| 284 | 293 | return y; |
| 285 | 294 | } |
| 286 | 295 | |
| 287 | pub fn __sqrtx(x: f80) callconv(.c) f80 { | |
| 296 | fn __sqrtx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 297 | return compiler_rt.f80.toAbi(sqrt_f80(compiler_rt.f80.fromAbi(x))); | |
| 298 | } | |
| 299 | pub fn sqrt_f80(x: f80) f80 { | |
| 288 | 300 | var ix: u80 = @bitCast(x); |
| 289 | 301 | var top = ix >> 64; |
| 290 | 302 | |
| ... | ... | @@ -381,7 +393,10 @@ pub fn __sqrtx(x: f80) callconv(.c) f80 { |
| 381 | 393 | return y; |
| 382 | 394 | } |
| 383 | 395 | |
| 384 | pub fn sqrtq(x: f128) callconv(.c) f128 { | |
| 396 | fn sqrtq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 397 | return compiler_rt.f128.toAbi(sqrt_f128(compiler_rt.f128.fromAbi(x))); | |
| 398 | } | |
| 399 | pub fn sqrt_f128(x: f128) f128 { | |
| 385 | 400 | var ix: u128 = @bitCast(x); |
| 386 | 401 | var top = ix >> 112; |
| 387 | 402 | |
| ... | ... | @@ -483,10 +498,10 @@ fn _Qp_sqrt(c: *f128, a: *f128) callconv(.c) void { |
| 483 | 498 | |
| 484 | 499 | pub fn sqrtl(x: c_longdouble) callconv(.c) c_longdouble { |
| 485 | 500 | switch (@typeInfo(c_longdouble).float.bits) { |
| 486 | 64 => return sqrt(x), | |
| 487 | 80 => return __sqrtx(x), | |
| 488 | 128 => return sqrtq(x), | |
| 489 | else => @compileError("unreachable"), | |
| 501 | 64 => return sqrt_f64(x), | |
| 502 | 80 => return sqrt_f80(x), | |
| 503 | 128 => return sqrt_f128(x), | |
| 504 | else => comptime unreachable, | |
| 490 | 505 | } |
| 491 | 506 | } |
| 492 | 507 | |
| ... | ... | @@ -545,187 +560,187 @@ inline fn mul80_tail(a: u80, b: u80) u80 { |
| 545 | 560 | return alo * blo +% ((ahi * blo) << 40) +% ((alo * bhi) << 40); |
| 546 | 561 | } |
| 547 | 562 | |
| 548 | test "__sqrth" { | |
| 563 | test "sqrt_f16" { | |
| 549 | 564 | // sqrt(±0) is ±0 |
| 550 | try std.testing.expectEqual(__sqrth(0x0.0p0), 0x0.0p0); | |
| 551 | try std.testing.expectEqual(__sqrth(-0x0.0p0), -0x0.0p0); | |
| 565 | try std.testing.expectEqual(sqrt_f16(0x0.0p0), 0x0.0p0); | |
| 566 | try std.testing.expectEqual(sqrt_f16(-0x0.0p0), -0x0.0p0); | |
| 552 | 567 | // sqrt(+max) is finite |
| 553 | try std.testing.expectEqual(__sqrth(0x1.FFCp15), 0x1.FFCp7); | |
| 568 | try std.testing.expectEqual(sqrt_f16(0x1.FFCp15), 0x1.FFCp7); | |
| 554 | 569 | // sqrt(4)=2 |
| 555 | try std.testing.expectEqual(__sqrth(0x1p2), 0x1p1); | |
| 570 | try std.testing.expectEqual(sqrt_f16(0x1p2), 0x1p1); | |
| 556 | 571 | // sqrt(x) for x=1, 1±ulp |
| 557 | try std.testing.expectEqual(__sqrth(0x1p0), 0x1p0); | |
| 558 | try std.testing.expectEqual(__sqrth(0x1.004p0), 0x1p0); | |
| 559 | try std.testing.expectEqual(__sqrth(0x1.FF8p-1), 0x1.FFCp-1); | |
| 572 | try std.testing.expectEqual(sqrt_f16(0x1p0), 0x1p0); | |
| 573 | try std.testing.expectEqual(sqrt_f16(0x1.004p0), 0x1p0); | |
| 574 | try std.testing.expectEqual(sqrt_f16(0x1.FF8p-1), 0x1.FFCp-1); | |
| 560 | 575 | // sqrt(+min) is non-zero |
| 561 | try std.testing.expectEqual(__sqrth(0x1p-14), 0x1p-7); | |
| 576 | try std.testing.expectEqual(sqrt_f16(0x1p-14), 0x1p-7); | |
| 562 | 577 | // sqrt(min subnormal) is non-zero |
| 563 | try std.testing.expectEqual(__sqrth(0x0.004p-14), 0x1p-12); | |
| 578 | try std.testing.expectEqual(sqrt_f16(0x0.004p-14), 0x1p-12); | |
| 564 | 579 | // sqrt(inf) is inf |
| 565 | try std.testing.expect(math.isInf(__sqrth(math.inf(f16)))); | |
| 580 | try std.testing.expect(math.isInf(sqrt_f16(math.inf(f16)))); | |
| 566 | 581 | // sqrt(nan) is nan |
| 567 | try std.testing.expect(math.isNan(__sqrth(math.nan(f16)))); | |
| 582 | try std.testing.expect(math.isNan(sqrt_f16(math.nan(f16)))); | |
| 568 | 583 | // sqrt(-ve) is nan |
| 569 | try std.testing.expect(math.isNan(__sqrth(-0x1p-14))); | |
| 570 | try std.testing.expect(math.isNan(__sqrth(-0x1p+0))); | |
| 571 | try std.testing.expect(math.isNan(__sqrth(-math.inf(f16)))); | |
| 584 | try std.testing.expect(math.isNan(sqrt_f16(-0x1p-14))); | |
| 585 | try std.testing.expect(math.isNan(sqrt_f16(-0x1p+0))); | |
| 586 | try std.testing.expect(math.isNan(sqrt_f16(-math.inf(f16)))); | |
| 572 | 587 | // random arguments |
| 573 | try std.testing.expectEqual(__sqrth(0x1.1p14), 0x1.08p7); | |
| 574 | try std.testing.expectEqual(__sqrth(0x1.C9p-12), 0x1.56p-6); | |
| 575 | try std.testing.expectEqual(__sqrth(0x1.CE8p-7), 0x1.E68p-4); | |
| 576 | try std.testing.expectEqual(__sqrth(0x1.134p-7), 0x1.778p-4); | |
| 577 | try std.testing.expectEqual(__sqrth(0x1.E9Cp-10), 0x1.62p-5); | |
| 578 | try std.testing.expectEqual(__sqrth(0x1.3Dp9), 0x1.92Cp4); | |
| 579 | try std.testing.expectEqual(__sqrth(0x1.AA4p8), 0x1.4A4p4); | |
| 580 | try std.testing.expectEqual(__sqrth(0x1.8A8p4), 0x1.3DCp2); | |
| 581 | try std.testing.expectEqual(__sqrth(0x1.8Fp-7), 0x1.C4p-4); | |
| 582 | try std.testing.expectEqual(__sqrth(0x1.584p-11), 0x1.A3Cp-6); | |
| 588 | try std.testing.expectEqual(sqrt_f16(0x1.1p14), 0x1.08p7); | |
| 589 | try std.testing.expectEqual(sqrt_f16(0x1.C9p-12), 0x1.56p-6); | |
| 590 | try std.testing.expectEqual(sqrt_f16(0x1.CE8p-7), 0x1.E68p-4); | |
| 591 | try std.testing.expectEqual(sqrt_f16(0x1.134p-7), 0x1.778p-4); | |
| 592 | try std.testing.expectEqual(sqrt_f16(0x1.E9Cp-10), 0x1.62p-5); | |
| 593 | try std.testing.expectEqual(sqrt_f16(0x1.3Dp9), 0x1.92Cp4); | |
| 594 | try std.testing.expectEqual(sqrt_f16(0x1.AA4p8), 0x1.4A4p4); | |
| 595 | try std.testing.expectEqual(sqrt_f16(0x1.8A8p4), 0x1.3DCp2); | |
| 596 | try std.testing.expectEqual(sqrt_f16(0x1.8Fp-7), 0x1.C4p-4); | |
| 597 | try std.testing.expectEqual(sqrt_f16(0x1.584p-11), 0x1.A3Cp-6); | |
| 583 | 598 | } |
| 584 | 599 | |
| 585 | test "sqrtf" { | |
| 600 | test "sqrt_f32" { | |
| 586 | 601 | // sqrt(±0) is ±0 |
| 587 | try std.testing.expectEqual(sqrtf(0x0.0p0), 0x0.0p0); | |
| 588 | try std.testing.expectEqual(sqrtf(-0x0.0p0), -0x0.0p0); | |
| 602 | try std.testing.expectEqual(sqrt_f32(0x0.0p0), 0x0.0p0); | |
| 603 | try std.testing.expectEqual(sqrt_f32(-0x0.0p0), -0x0.0p0); | |
| 589 | 604 | // sqrt(+max) is finite |
| 590 | try std.testing.expectEqual(sqrtf(0x1.FFFFFEp127), 0x1.FFFFFEp63); | |
| 605 | try std.testing.expectEqual(sqrt_f32(0x1.FFFFFEp127), 0x1.FFFFFEp63); | |
| 591 | 606 | // sqrt(4)=2 |
| 592 | try std.testing.expectEqual(sqrtf(0x1p2), 0x1p1); | |
| 607 | try std.testing.expectEqual(sqrt_f32(0x1p2), 0x1p1); | |
| 593 | 608 | // sqrt(x) for x=1, 1±ulp |
| 594 | try std.testing.expectEqual(sqrtf(0x1p0), 0x1p0); | |
| 595 | try std.testing.expectEqual(sqrtf(0x1.000002p0), 0x1p0); | |
| 596 | try std.testing.expectEqual(sqrtf(0x1.FFFFFEp-1), 0x1.FFFFFEp-1); | |
| 609 | try std.testing.expectEqual(sqrt_f32(0x1p0), 0x1p0); | |
| 610 | try std.testing.expectEqual(sqrt_f32(0x1.000002p0), 0x1p0); | |
| 611 | try std.testing.expectEqual(sqrt_f32(0x1.FFFFFEp-1), 0x1.FFFFFEp-1); | |
| 597 | 612 | // sqrt(+min) is non-zero |
| 598 | try std.testing.expectEqual(sqrtf(0x1p-126), 0x1p-63); | |
| 613 | try std.testing.expectEqual(sqrt_f32(0x1p-126), 0x1p-63); | |
| 599 | 614 | // sqrt(min subnormal) is non-zero |
| 600 | try std.testing.expectEqual(sqrtf(0x0.000002p-126), 0x1.6a09e6p-75); | |
| 615 | try std.testing.expectEqual(sqrt_f32(0x0.000002p-126), 0x1.6a09e6p-75); | |
| 601 | 616 | // sqrt(inf) is inf |
| 602 | try std.testing.expect(math.isInf(sqrtf(math.inf(f32)))); | |
| 617 | try std.testing.expect(math.isInf(sqrt_f32(math.inf(f32)))); | |
| 603 | 618 | // sqrt(nan) is nan |
| 604 | try std.testing.expect(math.isNan(sqrtf(math.nan(f32)))); | |
| 619 | try std.testing.expect(math.isNan(sqrt_f32(math.nan(f32)))); | |
| 605 | 620 | // sqrt(-ve) is nan |
| 606 | try std.testing.expect(math.isNan(sqrtf(-0x1p-149))); | |
| 607 | try std.testing.expect(math.isNan(sqrtf(-0x1p0))); | |
| 608 | try std.testing.expect(math.isNan(sqrtf(-math.inf(f32)))); | |
| 621 | try std.testing.expect(math.isNan(sqrt_f32(-0x1p-149))); | |
| 622 | try std.testing.expect(math.isNan(sqrt_f32(-0x1p0))); | |
| 623 | try std.testing.expect(math.isNan(sqrt_f32(-math.inf(f32)))); | |
| 609 | 624 | // random arguments |
| 610 | try std.testing.expectEqual(sqrtf(0x1.4DD57Ep77), 0x1.9D6DA8p38); | |
| 611 | try std.testing.expectEqual(sqrtf(0x1.871848p102), 0x1.3C6AFAp51); | |
| 612 | try std.testing.expectEqual(sqrtf(0x1.A1D748p-112), 0x1.470EFCp-56); | |
| 613 | try std.testing.expectEqual(sqrtf(0x1.E626C2p18), 0x1.60C80Ep9); | |
| 614 | try std.testing.expectEqual(sqrtf(0x1.E80E66p-29), 0x1.F3E282p-15); | |
| 615 | try std.testing.expectEqual(sqrtf(0x1.B47204p89), 0x1.D8B732p44); | |
| 616 | try std.testing.expectEqual(sqrtf(0x1.77F45p15), 0x1.B6BC3Ap7); | |
| 617 | try std.testing.expectEqual(sqrtf(0x1.AD5F5p-48), 0x1.4B8A72p-24); | |
| 618 | try std.testing.expectEqual(sqrtf(0x1.91A39p-76), 0x1.40A7A8p-38); | |
| 619 | try std.testing.expectEqual(sqrtf(0x1.DAE088p79), 0x1.ED16DCp39); | |
| 625 | try std.testing.expectEqual(sqrt_f32(0x1.4DD57Ep77), 0x1.9D6DA8p38); | |
| 626 | try std.testing.expectEqual(sqrt_f32(0x1.871848p102), 0x1.3C6AFAp51); | |
| 627 | try std.testing.expectEqual(sqrt_f32(0x1.A1D748p-112), 0x1.470EFCp-56); | |
| 628 | try std.testing.expectEqual(sqrt_f32(0x1.E626C2p18), 0x1.60C80Ep9); | |
| 629 | try std.testing.expectEqual(sqrt_f32(0x1.E80E66p-29), 0x1.F3E282p-15); | |
| 630 | try std.testing.expectEqual(sqrt_f32(0x1.B47204p89), 0x1.D8B732p44); | |
| 631 | try std.testing.expectEqual(sqrt_f32(0x1.77F45p15), 0x1.B6BC3Ap7); | |
| 632 | try std.testing.expectEqual(sqrt_f32(0x1.AD5F5p-48), 0x1.4B8A72p-24); | |
| 633 | try std.testing.expectEqual(sqrt_f32(0x1.91A39p-76), 0x1.40A7A8p-38); | |
| 634 | try std.testing.expectEqual(sqrt_f32(0x1.DAE088p79), 0x1.ED16DCp39); | |
| 620 | 635 | } |
| 621 | 636 | |
| 622 | test "sqrt" { | |
| 637 | test "sqrt_f64" { | |
| 623 | 638 | // sqrt(±0) is ±0 |
| 624 | try std.testing.expectEqual(sqrt(0x0.0p0), 0x0.0p0); | |
| 625 | try std.testing.expectEqual(sqrt(-0x0.0p0), -0x0.0p0); | |
| 639 | try std.testing.expectEqual(sqrt_f64(0x0.0p0), 0x0.0p0); | |
| 640 | try std.testing.expectEqual(sqrt_f64(-0x0.0p0), -0x0.0p0); | |
| 626 | 641 | // sqrt(+max) is finite |
| 627 | try std.testing.expectEqual(sqrt(math.floatMax(f64)), 0x1.FFFFFFFFFFFFFp511); | |
| 642 | try std.testing.expectEqual(sqrt_f64(math.floatMax(f64)), 0x1.FFFFFFFFFFFFFp511); | |
| 628 | 643 | // sqrt(4)=2 |
| 629 | try std.testing.expectEqual(sqrt(0x1p2), 0x1p1); | |
| 644 | try std.testing.expectEqual(sqrt_f64(0x1p2), 0x1p1); | |
| 630 | 645 | // sqrt(x) for x=1, 1±ulp |
| 631 | try std.testing.expectEqual(sqrt(0x1p0), 0x1p0); | |
| 632 | try std.testing.expectEqual(sqrt(0x1p0 + math.floatEps(f64)), 0x1p0); | |
| 633 | try std.testing.expectEqual(sqrt(0x1p0 - math.floatEps(f64)), 0x1.FFFFFFFFFFFFFp-1); | |
| 646 | try std.testing.expectEqual(sqrt_f64(0x1p0), 0x1p0); | |
| 647 | try std.testing.expectEqual(sqrt_f64(0x1p0 + math.floatEps(f64)), 0x1p0); | |
| 648 | try std.testing.expectEqual(sqrt_f64(0x1p0 - math.floatEps(f64)), 0x1.FFFFFFFFFFFFFp-1); | |
| 634 | 649 | // sqrt(+min) is non-zero |
| 635 | try std.testing.expectEqual(sqrt(math.floatMin(f64)), 0x1p-511); | |
| 650 | try std.testing.expectEqual(sqrt_f64(math.floatMin(f64)), 0x1p-511); | |
| 636 | 651 | // sqrt(min subnormal) is non-zero |
| 637 | try std.testing.expectEqual(sqrt(math.floatTrueMin(f64)), 0x1p-537); | |
| 652 | try std.testing.expectEqual(sqrt_f64(math.floatTrueMin(f64)), 0x1p-537); | |
| 638 | 653 | // sqrt(inf) is inf |
| 639 | try std.testing.expect(math.isInf(sqrt(math.inf(f64)))); | |
| 654 | try std.testing.expect(math.isInf(sqrt_f64(math.inf(f64)))); | |
| 640 | 655 | // sqrt(nan) is nan |
| 641 | try std.testing.expect(math.isNan(sqrt(math.nan(f64)))); | |
| 656 | try std.testing.expect(math.isNan(sqrt_f64(math.nan(f64)))); | |
| 642 | 657 | // sqrt(-ve) is nan |
| 643 | try std.testing.expect(math.isNan(sqrt(-0x1p-1074))); | |
| 644 | try std.testing.expect(math.isNan(sqrt(-0x1p0))); | |
| 645 | try std.testing.expect(math.isNan(sqrt(-math.inf(f64)))); | |
| 658 | try std.testing.expect(math.isNan(sqrt_f64(-0x1p-1074))); | |
| 659 | try std.testing.expect(math.isNan(sqrt_f64(-0x1p0))); | |
| 660 | try std.testing.expect(math.isNan(sqrt_f64(-math.inf(f64)))); | |
| 646 | 661 | // random arguments |
| 647 | try std.testing.expectEqual(sqrt(0x1.27D3510D4789Bp471), 0x1.852E97E58CFB7p235); | |
| 648 | try std.testing.expectEqual(sqrt(0x1.8C4FCD5A07846p791), 0x1.C27504E56D938p395); | |
| 649 | try std.testing.expectEqual(sqrt(0x1.B1B69324F96E7p-137), 0x1.D73BD0414D8BFp-69); | |
| 650 | try std.testing.expectEqual(sqrt(0x1.1CBD179A811FEp278), 0x1.0DFCB9A114A61p139); | |
| 651 | try std.testing.expectEqual(sqrt(0x1.1D0C7EFB04A56p917), 0x1.7E0708A25DDCDp458); | |
| 652 | try std.testing.expectEqual(sqrt(0x1.21B355DA8C94Bp-249), 0x1.8121CBE2608E3p-125); | |
| 653 | try std.testing.expectEqual(sqrt(0x1.63024D4C5E987p487), 0x1.AA56AEA589DCDp243); | |
| 654 | try std.testing.expectEqual(sqrt(0x1.45AC3BE941F6Ep339), 0x1.9857F3F453E2Dp169); | |
| 655 | try std.testing.expectEqual(sqrt(0x1.3B719C733AA24p267), 0x1.91E12E3AC8F71p133); | |
| 656 | try std.testing.expectEqual(sqrt(0x1.0B150433A2275p357), 0x1.71CAB87F8277Cp178); | |
| 662 | try std.testing.expectEqual(sqrt_f64(0x1.27D3510D4789Bp471), 0x1.852E97E58CFB7p235); | |
| 663 | try std.testing.expectEqual(sqrt_f64(0x1.8C4FCD5A07846p791), 0x1.C27504E56D938p395); | |
| 664 | try std.testing.expectEqual(sqrt_f64(0x1.B1B69324F96E7p-137), 0x1.D73BD0414D8BFp-69); | |
| 665 | try std.testing.expectEqual(sqrt_f64(0x1.1CBD179A811FEp278), 0x1.0DFCB9A114A61p139); | |
| 666 | try std.testing.expectEqual(sqrt_f64(0x1.1D0C7EFB04A56p917), 0x1.7E0708A25DDCDp458); | |
| 667 | try std.testing.expectEqual(sqrt_f64(0x1.21B355DA8C94Bp-249), 0x1.8121CBE2608E3p-125); | |
| 668 | try std.testing.expectEqual(sqrt_f64(0x1.63024D4C5E987p487), 0x1.AA56AEA589DCDp243); | |
| 669 | try std.testing.expectEqual(sqrt_f64(0x1.45AC3BE941F6Ep339), 0x1.9857F3F453E2Dp169); | |
| 670 | try std.testing.expectEqual(sqrt_f64(0x1.3B719C733AA24p267), 0x1.91E12E3AC8F71p133); | |
| 671 | try std.testing.expectEqual(sqrt_f64(0x1.0B150433A2275p357), 0x1.71CAB87F8277Cp178); | |
| 657 | 672 | } |
| 658 | 673 | |
| 659 | 674 | test "__sqrtx" { |
| 660 | 675 | // sqrt(±0) is ±0 |
| 661 | try std.testing.expectEqual(__sqrtx(0x0.0p0), 0x0.0p0); | |
| 662 | try std.testing.expectEqual(__sqrtx(-0x0.0p0), -0x0.0p0); | |
| 676 | try std.testing.expectEqual(sqrt_f80(0x0.0p0), 0x0.0p0); | |
| 677 | try std.testing.expectEqual(sqrt_f80(-0x0.0p0), -0x0.0p0); | |
| 663 | 678 | // sqrt(+max) is finite |
| 664 | try std.testing.expectEqual(__sqrtx(math.floatMax(f80)), 0x1.FFFFFFFFFFFFFFFEp8191); | |
| 679 | try std.testing.expectEqual(sqrt_f80(math.floatMax(f80)), 0x1.FFFFFFFFFFFFFFFEp8191); | |
| 665 | 680 | // sqrt(4)=2 |
| 666 | try std.testing.expectEqual(__sqrtx(0x1p2), 0x1p1); | |
| 681 | try std.testing.expectEqual(sqrt_f80(0x1p2), 0x1p1); | |
| 667 | 682 | // sqrt(x) for x=1, 1±ulp |
| 668 | try std.testing.expectEqual(__sqrtx(0x1p0), 0x1p0); | |
| 669 | try std.testing.expectEqual(__sqrtx(0x1p0 + math.floatEps(f80)), 0x1p0); | |
| 670 | try std.testing.expectEqual(__sqrtx(0x1p0 - math.floatEps(f80)), 0x1.FFFFFFFFFFFFFFFEp-1); | |
| 683 | try std.testing.expectEqual(sqrt_f80(0x1p0), 0x1p0); | |
| 684 | try std.testing.expectEqual(sqrt_f80(0x1p0 + math.floatEps(f80)), 0x1p0); | |
| 685 | try std.testing.expectEqual(sqrt_f80(0x1p0 - math.floatEps(f80)), 0x1.FFFFFFFFFFFFFFFEp-1); | |
| 671 | 686 | // sqrt(+min) is non-zero |
| 672 | try std.testing.expectEqual(__sqrtx(math.floatMin(f80)), 0x1p-8191); | |
| 687 | try std.testing.expectEqual(sqrt_f80(math.floatMin(f80)), 0x1p-8191); | |
| 673 | 688 | // sqrt(min subnormal) is non-zero |
| 674 | try std.testing.expectEqual(__sqrtx(math.floatTrueMin(f80)), 0x1.6A09E667F3BCC908p-8223); | |
| 689 | try std.testing.expectEqual(sqrt_f80(math.floatTrueMin(f80)), 0x1.6A09E667F3BCC908p-8223); | |
| 675 | 690 | // sqrt(inf) is inf |
| 676 | try std.testing.expect(math.isInf(__sqrtx(math.inf(f80)))); | |
| 691 | try std.testing.expect(math.isInf(sqrt_f80(math.inf(f80)))); | |
| 677 | 692 | // sqrt(nan) is nan |
| 678 | try std.testing.expect(math.isNan(__sqrtx(math.nan(f80)))); | |
| 693 | try std.testing.expect(math.isNan(sqrt_f80(math.nan(f80)))); | |
| 679 | 694 | // sqrt(-ve) is nan |
| 680 | try std.testing.expect(math.isNan(__sqrtx(-0x1p-16442))); | |
| 681 | try std.testing.expect(math.isNan(__sqrtx(-0x1p0))); | |
| 682 | try std.testing.expect(math.isNan(__sqrtx(-math.inf(f80)))); | |
| 695 | try std.testing.expect(math.isNan(sqrt_f80(-0x1p-16442))); | |
| 696 | try std.testing.expect(math.isNan(sqrt_f80(-0x1p0))); | |
| 697 | try std.testing.expect(math.isNan(sqrt_f80(-math.inf(f80)))); | |
| 683 | 698 | // random arguments |
| 684 | try std.testing.expectEqual(__sqrtx(0x1.087F3953486918A4p15482), 0x1.0436BBE03D02F32p7741); | |
| 685 | try std.testing.expectEqual(__sqrtx(0x1.530CF9E2AE84D8Fp-6330), 0x1.269CFEF51933BE58p-3165); | |
| 686 | try std.testing.expectEqual(__sqrtx(0x1.3F971515EADD574Ap5713), 0x1.9483232AB780B006p2856); | |
| 687 | try std.testing.expectEqual(__sqrtx(0x1.4CC0DC7379222954p864), 0x1.23DD4D0A4758C2Cp432); | |
| 688 | try std.testing.expectEqual(__sqrtx(0x1.920E5649559A839Ep-3181), 0x1.C5B5BC0F98DD83D2p-1591); | |
| 689 | try std.testing.expectEqual(__sqrtx(0x1.2E59726F87CD1746p-629), 0x1.8973327E95CB350Cp-315); | |
| 690 | try std.testing.expectEqual(__sqrtx(0x1.D3A16391F57B4D64p-9034), 0x1.59FF08B7DEEF5DB2p-4517); | |
| 691 | try std.testing.expectEqual(__sqrtx(0x1.E7053D8DAA49BCEEp-11411), 0x1.F35AA3EA5E18E344p-5706); | |
| 692 | try std.testing.expectEqual(__sqrtx(0x1.797ED0B05DD4A984p7521), 0x1.B7A22E40C6A7867Ap3760); | |
| 693 | try std.testing.expectEqual(__sqrtx(0x1.FC50806445C7226Ap15371), 0x1.FE2766142653F5BEp7685); | |
| 699 | try std.testing.expectEqual(sqrt_f80(0x1.087F3953486918A4p15482), 0x1.0436BBE03D02F32p7741); | |
| 700 | try std.testing.expectEqual(sqrt_f80(0x1.530CF9E2AE84D8Fp-6330), 0x1.269CFEF51933BE58p-3165); | |
| 701 | try std.testing.expectEqual(sqrt_f80(0x1.3F971515EADD574Ap5713), 0x1.9483232AB780B006p2856); | |
| 702 | try std.testing.expectEqual(sqrt_f80(0x1.4CC0DC7379222954p864), 0x1.23DD4D0A4758C2Cp432); | |
| 703 | try std.testing.expectEqual(sqrt_f80(0x1.920E5649559A839Ep-3181), 0x1.C5B5BC0F98DD83D2p-1591); | |
| 704 | try std.testing.expectEqual(sqrt_f80(0x1.2E59726F87CD1746p-629), 0x1.8973327E95CB350Cp-315); | |
| 705 | try std.testing.expectEqual(sqrt_f80(0x1.D3A16391F57B4D64p-9034), 0x1.59FF08B7DEEF5DB2p-4517); | |
| 706 | try std.testing.expectEqual(sqrt_f80(0x1.E7053D8DAA49BCEEp-11411), 0x1.F35AA3EA5E18E344p-5706); | |
| 707 | try std.testing.expectEqual(sqrt_f80(0x1.797ED0B05DD4A984p7521), 0x1.B7A22E40C6A7867Ap3760); | |
| 708 | try std.testing.expectEqual(sqrt_f80(0x1.FC50806445C7226Ap15371), 0x1.FE2766142653F5BEp7685); | |
| 694 | 709 | } |
| 695 | 710 | |
| 696 | test "sqrtq" { | |
| 711 | test "sqrt_f128" { | |
| 697 | 712 | // sqrt(±0) is ±0 |
| 698 | try std.testing.expectEqual(sqrtq(0x0.0p0), 0x0.0p0); | |
| 699 | try std.testing.expectEqual(sqrtq(-0x0.0p0), -0x0.0p0); | |
| 713 | try std.testing.expectEqual(sqrt_f128(0x0.0p0), 0x0.0p0); | |
| 714 | try std.testing.expectEqual(sqrt_f128(-0x0.0p0), -0x0.0p0); | |
| 700 | 715 | // sqrt(+max) is finite |
| 701 | try std.testing.expectEqual(sqrtq(math.floatMax(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp8191); | |
| 716 | try std.testing.expectEqual(sqrt_f128(math.floatMax(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp8191); | |
| 702 | 717 | // sqrt(4)=2 |
| 703 | try std.testing.expectEqual(sqrtq(0x1p2), 0x1p1); | |
| 718 | try std.testing.expectEqual(sqrt_f128(0x1p2), 0x1p1); | |
| 704 | 719 | // sqrt(x) for x=1, 1±ulp |
| 705 | try std.testing.expectEqual(sqrtq(0x1p0), 0x1p0); | |
| 706 | try std.testing.expectEqual(sqrtq(0x1p0 + math.floatEps(f128)), 0x1p0); | |
| 707 | try std.testing.expectEqual(sqrtq(0x1p0 - math.floatEps(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp-1); | |
| 720 | try std.testing.expectEqual(sqrt_f128(0x1p0), 0x1p0); | |
| 721 | try std.testing.expectEqual(sqrt_f128(0x1p0 + math.floatEps(f128)), 0x1p0); | |
| 722 | try std.testing.expectEqual(sqrt_f128(0x1p0 - math.floatEps(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp-1); | |
| 708 | 723 | // sqrt(+min) is non-zero |
| 709 | try std.testing.expectEqual(sqrtq(math.floatMin(f128)), 0x1p-8191); | |
| 724 | try std.testing.expectEqual(sqrt_f128(math.floatMin(f128)), 0x1p-8191); | |
| 710 | 725 | // sqrt(min subnormal) is non-zero |
| 711 | try std.testing.expectEqual(sqrtq(math.floatTrueMin(f128)), 0x1p-8247); | |
| 726 | try std.testing.expectEqual(sqrt_f128(math.floatTrueMin(f128)), 0x1p-8247); | |
| 712 | 727 | // sqrt(inf) is inf |
| 713 | try std.testing.expect(math.isInf(sqrtq(math.inf(f128)))); | |
| 728 | try std.testing.expect(math.isInf(sqrt_f128(math.inf(f128)))); | |
| 714 | 729 | // sqrt(nan) is nan |
| 715 | try std.testing.expect(math.isNan(sqrtq(math.nan(f128)))); | |
| 730 | try std.testing.expect(math.isNan(sqrt_f128(math.nan(f128)))); | |
| 716 | 731 | // sqrt(-ve) is nan |
| 717 | try std.testing.expect(math.isNan(sqrtq(-0x1p-16442))); | |
| 718 | try std.testing.expect(math.isNan(sqrtq(-0x1p0))); | |
| 719 | try std.testing.expect(math.isNan(sqrtq(-math.inf(f128)))); | |
| 732 | try std.testing.expect(math.isNan(sqrt_f128(-0x1p-16442))); | |
| 733 | try std.testing.expect(math.isNan(sqrt_f128(-0x1p0))); | |
| 734 | try std.testing.expect(math.isNan(sqrt_f128(-math.inf(f128)))); | |
| 720 | 735 | // random arguments |
| 721 | try std.testing.expectEqual(sqrtq(0x1.B6942D29A331751600C9F3AF7E5Fp3363), 0x1.D9DE9AFEF0F2D25586A50CA39D4Dp1681); | |
| 722 | try std.testing.expectEqual(sqrtq(0x1.5E65C405F84D471A8070ADD7A42Dp11765), 0x1.A78F7F9452B4D9EC2403C81D9D42p5882); | |
| 723 | try std.testing.expectEqual(sqrtq(0x1.B42334D68F8016D8AE6F5E22B044p-5624), 0x1.4E247A7F2FF2A325E9377BB09C8p-2812); | |
| 724 | try std.testing.expectEqual(sqrtq(0x1.E61715047F80F2E0B9382B38E06Bp10062), 0x1.60C25D9DFDC0116B78EF5AFDE0E9p5031); | |
| 725 | try std.testing.expectEqual(sqrtq(0x1.2ED0B53B494CB55A7B04E653D40Ep-1026), 0x1.166CE78D658D2453D700B04C5748p-513); | |
| 726 | try std.testing.expectEqual(sqrtq(0x1.1BA756B9790E78A4E6F0B083AA89p1835), 0x1.7D1767EA3303DB7A46940033988p917); | |
| 727 | try std.testing.expectEqual(sqrtq(0x1.5B6C574319C1120335C8E1609704p4512), 0x1.2A3A8A415BB1648C548FBA2A4182p2256); | |
| 728 | try std.testing.expectEqual(sqrtq(0x1.FF91E8CDEE1552A2B74E77B602Ep14953), 0x1.FFC8F171267D4FE75CBE7AB4D851p7476); | |
| 729 | try std.testing.expectEqual(sqrtq(0x1.9B1837CFC629A1B6B1BB97099E7Dp2892), 0x1.4468511B909EAF8641BD59105A6Bp1446); | |
| 730 | try std.testing.expectEqual(sqrtq(0x1.0E2115475E64A92340914E7F7B37p-13951), 0x1.73E536F82F414134012F55BA5368p-6976); | |
| 736 | try std.testing.expectEqual(sqrt_f128(0x1.B6942D29A331751600C9F3AF7E5Fp3363), 0x1.D9DE9AFEF0F2D25586A50CA39D4Dp1681); | |
| 737 | try std.testing.expectEqual(sqrt_f128(0x1.5E65C405F84D471A8070ADD7A42Dp11765), 0x1.A78F7F9452B4D9EC2403C81D9D42p5882); | |
| 738 | try std.testing.expectEqual(sqrt_f128(0x1.B42334D68F8016D8AE6F5E22B044p-5624), 0x1.4E247A7F2FF2A325E9377BB09C8p-2812); | |
| 739 | try std.testing.expectEqual(sqrt_f128(0x1.E61715047F80F2E0B9382B38E06Bp10062), 0x1.60C25D9DFDC0116B78EF5AFDE0E9p5031); | |
| 740 | try std.testing.expectEqual(sqrt_f128(0x1.2ED0B53B494CB55A7B04E653D40Ep-1026), 0x1.166CE78D658D2453D700B04C5748p-513); | |
| 741 | try std.testing.expectEqual(sqrt_f128(0x1.1BA756B9790E78A4E6F0B083AA89p1835), 0x1.7D1767EA3303DB7A46940033988p917); | |
| 742 | try std.testing.expectEqual(sqrt_f128(0x1.5B6C574319C1120335C8E1609704p4512), 0x1.2A3A8A415BB1648C548FBA2A4182p2256); | |
| 743 | try std.testing.expectEqual(sqrt_f128(0x1.FF91E8CDEE1552A2B74E77B602Ep14953), 0x1.FFC8F171267D4FE75CBE7AB4D851p7476); | |
| 744 | try std.testing.expectEqual(sqrt_f128(0x1.9B1837CFC629A1B6B1BB97099E7Dp2892), 0x1.4468511B909EAF8641BD59105A6Bp1446); | |
| 745 | try std.testing.expectEqual(sqrt_f128(0x1.0E2115475E64A92340914E7F7B37p-13951), 0x1.73E536F82F414134012F55BA5368p-6976); | |
| 731 | 746 | } |
lib/compiler_rt/subdf3.zig deleted-24| ... | ... | @@ -1,24 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const addf3 = @import("./addf3.zig").addf3; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_dsub, "__aeabi_dsub"); | |
| 8 | } else { | |
| 9 | symbol(&__subdf3, "__subdf3"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | fn __subdf3(a: f64, b: f64) callconv(.c) f64 { | |
| 14 | return sub(a, b); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_dsub(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { | |
| 18 | return sub(a, b); | |
| 19 | } | |
| 20 | ||
| 21 | inline fn sub(a: f64, b: f64) f64 { | |
| 22 | const neg_b = @as(f64, @bitCast(@as(u64, @bitCast(b)) ^ (@as(u64, 1) << 63))); | |
| 23 | return addf3(f64, a, neg_b); | |
| 24 | } |
lib/compiler_rt/subhf3.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const addf3 = @import("./addf3.zig").addf3; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__subhf3, "__subhf3"); | |
| 7 | } | |
| 8 | ||
| 9 | fn __subhf3(a: f16, b: f16) callconv(.c) f16 { | |
| 10 | const neg_b = @as(f16, @bitCast(@as(u16, @bitCast(b)) ^ (@as(u16, 1) << 15))); | |
| 11 | return addf3(f16, a, neg_b); | |
| 12 | } |
lib/compiler_rt/subsf3.zig deleted-24| ... | ... | @@ -1,24 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const addf3 = @import("./addf3.zig").addf3; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_fsub, "__aeabi_fsub"); | |
| 8 | } else { | |
| 9 | symbol(&__subsf3, "__subsf3"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | fn __subsf3(a: f32, b: f32) callconv(.c) f32 { | |
| 14 | return sub(a, b); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_fsub(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 18 | return sub(a, b); | |
| 19 | } | |
| 20 | ||
| 21 | inline fn sub(a: f32, b: f32) f32 { | |
| 22 | const neg_b = @as(f32, @bitCast(@as(u32, @bitCast(b)) ^ (@as(u32, 1) << 31))); | |
| 23 | return addf3(f32, a, neg_b); | |
| 24 | } |
lib/compiler_rt/subtf3.zig deleted-27| ... | ... | @@ -1,27 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const addf3 = @import("./addf3.zig").addf3; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) { | |
| 7 | symbol(&__subtf3, "__subkf3"); | |
| 8 | } else if (compiler_rt.want_sparc64_abi) { | |
| 9 | symbol(&_Qp_sub, "_Qp_sub"); | |
| 10 | } else if (compiler_rt.want_sparc32_abi) { | |
| 11 | symbol(&__subtf3, "_Q_sub"); | |
| 12 | } | |
| 13 | symbol(&__subtf3, "__subtf3"); | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __subtf3(a: f128, b: f128) callconv(.c) f128 { | |
| 17 | return sub(a, b); | |
| 18 | } | |
| 19 | ||
| 20 | fn _Qp_sub(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { | |
| 21 | c.* = sub(a.*, b.*); | |
| 22 | } | |
| 23 | ||
| 24 | inline fn sub(a: f128, b: f128) f128 { | |
| 25 | const neg_b = @as(f128, @bitCast(@as(u128, @bitCast(b)) ^ (@as(u128, 1) << 127))); | |
| 26 | return addf3(f128, a, neg_b); | |
| 27 | } |
lib/compiler_rt/subvdi3.zig+3-2| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 2 | 1 | const testing = @import("std").testing; |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 3 | const symbol = compiler_rt.symbol; | |
| 3 | 4 | |
| 4 | 5 | comptime { |
| 5 | 6 | symbol(&__subvdi3, "__subvdi3"); |
| ... | ... | @@ -9,7 +10,7 @@ pub fn __subvdi3(a: i64, b: i64) callconv(.c) i64 { |
| 9 | 10 | const sum = a -% b; |
| 10 | 11 | // Overflow occurred iff the operands have opposite signs, and the sign of the |
| 11 | 12 | // sum is the opposite of the lhs sign. |
| 12 | if (((a ^ b) & (sum ^ a)) < 0) @panic("compiler-rt: integer overflow"); | |
| 13 | if (((a ^ b) & (sum ^ a)) < 0) @panic("integer overflow"); | |
| 13 | 14 | return sum; |
| 14 | 15 | } |
| 15 | 16 |
lib/compiler_rt/subvsi3.zig+1-1| ... | ... | @@ -10,7 +10,7 @@ pub fn __subvsi3(a: i32, b: i32) callconv(.c) i32 { |
| 10 | 10 | const sum = a -% b; |
| 11 | 11 | // Overflow occurred iff the operands have opposite signs, and the sign of the |
| 12 | 12 | // sum is the opposite of the lhs sign. |
| 13 | if (((a ^ b) & (sum ^ a)) < 0) @panic("compiler-rt: integer overflow"); | |
| 13 | if (((a ^ b) & (sum ^ a)) < 0) @panic("integer overflow"); | |
| 14 | 14 | return sum; |
| 15 | 15 | } |
| 16 | 16 |
lib/compiler_rt/subxf3.zig deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | ||
| 4 | comptime { | |
| 5 | symbol(&__subxf3, "__subxf3"); | |
| 6 | } | |
| 7 | ||
| 8 | fn __subxf3(a: f80, b: f80) callconv(.c) f80 { | |
| 9 | var b_rep = std.math.F80.fromFloat(b); | |
| 10 | b_rep.exp ^= 0x8000; | |
| 11 | const neg_b = b_rep.toFloat(); | |
| 12 | return a + neg_b; | |
| 13 | } |
lib/compiler_rt/tan.zig+52-33| ... | ... | @@ -21,13 +21,13 @@ const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; |
| 21 | 21 | |
| 22 | 22 | const arch = builtin.cpu.arch; |
| 23 | 23 | const compiler_rt = @import("../compiler_rt.zig"); |
| 24 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 24 | const symbol = compiler_rt.symbol; | |
| 25 | 25 | |
| 26 | 26 | comptime { |
| 27 | symbol(&tanh, "__tanh"); | |
| 27 | symbol(&__tanh, "__tanh"); | |
| 28 | 28 | symbol(&tanf, "tanf"); |
| 29 | 29 | symbol(&tan, "tan"); |
| 30 | symbol(&tanx, "__tanx"); | |
| 30 | symbol(&__tanx, "__tanx"); | |
| 31 | 31 | if (compiler_rt.want_ppc_abi) { |
| 32 | 32 | symbol(&tanq, "tanf128"); |
| 33 | 33 | } |
| ... | ... | @@ -35,12 +35,18 @@ comptime { |
| 35 | 35 | symbol(&tanl, "tanl"); |
| 36 | 36 | } |
| 37 | 37 | |
| 38 | pub fn tanh(x: f16) callconv(.c) f16 { | |
| 38 | fn __tanh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 39 | return compiler_rt.f16.toAbi(tan_f16(compiler_rt.f16.fromAbi(x))); | |
| 40 | } | |
| 41 | pub fn tan_f16(x: f16) f16 { | |
| 39 | 42 | // TODO: more efficient implementation |
| 40 | return @floatCast(tanf(x)); | |
| 43 | return @floatCast(tan_f32(x)); | |
| 41 | 44 | } |
| 42 | 45 | |
| 43 | pub fn tanf(x: f32) callconv(.c) f32 { | |
| 46 | fn tanf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 47 | return compiler_rt.f32.toAbi(tan_f32(compiler_rt.f32.fromAbi(x))); | |
| 48 | } | |
| 49 | pub fn tan_f32(x: f32) f32 { | |
| 44 | 50 | // Small multiples of pi/2 rounded to double precision. |
| 45 | 51 | const t1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 |
| 46 | 52 | const t2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 |
| ... | ... | @@ -90,7 +96,10 @@ pub fn tanf(x: f32) callconv(.c) f32 { |
| 90 | 96 | return kernel.tandf(y, n & 1 != 0); |
| 91 | 97 | } |
| 92 | 98 | |
| 93 | pub fn tan(x: f64) callconv(.c) f64 { | |
| 99 | fn tan(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 100 | return compiler_rt.f64.toAbi(tan_f64(compiler_rt.f64.fromAbi(x))); | |
| 101 | } | |
| 102 | pub fn tan_f64(x: f64) f64 { | |
| 94 | 103 | var ix = @as(u64, @bitCast(x)) >> 32; |
| 95 | 104 | ix &= 0x7fffffff; |
| 96 | 105 | |
| ... | ... | @@ -120,7 +129,10 @@ pub fn tan(x: f64) callconv(.c) f64 { |
| 120 | 129 | return kernel.tan(y[0], y[1], n & 1 != 0); |
| 121 | 130 | } |
| 122 | 131 | |
| 123 | pub fn tanx(x: f80) callconv(.c) f80 { | |
| 132 | fn __tanx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 133 | return compiler_rt.f80.toAbi(tan_f80(compiler_rt.f80.fromAbi(x))); | |
| 134 | } | |
| 135 | pub fn tan_f80(x: f80) f80 { | |
| 124 | 136 | const se = ld.signExponent(x) & 0x7fff; |
| 125 | 137 | if (se == 0x7fff) { |
| 126 | 138 | return x - x; |
| ... | ... | @@ -141,7 +153,10 @@ pub fn tanx(x: f80) callconv(.c) f80 { |
| 141 | 153 | return kernel.tanx(y[0], y[1], n & 1); |
| 142 | 154 | } |
| 143 | 155 | |
| 144 | pub fn tanq(x: f128) callconv(.c) f128 { | |
| 156 | fn tanq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 157 | return compiler_rt.f128.toAbi(tan_f128(compiler_rt.f128.fromAbi(x))); | |
| 158 | } | |
| 159 | pub fn tan_f128(x: f128) f128 { | |
| 145 | 160 | const se = ld.signExponent(x) & 0x7fff; |
| 146 | 161 | if (se == 0x7fff) { |
| 147 | 162 | return x - x; |
| ... | ... | @@ -164,18 +179,21 @@ pub fn tanq(x: f128) callconv(.c) f128 { |
| 164 | 179 | |
| 165 | 180 | pub fn tanl(x: c_longdouble) callconv(.c) c_longdouble { |
| 166 | 181 | switch (@typeInfo(c_longdouble).float.bits) { |
| 167 | 64 => return tan(x), | |
| 168 | 80 => return tanx(x), | |
| 169 | 128 => return tanq(x), | |
| 170 | else => @compileError("unreachable"), | |
| 182 | 64 => return tan_f64(x), | |
| 183 | 80 => return tan_f80(x), | |
| 184 | 128 => return tan_f128(x), | |
| 185 | else => comptime unreachable, | |
| 171 | 186 | } |
| 172 | 187 | } |
| 173 | 188 | |
| 174 | 189 | fn testTanNormal(comptime T: type) !void { |
| 175 | 190 | const f = switch (T) { |
| 176 | f32 => tanf, | |
| 177 | f64 => tan, | |
| 178 | else => @compileError("unimplemented"), | |
| 191 | f16 => tan_f16, | |
| 192 | f32 => tan_f32, | |
| 193 | f64 => tan_f64, | |
| 194 | f80 => tan_f80, | |
| 195 | f128 => tan_f128, | |
| 196 | else => comptime unreachable, | |
| 179 | 197 | }; |
| 180 | 198 | const epsilon = 0.00001; |
| 181 | 199 | |
| ... | ... | @@ -189,11 +207,12 @@ fn testTanNormal(comptime T: type) !void { |
| 189 | 207 | |
| 190 | 208 | fn testTanSpecial(comptime T: type) !void { |
| 191 | 209 | const f = switch (T) { |
| 192 | f32 => tanf, | |
| 193 | f64 => tan, | |
| 194 | f80 => tanx, | |
| 195 | f128 => tanq, | |
| 196 | else => @compileError("unimplemented"), | |
| 210 | f16 => tan_f16, | |
| 211 | f32 => tan_f32, | |
| 212 | f64 => tan_f64, | |
| 213 | f80 => tan_f80, | |
| 214 | f128 => tan_f128, | |
| 215 | else => comptime unreachable, | |
| 197 | 216 | }; |
| 198 | 217 | |
| 199 | 218 | try expect(math.isPositiveZero(f(0.0))); |
| ... | ... | @@ -214,23 +233,23 @@ test "tan64.normal" { |
| 214 | 233 | test "tan80.normal" { |
| 215 | 234 | const epsilon = math.floatEps(f80); |
| 216 | 235 | |
| 217 | try expectApproxEqAbs(@as(f80, 0.0), tanx(0.0), epsilon); | |
| 218 | try expectApproxEqAbs(@as(f80, 0.2027100355086724833213582716475345), tanx(0.2), epsilon); | |
| 219 | try expectApproxEqAbs(@as(f80, 1.2404217445497097995561220131857544), tanx(0.8923), epsilon); | |
| 220 | try expectApproxEqAbs(@as(f80, 14.10141994717171938764), tanx(1.5), epsilon); | |
| 221 | try expectApproxEqAbs(@as(f80, -0.25439607116885656232), tanx(37.45), epsilon); | |
| 222 | try expectApproxEqAbs(@as(f80, 2.2858376251355320963), tanx(89.123), epsilon); | |
| 236 | try expectApproxEqAbs(@as(f80, 0.0), tan_f80(0.0), epsilon); | |
| 237 | try expectApproxEqAbs(@as(f80, 0.2027100355086724833213582716475345), tan_f80(0.2), epsilon); | |
| 238 | try expectApproxEqAbs(@as(f80, 1.2404217445497097995561220131857544), tan_f80(0.8923), epsilon); | |
| 239 | try expectApproxEqAbs(@as(f80, 14.10141994717171938764), tan_f80(1.5), epsilon); | |
| 240 | try expectApproxEqAbs(@as(f80, -0.25439607116885656232), tan_f80(37.45), epsilon); | |
| 241 | try expectApproxEqAbs(@as(f80, 2.2858376251355320963), tan_f80(89.123), epsilon); | |
| 223 | 242 | } |
| 224 | 243 | |
| 225 | 244 | test "tan128.normal" { |
| 226 | 245 | const epsilon = math.floatEps(f128); |
| 227 | 246 | |
| 228 | try expectApproxEqAbs(@as(f128, 0.0), tanq(0.0), epsilon); | |
| 229 | try expectApproxEqAbs(@as(f128, 0.2027100355086724833213582716475345), tanq(0.2), epsilon); | |
| 230 | try expectApproxEqAbs(@as(f128, 1.2404217445497097995561220131857544), tanq(0.8923), epsilon); | |
| 231 | try expectApproxEqAbs(@as(f128, 14.101419947171719387646083651987755), tanq(1.5), epsilon); | |
| 232 | try expectApproxEqAbs(@as(f128, -0.2543960711688565630469573224504774), tanq(37.45), epsilon); | |
| 233 | try expectApproxEqAbs(@as(f128, 2.2858376251355321074066028114094292), tanq(89.123), epsilon); | |
| 247 | try expectApproxEqAbs(@as(f128, 0.0), tan_f128(0.0), epsilon); | |
| 248 | try expectApproxEqAbs(@as(f128, 0.2027100355086724833213582716475345), tan_f128(0.2), epsilon); | |
| 249 | try expectApproxEqAbs(@as(f128, 1.2404217445497097995561220131857544), tan_f128(0.8923), epsilon); | |
| 250 | try expectApproxEqAbs(@as(f128, 14.101419947171719387646083651987755), tan_f128(1.5), epsilon); | |
| 251 | try expectApproxEqAbs(@as(f128, -0.2543960711688565630469573224504774), tan_f128(37.45), epsilon); | |
| 252 | try expectApproxEqAbs(@as(f128, 2.2858376251355321074066028114094292), tan_f128(89.123), epsilon); | |
| 234 | 253 | } |
| 235 | 254 | |
| 236 | 255 | test "tan32.special" { |
lib/compiler_rt/trunc.zig+76-43| ... | ... | @@ -24,12 +24,18 @@ comptime { |
| 24 | 24 | symbol(&truncl, "truncl"); |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | pub fn __trunch(x: f16) callconv(.c) f16 { | |
| 27 | fn __trunch(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { | |
| 28 | return compiler_rt.f16.toAbi(trunc_f16(compiler_rt.f16.fromAbi(x))); | |
| 29 | } | |
| 30 | pub fn trunc_f16(x: f16) f16 { | |
| 28 | 31 | // TODO: more efficient implementation |
| 29 | return @floatCast(truncf(x)); | |
| 32 | return @floatCast(trunc_f32(x)); | |
| 30 | 33 | } |
| 31 | 34 | |
| 32 | pub fn truncf(x: f32) callconv(.c) f32 { | |
| 35 | fn truncf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 36 | return compiler_rt.f32.toAbi(trunc_f32(compiler_rt.f32.fromAbi(x))); | |
| 37 | } | |
| 38 | pub fn trunc_f32(x: f32) f32 { | |
| 33 | 39 | const u: u32 = @bitCast(x); |
| 34 | 40 | var e = @as(i32, @intCast(((u >> 23) & 0xFF))) - 0x7F + 9; |
| 35 | 41 | var m: u32 = undefined; |
| ... | ... | @@ -50,7 +56,10 @@ pub fn truncf(x: f32) callconv(.c) f32 { |
| 50 | 56 | } |
| 51 | 57 | } |
| 52 | 58 | |
| 53 | pub fn trunc(x: f64) callconv(.c) f64 { | |
| 59 | fn trunc(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 60 | return compiler_rt.f64.toAbi(trunc_f64(compiler_rt.f64.fromAbi(x))); | |
| 61 | } | |
| 62 | pub fn trunc_f64(x: f64) f64 { | |
| 54 | 63 | const u: u64 = @bitCast(x); |
| 55 | 64 | var e = @as(i32, @intCast(((u >> 52) & 0x7FF))) - 0x3FF + 12; |
| 56 | 65 | var m: u64 = undefined; |
| ... | ... | @@ -71,12 +80,18 @@ pub fn trunc(x: f64) callconv(.c) f64 { |
| 71 | 80 | } |
| 72 | 81 | } |
| 73 | 82 | |
| 74 | pub fn __truncx(x: f80) callconv(.c) f80 { | |
| 83 | fn __truncx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 84 | return compiler_rt.f80.toAbi(trunc_f80(compiler_rt.f80.fromAbi(x))); | |
| 85 | } | |
| 86 | pub fn trunc_f80(x: f80) f80 { | |
| 75 | 87 | // TODO: more efficient implementation |
| 76 | return @floatCast(truncq(x)); | |
| 88 | return @floatCast(trunc_f128(x)); | |
| 77 | 89 | } |
| 78 | 90 | |
| 79 | pub fn truncq(x: f128) callconv(.c) f128 { | |
| 91 | fn truncq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { | |
| 92 | return compiler_rt.f128.toAbi(trunc_f128(compiler_rt.f128.fromAbi(x))); | |
| 93 | } | |
| 94 | pub fn trunc_f128(x: f128) f128 { | |
| 80 | 95 | const u: u128 = @bitCast(x); |
| 81 | 96 | var e = @as(i32, @intCast(((u >> 112) & 0x7FFF))) - 0x3FFF + 16; |
| 82 | 97 | var m: u128 = undefined; |
| ... | ... | @@ -99,51 +114,69 @@ pub fn truncq(x: f128) callconv(.c) f128 { |
| 99 | 114 | |
| 100 | 115 | pub fn truncl(x: c_longdouble) callconv(.c) c_longdouble { |
| 101 | 116 | switch (@typeInfo(c_longdouble).float.bits) { |
| 102 | 64 => return trunc(x), | |
| 103 | 80 => return __truncx(x), | |
| 104 | 128 => return truncq(x), | |
| 105 | else => @compileError("unreachable"), | |
| 117 | 64 => return trunc_f64(x), | |
| 118 | 80 => return trunc_f80(x), | |
| 119 | 128 => return trunc_f128(x), | |
| 120 | else => comptime unreachable, | |
| 106 | 121 | } |
| 107 | 122 | } |
| 108 | 123 | |
| 109 | test "trunc32" { | |
| 110 | try expect(truncf(1.3) == 1.0); | |
| 111 | try expect(truncf(-1.3) == -1.0); | |
| 112 | try expect(truncf(0.2) == 0.0); | |
| 113 | } | |
| 114 | ||
| 115 | test "trunc64" { | |
| 116 | try expect(trunc(1.3) == 1.0); | |
| 117 | try expect(trunc(-1.3) == -1.0); | |
| 118 | try expect(trunc(0.2) == 0.0); | |
| 124 | test trunc_f16 { | |
| 125 | try expect(trunc_f16(1.3) == 1.0); | |
| 126 | try expect(trunc_f16(-1.3) == -1.0); | |
| 127 | try expect(math.isPositiveZero(trunc_f16(0.2))); | |
| 128 | try expect(math.isNegativeZero(trunc_f16(-0.2))); | |
| 129 | try expect(math.isPositiveZero(trunc_f16(0.0))); | |
| 130 | try expect(math.isNegativeZero(trunc_f16(-0.0))); | |
| 131 | try expect(math.isPositiveInf(trunc_f16(math.inf(f32)))); | |
| 132 | try expect(math.isNegativeInf(trunc_f16(-math.inf(f32)))); | |
| 133 | try expect(math.isNan(trunc_f16(math.nan(f32)))); | |
| 119 | 134 | } |
| 120 | 135 | |
| 121 | test "trunc128" { | |
| 122 | try expect(truncq(1.3) == 1.0); | |
| 123 | try expect(truncq(-1.3) == -1.0); | |
| 124 | try expect(truncq(0.2) == 0.0); | |
| 136 | test trunc_f32 { | |
| 137 | try expect(trunc_f32(1.3) == 1.0); | |
| 138 | try expect(trunc_f32(-1.3) == -1.0); | |
| 139 | try expect(math.isPositiveZero(trunc_f32(0.2))); | |
| 140 | try expect(math.isNegativeZero(trunc_f32(-0.2))); | |
| 141 | try expect(math.isPositiveZero(trunc_f32(0.0))); | |
| 142 | try expect(math.isNegativeZero(trunc_f32(-0.0))); | |
| 143 | try expect(math.isPositiveInf(trunc_f32(math.inf(f32)))); | |
| 144 | try expect(math.isNegativeInf(trunc_f32(-math.inf(f32)))); | |
| 145 | try expect(math.isNan(trunc_f32(math.nan(f32)))); | |
| 125 | 146 | } |
| 126 | 147 | |
| 127 | test "trunc32.special" { | |
| 128 | try expect(truncf(0.0) == 0.0); // 0x3F800000 | |
| 129 | try expect(truncf(-0.0) == -0.0); | |
| 130 | try expect(math.isPositiveInf(truncf(math.inf(f32)))); | |
| 131 | try expect(math.isNegativeInf(truncf(-math.inf(f32)))); | |
| 132 | try expect(math.isNan(truncf(math.nan(f32)))); | |
| 148 | test trunc_f64 { | |
| 149 | try expect(trunc_f64(1.3) == 1.0); | |
| 150 | try expect(trunc_f64(-1.3) == -1.0); | |
| 151 | try expect(math.isPositiveZero(trunc_f64(0.2))); | |
| 152 | try expect(math.isNegativeZero(trunc_f64(-0.2))); | |
| 153 | try expect(math.isPositiveZero(trunc_f64(0.0))); | |
| 154 | try expect(math.isNegativeZero(trunc_f64(-0.0))); | |
| 155 | try expect(math.isPositiveInf(trunc_f64(math.inf(f64)))); | |
| 156 | try expect(math.isNegativeInf(trunc_f64(-math.inf(f64)))); | |
| 157 | try expect(math.isNan(trunc_f64(math.nan(f64)))); | |
| 133 | 158 | } |
| 134 | 159 | |
| 135 | test "trunc64.special" { | |
| 136 | try expect(trunc(0.0) == 0.0); | |
| 137 | try expect(trunc(-0.0) == -0.0); | |
| 138 | try expect(math.isPositiveInf(trunc(math.inf(f64)))); | |
| 139 | try expect(math.isNegativeInf(trunc(-math.inf(f64)))); | |
| 140 | try expect(math.isNan(trunc(math.nan(f64)))); | |
| 160 | test trunc_f80 { | |
| 161 | try expect(trunc_f80(1.3) == 1.0); | |
| 162 | try expect(trunc_f80(-1.3) == -1.0); | |
| 163 | try expect(math.isPositiveZero(trunc_f80(0.2))); | |
| 164 | try expect(math.isNegativeZero(trunc_f80(-0.2))); | |
| 165 | try expect(math.isPositiveZero(trunc_f80(0.0))); | |
| 166 | try expect(math.isNegativeZero(trunc_f80(-0.0))); | |
| 167 | try expect(math.isPositiveInf(trunc_f80(math.inf(f64)))); | |
| 168 | try expect(math.isNegativeInf(trunc_f80(-math.inf(f64)))); | |
| 169 | try expect(math.isNan(trunc_f80(math.nan(f64)))); | |
| 141 | 170 | } |
| 142 | 171 | |
| 143 | test "trunc128.special" { | |
| 144 | try expect(truncq(0.0) == 0.0); | |
| 145 | try expect(truncq(-0.0) == -0.0); | |
| 146 | try expect(math.isPositiveInf(truncq(math.inf(f128)))); | |
| 147 | try expect(math.isNegativeInf(truncq(-math.inf(f128)))); | |
| 148 | try expect(math.isNan(truncq(math.nan(f128)))); | |
| 172 | test trunc_f128 { | |
| 173 | try expect(trunc_f128(1.3) == 1.0); | |
| 174 | try expect(trunc_f128(-1.3) == -1.0); | |
| 175 | try expect(math.isPositiveZero(trunc_f128(0.2))); | |
| 176 | try expect(math.isNegativeZero(trunc_f128(-0.2))); | |
| 177 | try expect(math.isPositiveZero(trunc_f128(0.0))); | |
| 178 | try expect(math.isNegativeZero(trunc_f128(-0.0))); | |
| 179 | try expect(math.isPositiveInf(trunc_f128(math.inf(f128)))); | |
| 180 | try expect(math.isNegativeInf(trunc_f128(-math.inf(f128)))); | |
| 181 | try expect(math.isNan(trunc_f128(math.nan(f128)))); | |
| 149 | 182 | } |
lib/compiler_rt/truncdfhf2.zig deleted-18| ... | ... | @@ -1,18 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const truncf = @import("./truncf.zig").truncf; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_d2h, "__aeabi_d2h"); | |
| 8 | } | |
| 9 | symbol(&__truncdfhf2, "__truncdfhf2"); | |
| 10 | } | |
| 11 | ||
| 12 | pub fn __truncdfhf2(a: f64) callconv(.c) compiler_rt.F16T(f64) { | |
| 13 | return @bitCast(truncf(f16, f64, a)); | |
| 14 | } | |
| 15 | ||
| 16 | fn __aeabi_d2h(a: f64) callconv(.{ .arm_aapcs = .{} }) u16 { | |
| 17 | return @bitCast(truncf(f16, f64, a)); | |
| 18 | } |
lib/compiler_rt/truncdfsf2.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const truncf = @import("./truncf.zig").truncf; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_d2f, "__aeabi_d2f"); | |
| 8 | } else { | |
| 9 | symbol(&__truncdfsf2, "__truncdfsf2"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | pub fn __truncdfsf2(a: f64) callconv(.c) f32 { | |
| 14 | return truncf(f32, f64, a); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_d2f(a: f64) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 18 | return truncf(f32, f64, a); | |
| 19 | } |
lib/compiler_rt/truncf.zig+200-2| ... | ... | @@ -1,6 +1,204 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | |
| 3 | pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t { | |
| 3 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 4 | const symbol = compiler_rt.symbol; | |
| 5 | ||
| 6 | comptime { | |
| 7 | if (compiler_rt.want_aeabi) { | |
| 8 | if (compiler_rt.gnu_f16_abi) { | |
| 9 | symbol(&__aeabi_f2h, "__gnu_f2h_ieee"); | |
| 10 | } else { | |
| 11 | symbol(&__aeabi_f2h, "__aeabi_f2h"); | |
| 12 | } | |
| 13 | symbol(&__aeabi_d2h, "__aeabi_d2h"); | |
| 14 | } else if (compiler_rt.gnu_f16_abi) { | |
| 15 | symbol(&__truncsfhf2, "__gnu_f2h_ieee"); | |
| 16 | } | |
| 17 | symbol(&__truncsfhf2, "__truncsfhf2"); | |
| 18 | symbol(&__truncdfhf2, "__truncdfhf2"); | |
| 19 | symbol(&__truncxfhf2, "__truncxfhf2"); | |
| 20 | if (compiler_rt.want_ppc_abi) { | |
| 21 | symbol(&__trunctfhf2, "__trunckfhf2"); | |
| 22 | } else { | |
| 23 | symbol(&__trunctfhf2, "__trunctfhf2"); | |
| 24 | } | |
| 25 | ||
| 26 | if (compiler_rt.want_aeabi) { | |
| 27 | symbol(&__aeabi_d2f, "__aeabi_d2f"); | |
| 28 | } else { | |
| 29 | symbol(&__truncdfsf2, "__truncdfsf2"); | |
| 30 | } | |
| 31 | symbol(&__truncxfsf2, "__truncxfsf2"); | |
| 32 | if (compiler_rt.want_ppc_abi) { | |
| 33 | symbol(&__trunctfsf2, "__trunckfsf2"); | |
| 34 | } else if (compiler_rt.want_sparc64_abi) { | |
| 35 | symbol(&_Qp_qtos, "_Qp_qtos"); | |
| 36 | } else if (compiler_rt.want_sparc32_abi) { | |
| 37 | symbol(&__trunctfsf2, "_Q_qtos"); | |
| 38 | } else { | |
| 39 | symbol(&__trunctfsf2, "__trunctfsf2"); | |
| 40 | } | |
| 41 | ||
| 42 | symbol(&__truncxfdf2, "__truncxfdf2"); | |
| 43 | ||
| 44 | if (compiler_rt.want_ppc_abi) { | |
| 45 | symbol(&__trunctfdf2, "__trunckfdf2"); | |
| 46 | } else if (compiler_rt.want_sparc64_abi) { | |
| 47 | symbol(&_Qp_qtod, "_Qp_qtod"); | |
| 48 | } else if (compiler_rt.want_sparc32_abi) { | |
| 49 | symbol(&__trunctfdf2, "_Q_qtod"); | |
| 50 | } else { | |
| 51 | symbol(&__trunctfdf2, "__trunctfdf2"); | |
| 52 | } | |
| 53 | ||
| 54 | if (compiler_rt.want_ppc_abi) { | |
| 55 | symbol(&__trunctfxf2, "__trunckfxf2"); | |
| 56 | } else { | |
| 57 | symbol(&__trunctfxf2, "__trunctfxf2"); | |
| 58 | } | |
| 59 | } | |
| 60 | ||
| 61 | fn __truncsfhf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f16Conv(f32).Abi { | |
| 62 | return compiler_rt.f16Conv(f32).toAbi(f16_floatCast_f32(compiler_rt.f32.fromAbi(a))); | |
| 63 | } | |
| 64 | fn __aeabi_f2h(a: u32) callconv(.{ .arm_aapcs = .{} }) u16 { | |
| 65 | return @bitCast(f16_floatCast_f32(@bitCast(a))); | |
| 66 | } | |
| 67 | pub fn f16_floatCast_f32(a: f32) f16 { | |
| 68 | return truncf(f16, f32, a); | |
| 69 | } | |
| 70 | ||
| 71 | fn __truncdfhf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f16Conv(f64).Abi { | |
| 72 | return compiler_rt.f16Conv(f64).toAbi(f16_floatCast_f64(compiler_rt.f64.fromAbi(a))); | |
| 73 | } | |
| 74 | fn __aeabi_d2h(a: u64) callconv(.{ .arm_aapcs = .{} }) u16 { | |
| 75 | return @bitCast(f16_floatCast_f64(@bitCast(a))); | |
| 76 | } | |
| 77 | pub fn f16_floatCast_f64(a: f64) f16 { | |
| 78 | return truncf(f16, f64, a); | |
| 79 | } | |
| 80 | ||
| 81 | fn __truncxfhf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f16Conv(f80).Abi { | |
| 82 | return compiler_rt.f16Conv(f80).toAbi(f16_floatCast_f80(compiler_rt.f80.fromAbi(a))); | |
| 83 | } | |
| 84 | pub fn f16_floatCast_f80(a: f80) f16 { | |
| 85 | return trunc_f80(f16, a); | |
| 86 | } | |
| 87 | ||
| 88 | fn __trunctfhf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f16Conv(f128).Abi { | |
| 89 | return compiler_rt.f16Conv(f128).toAbi(f16_floatCast_f128(compiler_rt.f128.fromAbi(a))); | |
| 90 | } | |
| 91 | pub fn f16_floatCast_f128(a: f128) f16 { | |
| 92 | return truncf(f16, f128, a); | |
| 93 | } | |
| 94 | ||
| 95 | fn __truncdfsf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 96 | return compiler_rt.f32.toAbi(f32_floatCast_f64(compiler_rt.f64.fromAbi(a))); | |
| 97 | } | |
| 98 | fn __aeabi_d2f(a: f64) callconv(.{ .arm_aapcs = .{} }) f32 { | |
| 99 | return f32_floatCast_f64(a); | |
| 100 | } | |
| 101 | pub fn f32_floatCast_f64(a: f64) f32 { | |
| 102 | return truncf(f32, f64, a); | |
| 103 | } | |
| 104 | ||
| 105 | fn __truncxfsf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 106 | return compiler_rt.f32.toAbi(f32_floatCast_f80(compiler_rt.f80.fromAbi(a))); | |
| 107 | } | |
| 108 | pub fn f32_floatCast_f80(a: f80) f32 { | |
| 109 | return trunc_f80(f32, a); | |
| 110 | } | |
| 111 | ||
| 112 | fn __trunctfsf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f32.Abi { | |
| 113 | return compiler_rt.f32.toAbi(f32_floatCast_f128(compiler_rt.f128.fromAbi(a))); | |
| 114 | } | |
| 115 | fn _Qp_qtos(a: *const f128) callconv(.c) f32 { | |
| 116 | return f32_floatCast_f128(a.*); | |
| 117 | } | |
| 118 | pub fn f32_floatCast_f128(a: f128) f32 { | |
| 119 | return truncf(f32, f128, a); | |
| 120 | } | |
| 121 | ||
| 122 | fn __truncxfdf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 123 | return compiler_rt.f64.toAbi(f64_floatCast_f80(compiler_rt.f80.fromAbi(a))); | |
| 124 | } | |
| 125 | pub fn f64_floatCast_f80(a: f80) f64 { | |
| 126 | return trunc_f80(f64, a); | |
| 127 | } | |
| 128 | ||
| 129 | fn __trunctfdf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f64.Abi { | |
| 130 | return compiler_rt.f64.toAbi(f64_floatCast_f128(compiler_rt.f128.fromAbi(a))); | |
| 131 | } | |
| 132 | fn _Qp_qtod(a: *const f128) callconv(.c) f64 { | |
| 133 | return f64_floatCast_f128(a.*); | |
| 134 | } | |
| 135 | pub fn f64_floatCast_f128(a: f128) f64 { | |
| 136 | return truncf(f64, f128, a); | |
| 137 | } | |
| 138 | ||
| 139 | fn __trunctfxf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f80.Abi { | |
| 140 | return compiler_rt.f80.toAbi(f80_floatCast_f128(compiler_rt.f128.fromAbi(a))); | |
| 141 | } | |
| 142 | pub fn f80_floatCast_f128(a: f128) f80 { | |
| 143 | const src_sig_bits = std.math.floatMantissaBits(f128); | |
| 144 | const dst_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit | |
| 145 | ||
| 146 | // Various constants whose values follow from the type parameters. | |
| 147 | // Any reasonable optimizer will fold and propagate all of these. | |
| 148 | const src_bits = @typeInfo(f128).float.bits; | |
| 149 | const src_exp_bits = src_bits - src_sig_bits - 1; | |
| 150 | const src_inf_exp = 0x7FFF; | |
| 151 | ||
| 152 | const src_inf = src_inf_exp << src_sig_bits; | |
| 153 | const src_sign_mask = 1 << (src_sig_bits + src_exp_bits); | |
| 154 | const src_abs_mask = src_sign_mask - 1; | |
| 155 | const round_mask = (1 << (src_sig_bits - dst_sig_bits)) - 1; | |
| 156 | const halfway = 1 << (src_sig_bits - dst_sig_bits - 1); | |
| 157 | ||
| 158 | // Break a into a sign and representation of the absolute value | |
| 159 | const a_rep: u128 = @bitCast(a); | |
| 160 | const a_abs = a_rep & src_abs_mask; | |
| 161 | const sign: u16 = if (a_rep & src_sign_mask != 0) 0x8000 else 0; | |
| 162 | const integer_bit = 1 << 63; | |
| 163 | ||
| 164 | var res: std.math.F80 = undefined; | |
| 165 | ||
| 166 | if (a_abs > src_inf) { | |
| 167 | // a is NaN. | |
| 168 | // Conjure the result by beginning with infinity, setting the qNaN | |
| 169 | // bit and inserting the (truncated) trailing NaN field. | |
| 170 | res.exp = 0x7fff; | |
| 171 | res.fraction = 0x8000000000000000; | |
| 172 | res.fraction |= @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits))); | |
| 173 | } else { | |
| 174 | // The exponent of a is within the range of normal numbers in the | |
| 175 | // destination format. We can convert by simply right-shifting with | |
| 176 | // rounding, adding the explicit integer bit, and adjusting the exponent | |
| 177 | res.fraction = @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits))) | integer_bit; | |
| 178 | res.exp = @truncate(a_abs >> src_sig_bits); | |
| 179 | ||
| 180 | const round_bits = a_abs & round_mask; | |
| 181 | if (round_bits > halfway) { | |
| 182 | // Round to nearest | |
| 183 | const ov = @addWithOverflow(res.fraction, 1); | |
| 184 | res.fraction = ov[0]; | |
| 185 | res.exp += ov[1]; | |
| 186 | res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry | |
| 187 | } else if (round_bits == halfway) { | |
| 188 | // Ties to even | |
| 189 | const ov = @addWithOverflow(res.fraction, res.fraction & 1); | |
| 190 | res.fraction = ov[0]; | |
| 191 | res.exp += ov[1]; | |
| 192 | res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry | |
| 193 | } | |
| 194 | if (res.exp == 0) res.fraction &= ~@as(u64, integer_bit); // Remove integer bit for de-normals | |
| 195 | } | |
| 196 | ||
| 197 | res.exp |= sign; | |
| 198 | return res.toFloat(); | |
| 199 | } | |
| 200 | ||
| 201 | inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t { | |
| 4 | 202 | const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits); |
| 5 | 203 | const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits); |
| 6 | 204 | const srcSigBits = std.math.floatMantissaBits(src_t); |
| ... | ... | @@ -99,7 +297,7 @@ pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t |
| 99 | 297 | return @bitCast(result); |
| 100 | 298 | } |
| 101 | 299 | |
| 102 | pub inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t { | |
| 300 | inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t { | |
| 103 | 301 | const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits); |
| 104 | 302 | const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit |
| 105 | 303 | const dst_sig_bits = std.math.floatMantissaBits(dst_t); |
lib/compiler_rt/truncf_test.zig+160-174| ... | ... | @@ -1,79 +1,82 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const testing = std.testing; |
| 3 | 3 | |
| 4 | const __truncsfhf2 = @import("truncsfhf2.zig").__truncsfhf2; | |
| 5 | const __truncdfhf2 = @import("truncdfhf2.zig").__truncdfhf2; | |
| 6 | const __truncdfsf2 = @import("truncdfsf2.zig").__truncdfsf2; | |
| 7 | const __trunctfhf2 = @import("trunctfhf2.zig").__trunctfhf2; | |
| 8 | const __trunctfsf2 = @import("trunctfsf2.zig").__trunctfsf2; | |
| 9 | const __trunctfdf2 = @import("trunctfdf2.zig").__trunctfdf2; | |
| 10 | const __trunctfxf2 = @import("trunctfxf2.zig").__trunctfxf2; | |
| 11 | ||
| 12 | fn test__truncsfhf2(a: u32, expected: u16) !void { | |
| 13 | const actual: u16 = @bitCast(__truncsfhf2(@bitCast(a))); | |
| 14 | ||
| 15 | if (actual == expected) { | |
| 16 | return; | |
| 17 | } | |
| 4 | const impl = @import("truncf.zig"); | |
| 18 | 5 | |
| 19 | return error.TestFailure; | |
| 6 | const f16_floatCast_f32 = impl.f16_floatCast_f32; | |
| 7 | const f16_floatCast_f64 = impl.f16_floatCast_f64; | |
| 8 | const f16_floatCast_f80 = impl.f16_floatCast_f80; | |
| 9 | const f16_floatCast_f128 = impl.f16_floatCast_f128; | |
| 10 | ||
| 11 | const f32_floatCast_f64 = impl.f32_floatCast_f64; | |
| 12 | const f32_floatCast_f80 = impl.f32_floatCast_f80; | |
| 13 | const f32_floatCast_f128 = impl.f32_floatCast_f128; | |
| 14 | ||
| 15 | const f64_floatCast_f80 = impl.f64_floatCast_f80; | |
| 16 | const f64_floatCast_f128 = impl.f64_floatCast_f128; | |
| 17 | ||
| 18 | const f80_floatCast_f128 = impl.f80_floatCast_f128; | |
| 19 | ||
| 20 | fn test_f16_floatCast_f32(a: u32, expected: u16) !void { | |
| 21 | const actual: u16 = @bitCast(f16_floatCast_f32(@bitCast(a))); | |
| 22 | try testing.expect(actual == expected); | |
| 20 | 23 | } |
| 21 | 24 | |
| 22 | test "truncsfhf2" { | |
| 23 | try test__truncsfhf2(0x7fc00000, 0x7e00); // qNaN | |
| 24 | try test__truncsfhf2(0x7fe00000, 0x7f00); // sNaN | |
| 25 | test f16_floatCast_f32 { | |
| 26 | try test_f16_floatCast_f32(0x7fc00000, 0x7e00); // qNaN | |
| 27 | try test_f16_floatCast_f32(0x7fe00000, 0x7f00); // sNaN | |
| 25 | 28 | |
| 26 | try test__truncsfhf2(0, 0); // 0 | |
| 27 | try test__truncsfhf2(0x80000000, 0x8000); // -0 | |
| 29 | try test_f16_floatCast_f32(0, 0); // 0 | |
| 30 | try test_f16_floatCast_f32(0x80000000, 0x8000); // -0 | |
| 28 | 31 | |
| 29 | try test__truncsfhf2(0x7f800000, 0x7c00); // inf | |
| 30 | try test__truncsfhf2(0xff800000, 0xfc00); // -inf | |
| 32 | try test_f16_floatCast_f32(0x7f800000, 0x7c00); // inf | |
| 33 | try test_f16_floatCast_f32(0xff800000, 0xfc00); // -inf | |
| 31 | 34 | |
| 32 | try test__truncsfhf2(0x477ff000, 0x7c00); // 65520 -> inf | |
| 33 | try test__truncsfhf2(0xc77ff000, 0xfc00); // -65520 -> -inf | |
| 35 | try test_f16_floatCast_f32(0x477ff000, 0x7c00); // 65520 -> inf | |
| 36 | try test_f16_floatCast_f32(0xc77ff000, 0xfc00); // -65520 -> -inf | |
| 34 | 37 | |
| 35 | try test__truncsfhf2(0x71cc3892, 0x7c00); // 0x1.987124876876324p+100 -> inf | |
| 36 | try test__truncsfhf2(0xf1cc3892, 0xfc00); // -0x1.987124876876324p+100 -> -inf | |
| 38 | try test_f16_floatCast_f32(0x71cc3892, 0x7c00); // 0x1.987124876876324p+100 -> inf | |
| 39 | try test_f16_floatCast_f32(0xf1cc3892, 0xfc00); // -0x1.987124876876324p+100 -> -inf | |
| 37 | 40 | |
| 38 | try test__truncsfhf2(0x38800000, 0x0400); // normal (min), 2**-14 | |
| 39 | try test__truncsfhf2(0xb8800000, 0x8400); // normal (min), -2**-14 | |
| 41 | try test_f16_floatCast_f32(0x38800000, 0x0400); // normal (min), 2**-14 | |
| 42 | try test_f16_floatCast_f32(0xb8800000, 0x8400); // normal (min), -2**-14 | |
| 40 | 43 | |
| 41 | try test__truncsfhf2(0x477fe000, 0x7bff); // normal (max), 65504 | |
| 42 | try test__truncsfhf2(0xc77fe000, 0xfbff); // normal (max), -65504 | |
| 44 | try test_f16_floatCast_f32(0x477fe000, 0x7bff); // normal (max), 65504 | |
| 45 | try test_f16_floatCast_f32(0xc77fe000, 0xfbff); // normal (max), -65504 | |
| 43 | 46 | |
| 44 | try test__truncsfhf2(0x477fe100, 0x7bff); // normal, 65505 -> 65504 | |
| 45 | try test__truncsfhf2(0xc77fe100, 0xfbff); // normal, -65505 -> -65504 | |
| 47 | try test_f16_floatCast_f32(0x477fe100, 0x7bff); // normal, 65505 -> 65504 | |
| 48 | try test_f16_floatCast_f32(0xc77fe100, 0xfbff); // normal, -65505 -> -65504 | |
| 46 | 49 | |
| 47 | try test__truncsfhf2(0x477fef00, 0x7bff); // normal, 65519 -> 65504 | |
| 48 | try test__truncsfhf2(0xc77fef00, 0xfbff); // normal, -65519 -> -65504 | |
| 50 | try test_f16_floatCast_f32(0x477fef00, 0x7bff); // normal, 65519 -> 65504 | |
| 51 | try test_f16_floatCast_f32(0xc77fef00, 0xfbff); // normal, -65519 -> -65504 | |
| 49 | 52 | |
| 50 | try test__truncsfhf2(0x3f802000, 0x3c01); // normal, 1 + 2**-10 | |
| 51 | try test__truncsfhf2(0xbf802000, 0xbc01); // normal, -1 - 2**-10 | |
| 53 | try test_f16_floatCast_f32(0x3f802000, 0x3c01); // normal, 1 + 2**-10 | |
| 54 | try test_f16_floatCast_f32(0xbf802000, 0xbc01); // normal, -1 - 2**-10 | |
| 52 | 55 | |
| 53 | try test__truncsfhf2(0x3eaaa000, 0x3555); // normal, approx. 1/3 | |
| 54 | try test__truncsfhf2(0xbeaaa000, 0xb555); // normal, approx. -1/3 | |
| 56 | try test_f16_floatCast_f32(0x3eaaa000, 0x3555); // normal, approx. 1/3 | |
| 57 | try test_f16_floatCast_f32(0xbeaaa000, 0xb555); // normal, approx. -1/3 | |
| 55 | 58 | |
| 56 | try test__truncsfhf2(0x40490fdb, 0x4248); // normal, 3.1415926535 | |
| 57 | try test__truncsfhf2(0xc0490fdb, 0xc248); // normal, -3.1415926535 | |
| 59 | try test_f16_floatCast_f32(0x40490fdb, 0x4248); // normal, 3.1415926535 | |
| 60 | try test_f16_floatCast_f32(0xc0490fdb, 0xc248); // normal, -3.1415926535 | |
| 58 | 61 | |
| 59 | try test__truncsfhf2(0x45cc3892, 0x6e62); // normal, 0x1.987124876876324p+12 | |
| 62 | try test_f16_floatCast_f32(0x45cc3892, 0x6e62); // normal, 0x1.987124876876324p+12 | |
| 60 | 63 | |
| 61 | try test__truncsfhf2(0x3f800000, 0x3c00); // normal, 1 | |
| 62 | try test__truncsfhf2(0x38800000, 0x0400); // normal, 0x1.0p-14 | |
| 64 | try test_f16_floatCast_f32(0x3f800000, 0x3c00); // normal, 1 | |
| 65 | try test_f16_floatCast_f32(0x38800000, 0x0400); // normal, 0x1.0p-14 | |
| 63 | 66 | |
| 64 | try test__truncsfhf2(0x33800000, 0x0001); // denormal (min), 2**-24 | |
| 65 | try test__truncsfhf2(0xb3800000, 0x8001); // denormal (min), -2**-24 | |
| 67 | try test_f16_floatCast_f32(0x33800000, 0x0001); // denormal (min), 2**-24 | |
| 68 | try test_f16_floatCast_f32(0xb3800000, 0x8001); // denormal (min), -2**-24 | |
| 66 | 69 | |
| 67 | try test__truncsfhf2(0x387fc000, 0x03ff); // denormal (max), 2**-14 - 2**-24 | |
| 68 | try test__truncsfhf2(0xb87fc000, 0x83ff); // denormal (max), -2**-14 + 2**-24 | |
| 70 | try test_f16_floatCast_f32(0x387fc000, 0x03ff); // denormal (max), 2**-14 - 2**-24 | |
| 71 | try test_f16_floatCast_f32(0xb87fc000, 0x83ff); // denormal (max), -2**-14 + 2**-24 | |
| 69 | 72 | |
| 70 | try test__truncsfhf2(0x35800000, 0x0010); // denormal, 0x1.0p-20 | |
| 71 | try test__truncsfhf2(0x33280000, 0x0001); // denormal, 0x1.5p-25 -> 0x1.0p-24 | |
| 72 | try test__truncsfhf2(0x33000000, 0x0000); // 0x1.0p-25 -> zero | |
| 73 | try test_f16_floatCast_f32(0x35800000, 0x0010); // denormal, 0x1.0p-20 | |
| 74 | try test_f16_floatCast_f32(0x33280000, 0x0001); // denormal, 0x1.5p-25 -> 0x1.0p-24 | |
| 75 | try test_f16_floatCast_f32(0x33000000, 0x0000); // 0x1.0p-25 -> zero | |
| 73 | 76 | } |
| 74 | 77 | |
| 75 | fn test__truncdfhf2(a: f64, expected: u16) void { | |
| 76 | const rep: u16 = @bitCast(__truncdfhf2(a)); | |
| 78 | fn test_f16_floatCast_f64(a: f64, expected: u16) !void { | |
| 79 | const rep: u16 = @bitCast(f16_floatCast_f64(a)); | |
| 77 | 80 | |
| 78 | 81 | if (rep == expected) { |
| 79 | 82 | return; |
| ... | ... | @@ -84,62 +87,56 @@ fn test__truncdfhf2(a: f64, expected: u16) void { |
| 84 | 87 | return; |
| 85 | 88 | } |
| 86 | 89 | } |
| 87 | ||
| 88 | @panic("__truncdfhf2 test failure"); | |
| 90 | return error.TestFailure; | |
| 89 | 91 | } |
| 90 | 92 | |
| 91 | fn test__truncdfhf2_raw(a: u64, expected: u16) void { | |
| 92 | const actual: u16 = @bitCast(__truncdfhf2(@bitCast(a))); | |
| 93 | ||
| 94 | if (actual == expected) { | |
| 95 | return; | |
| 96 | } | |
| 97 | ||
| 98 | @panic("__truncdfhf2 test failure"); | |
| 93 | fn test_f16_floatCast_f64_raw(a: u64, expected: u16) !void { | |
| 94 | const actual: u16 = @bitCast(f16_floatCast_f64(@bitCast(a))); | |
| 95 | try testing.expect(actual == expected); | |
| 99 | 96 | } |
| 100 | 97 | |
| 101 | test "truncdfhf2" { | |
| 102 | test__truncdfhf2_raw(0x7ff8000000000000, 0x7e00); // qNaN | |
| 103 | test__truncdfhf2_raw(0x7ff0000000008000, 0x7e00); // NaN | |
| 98 | test f16_floatCast_f64 { | |
| 99 | try test_f16_floatCast_f64_raw(0x7ff8000000000000, 0x7e00); // qNaN | |
| 100 | try test_f16_floatCast_f64_raw(0x7ff0000000008000, 0x7e00); // NaN | |
| 104 | 101 | |
| 105 | test__truncdfhf2_raw(0x7ff0000000000000, 0x7c00); //inf | |
| 106 | test__truncdfhf2_raw(0xfff0000000000000, 0xfc00); // -inf | |
| 102 | try test_f16_floatCast_f64_raw(0x7ff0000000000000, 0x7c00); //inf | |
| 103 | try test_f16_floatCast_f64_raw(0xfff0000000000000, 0xfc00); // -inf | |
| 107 | 104 | |
| 108 | test__truncdfhf2(0.0, 0x0); // zero | |
| 109 | test__truncdfhf2_raw(0x80000000 << 32, 0x8000); // -zero | |
| 105 | try test_f16_floatCast_f64(0.0, 0x0); // zero | |
| 106 | try test_f16_floatCast_f64_raw(0x80000000 << 32, 0x8000); // -zero | |
| 110 | 107 | |
| 111 | test__truncdfhf2(3.1415926535, 0x4248); | |
| 112 | test__truncdfhf2(-3.1415926535, 0xc248); | |
| 108 | try test_f16_floatCast_f64(3.1415926535, 0x4248); | |
| 109 | try test_f16_floatCast_f64(-3.1415926535, 0xc248); | |
| 113 | 110 | |
| 114 | test__truncdfhf2(0x1.987124876876324p+1000, 0x7c00); | |
| 115 | test__truncdfhf2(0x1.987124876876324p+12, 0x6e62); | |
| 116 | test__truncdfhf2(0x1.0p+0, 0x3c00); | |
| 117 | test__truncdfhf2(0x1.0p-14, 0x0400); | |
| 111 | try test_f16_floatCast_f64(0x1.987124876876324p+1000, 0x7c00); | |
| 112 | try test_f16_floatCast_f64(0x1.987124876876324p+12, 0x6e62); | |
| 113 | try test_f16_floatCast_f64(0x1.0p+0, 0x3c00); | |
| 114 | try test_f16_floatCast_f64(0x1.0p-14, 0x0400); | |
| 118 | 115 | |
| 119 | 116 | // denormal |
| 120 | test__truncdfhf2(0x1.0p-20, 0x0010); | |
| 121 | test__truncdfhf2(0x1.0p-24, 0x0001); | |
| 122 | test__truncdfhf2(-0x1.0p-24, 0x8001); | |
| 123 | test__truncdfhf2(0x1.5p-25, 0x0001); | |
| 117 | try test_f16_floatCast_f64(0x1.0p-20, 0x0010); | |
| 118 | try test_f16_floatCast_f64(0x1.0p-24, 0x0001); | |
| 119 | try test_f16_floatCast_f64(-0x1.0p-24, 0x8001); | |
| 120 | try test_f16_floatCast_f64(0x1.5p-25, 0x0001); | |
| 124 | 121 | |
| 125 | 122 | // and back to zero |
| 126 | test__truncdfhf2(0x1.0p-25, 0x0000); | |
| 127 | test__truncdfhf2(-0x1.0p-25, 0x8000); | |
| 123 | try test_f16_floatCast_f64(0x1.0p-25, 0x0000); | |
| 124 | try test_f16_floatCast_f64(-0x1.0p-25, 0x8000); | |
| 128 | 125 | |
| 129 | 126 | // max (precise) |
| 130 | test__truncdfhf2(65504.0, 0x7bff); | |
| 127 | try test_f16_floatCast_f64(65504.0, 0x7bff); | |
| 131 | 128 | |
| 132 | 129 | // max (rounded) |
| 133 | test__truncdfhf2(65519.0, 0x7bff); | |
| 130 | try test_f16_floatCast_f64(65519.0, 0x7bff); | |
| 134 | 131 | |
| 135 | 132 | // max (to +inf) |
| 136 | test__truncdfhf2(65520.0, 0x7c00); | |
| 137 | test__truncdfhf2(-65520.0, 0xfc00); | |
| 138 | test__truncdfhf2(65536.0, 0x7c00); | |
| 133 | try test_f16_floatCast_f64(65520.0, 0x7c00); | |
| 134 | try test_f16_floatCast_f64(-65520.0, 0xfc00); | |
| 135 | try test_f16_floatCast_f64(65536.0, 0x7c00); | |
| 139 | 136 | } |
| 140 | 137 | |
| 141 | fn test__trunctfsf2(a: f128, expected: u32) void { | |
| 142 | const x = __trunctfsf2(a); | |
| 138 | fn test_f32_floatCast_f128(a: f128, expected: u32) !void { | |
| 139 | const x = f32_floatCast_f128(a); | |
| 143 | 140 | |
| 144 | 141 | const rep: u32 = @bitCast(x); |
| 145 | 142 | if (rep == expected) { |
| ... | ... | @@ -151,28 +148,27 @@ fn test__trunctfsf2(a: f128, expected: u32) void { |
| 151 | 148 | return; |
| 152 | 149 | } |
| 153 | 150 | } |
| 154 | ||
| 155 | @panic("__trunctfsf2 test failure"); | |
| 151 | return error.TestFailure; | |
| 156 | 152 | } |
| 157 | 153 | |
| 158 | test "trunctfsf2" { | |
| 154 | test f32_floatCast_f128 { | |
| 159 | 155 | // qnan |
| 160 | test__trunctfsf2(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7fc00000); | |
| 156 | try test_f32_floatCast_f128(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7fc00000); | |
| 161 | 157 | // nan |
| 162 | test__trunctfsf2(@bitCast(@as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7fc08000); | |
| 158 | try test_f32_floatCast_f128(@bitCast(@as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7fc08000); | |
| 163 | 159 | // inf |
| 164 | test__trunctfsf2(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7f800000); | |
| 160 | try test_f32_floatCast_f128(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7f800000); | |
| 165 | 161 | // zero |
| 166 | test__trunctfsf2(0.0, 0x0); | |
| 162 | try test_f32_floatCast_f128(0.0, 0x0); | |
| 167 | 163 | |
| 168 | test__trunctfsf2(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x4211d156); | |
| 169 | test__trunctfsf2(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x3b71e9e2); | |
| 170 | test__trunctfsf2(0x1.234eebb5faa678f4488693abcdefp+4534, 0x7f800000); | |
| 171 | test__trunctfsf2(0x1.edcba9bb8c76a5a43dd21f334634p-435, 0x0); | |
| 164 | try test_f32_floatCast_f128(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x4211d156); | |
| 165 | try test_f32_floatCast_f128(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x3b71e9e2); | |
| 166 | try test_f32_floatCast_f128(0x1.234eebb5faa678f4488693abcdefp+4534, 0x7f800000); | |
| 167 | try test_f32_floatCast_f128(0x1.edcba9bb8c76a5a43dd21f334634p-435, 0x0); | |
| 172 | 168 | } |
| 173 | 169 | |
| 174 | fn test__trunctfdf2(a: f128, expected: u64) void { | |
| 175 | const x = __trunctfdf2(a); | |
| 170 | fn test_f64_floatCast_f128(a: f128, expected: u64) !void { | |
| 171 | const x = f64_floatCast_f128(a); | |
| 176 | 172 | |
| 177 | 173 | const rep: u64 = @bitCast(x); |
| 178 | 174 | if (rep == expected) { |
| ... | ... | @@ -184,28 +180,27 @@ fn test__trunctfdf2(a: f128, expected: u64) void { |
| 184 | 180 | return; |
| 185 | 181 | } |
| 186 | 182 | } |
| 187 | ||
| 188 | @panic("__trunctfsf2 test failure"); | |
| 183 | return error.TestFailure; | |
| 189 | 184 | } |
| 190 | 185 | |
| 191 | test "trunctfdf2" { | |
| 186 | test f64_floatCast_f128 { | |
| 192 | 187 | // qnan |
| 193 | test__trunctfdf2(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000); | |
| 188 | try test_f64_floatCast_f128(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000); | |
| 194 | 189 | // nan |
| 195 | test__trunctfdf2(@bitCast(@as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7ff8100000000000); | |
| 190 | try test_f64_floatCast_f128(@bitCast(@as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7ff8100000000000); | |
| 196 | 191 | // inf |
| 197 | test__trunctfdf2(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7ff0000000000000); | |
| 192 | try test_f64_floatCast_f128(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7ff0000000000000); | |
| 198 | 193 | // zero |
| 199 | test__trunctfdf2(0.0, 0x0); | |
| 194 | try test_f64_floatCast_f128(0.0, 0x0); | |
| 200 | 195 | |
| 201 | test__trunctfdf2(0x1.af23456789bbaaab347645365cdep+5, 0x404af23456789bbb); | |
| 202 | test__trunctfdf2(0x1.dedafcff354b6ae9758763545432p-9, 0x3f6dedafcff354b7); | |
| 203 | test__trunctfdf2(0x1.2f34dd5f437e849b4baab754cdefp+4534, 0x7ff0000000000000); | |
| 204 | test__trunctfdf2(0x1.edcbff8ad76ab5bf46463233214fp-435, 0x24cedcbff8ad76ab); | |
| 196 | try test_f64_floatCast_f128(0x1.af23456789bbaaab347645365cdep+5, 0x404af23456789bbb); | |
| 197 | try test_f64_floatCast_f128(0x1.dedafcff354b6ae9758763545432p-9, 0x3f6dedafcff354b7); | |
| 198 | try test_f64_floatCast_f128(0x1.2f34dd5f437e849b4baab754cdefp+4534, 0x7ff0000000000000); | |
| 199 | try test_f64_floatCast_f128(0x1.edcbff8ad76ab5bf46463233214fp-435, 0x24cedcbff8ad76ab); | |
| 205 | 200 | } |
| 206 | 201 | |
| 207 | fn test__truncdfsf2(a: f64, expected: u32) void { | |
| 208 | const x = __truncdfsf2(a); | |
| 202 | fn test_f32_floatCast_f64(a: f64, expected: u32) !void { | |
| 203 | const x = f32_floatCast_f64(a); | |
| 209 | 204 | |
| 210 | 205 | const rep: u32 = @bitCast(x); |
| 211 | 206 | if (rep == expected) { |
| ... | ... | @@ -217,90 +212,81 @@ fn test__truncdfsf2(a: f64, expected: u32) void { |
| 217 | 212 | return; |
| 218 | 213 | } |
| 219 | 214 | } |
| 220 | ||
| 221 | std.debug.print("got 0x{x} wanted 0x{x}\n", .{ rep, expected }); | |
| 222 | ||
| 223 | @panic("__trunctfsf2 test failure"); | |
| 215 | return error.TestFailure; | |
| 224 | 216 | } |
| 225 | 217 | |
| 226 | test "truncdfsf2" { | |
| 218 | test f32_floatCast_f64 { | |
| 227 | 219 | // nan & qnan |
| 228 | test__truncdfsf2(@bitCast(@as(u64, 0x7ff8000000000000)), 0x7fc00000); | |
| 229 | test__truncdfsf2(@bitCast(@as(u64, 0x7ff0000000000001)), 0x7fc00000); | |
| 220 | try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff8000000000000)), 0x7fc00000); | |
| 221 | try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff0000000000001)), 0x7fc00000); | |
| 230 | 222 | // inf |
| 231 | test__truncdfsf2(@bitCast(@as(u64, 0x7ff0000000000000)), 0x7f800000); | |
| 232 | test__truncdfsf2(@bitCast(@as(u64, 0xfff0000000000000)), 0xff800000); | |
| 223 | try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff0000000000000)), 0x7f800000); | |
| 224 | try test_f32_floatCast_f64(@bitCast(@as(u64, 0xfff0000000000000)), 0xff800000); | |
| 233 | 225 | |
| 234 | test__truncdfsf2(0.0, 0x0); | |
| 235 | test__truncdfsf2(1.0, 0x3f800000); | |
| 236 | test__truncdfsf2(-1.0, 0xbf800000); | |
| 226 | try test_f32_floatCast_f64(0.0, 0x0); | |
| 227 | try test_f32_floatCast_f64(1.0, 0x3f800000); | |
| 228 | try test_f32_floatCast_f64(-1.0, 0xbf800000); | |
| 237 | 229 | |
| 238 | 230 | // huge number becomes inf |
| 239 | test__truncdfsf2(340282366920938463463374607431768211456.0, 0x7f800000); | |
| 231 | try test_f32_floatCast_f64(340282366920938463463374607431768211456.0, 0x7f800000); | |
| 240 | 232 | } |
| 241 | 233 | |
| 242 | fn test__trunctfhf2(a: f128, expected: u16) void { | |
| 243 | const x = __trunctfhf2(a); | |
| 234 | fn test_f16_floatCast_f128(a: f128, expected: u16) !void { | |
| 235 | const x = f16_floatCast_f128(a); | |
| 244 | 236 | |
| 245 | 237 | const rep: u16 = @bitCast(x); |
| 246 | if (rep == expected) { | |
| 247 | return; | |
| 248 | } | |
| 249 | ||
| 250 | std.debug.print("got 0x{x} wanted 0x{x}\n", .{ rep, expected }); | |
| 251 | ||
| 252 | @panic("__trunctfhf2 test failure"); | |
| 238 | try testing.expect(rep == expected); | |
| 253 | 239 | } |
| 254 | 240 | |
| 255 | test "trunctfhf2" { | |
| 241 | test f16_floatCast_f128 { | |
| 256 | 242 | // qNaN |
| 257 | test__trunctfhf2(@bitCast(@as(u128, 0x7fff8000000000000000000000000000)), 0x7e00); | |
| 243 | try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff8000000000000000000000000000)), 0x7e00); | |
| 258 | 244 | // NaN |
| 259 | test__trunctfhf2(@bitCast(@as(u128, 0x7fff0000000000000000000000000001)), 0x7e00); | |
| 245 | try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff0000000000000000000000000001)), 0x7e00); | |
| 260 | 246 | // inf |
| 261 | test__trunctfhf2(@bitCast(@as(u128, 0x7fff0000000000000000000000000000)), 0x7c00); | |
| 262 | test__trunctfhf2(-@as(f128, @bitCast(@as(u128, 0x7fff0000000000000000000000000000))), 0xfc00); | |
| 247 | try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff0000000000000000000000000000)), 0x7c00); | |
| 248 | try test_f16_floatCast_f128(-@as(f128, @bitCast(@as(u128, 0x7fff0000000000000000000000000000))), 0xfc00); | |
| 263 | 249 | // zero |
| 264 | test__trunctfhf2(0.0, 0x0); | |
| 265 | test__trunctfhf2(-0.0, 0x8000); | |
| 266 | ||
| 267 | test__trunctfhf2(3.1415926535, 0x4248); | |
| 268 | test__trunctfhf2(-3.1415926535, 0xc248); | |
| 269 | test__trunctfhf2(0x1.987124876876324p+100, 0x7c00); | |
| 270 | test__trunctfhf2(0x1.987124876876324p+12, 0x6e62); | |
| 271 | test__trunctfhf2(0x1.0p+0, 0x3c00); | |
| 272 | test__trunctfhf2(0x1.0p-14, 0x0400); | |
| 250 | try test_f16_floatCast_f128(0.0, 0x0); | |
| 251 | try test_f16_floatCast_f128(-0.0, 0x8000); | |
| 252 | ||
| 253 | try test_f16_floatCast_f128(3.1415926535, 0x4248); | |
| 254 | try test_f16_floatCast_f128(-3.1415926535, 0xc248); | |
| 255 | try test_f16_floatCast_f128(0x1.987124876876324p+100, 0x7c00); | |
| 256 | try test_f16_floatCast_f128(0x1.987124876876324p+12, 0x6e62); | |
| 257 | try test_f16_floatCast_f128(0x1.0p+0, 0x3c00); | |
| 258 | try test_f16_floatCast_f128(0x1.0p-14, 0x0400); | |
| 273 | 259 | // denormal |
| 274 | test__trunctfhf2(0x1.0p-20, 0x0010); | |
| 275 | test__trunctfhf2(0x1.0p-24, 0x0001); | |
| 276 | test__trunctfhf2(-0x1.0p-24, 0x8001); | |
| 277 | test__trunctfhf2(0x1.5p-25, 0x0001); | |
| 260 | try test_f16_floatCast_f128(0x1.0p-20, 0x0010); | |
| 261 | try test_f16_floatCast_f128(0x1.0p-24, 0x0001); | |
| 262 | try test_f16_floatCast_f128(-0x1.0p-24, 0x8001); | |
| 263 | try test_f16_floatCast_f128(0x1.5p-25, 0x0001); | |
| 278 | 264 | // and back to zero |
| 279 | test__trunctfhf2(0x1.0p-25, 0x0000); | |
| 280 | test__trunctfhf2(-0x1.0p-25, 0x8000); | |
| 265 | try test_f16_floatCast_f128(0x1.0p-25, 0x0000); | |
| 266 | try test_f16_floatCast_f128(-0x1.0p-25, 0x8000); | |
| 281 | 267 | // max (precise) |
| 282 | test__trunctfhf2(65504.0, 0x7bff); | |
| 268 | try test_f16_floatCast_f128(65504.0, 0x7bff); | |
| 283 | 269 | // max (rounded) |
| 284 | test__trunctfhf2(65519.0, 0x7bff); | |
| 270 | try test_f16_floatCast_f128(65519.0, 0x7bff); | |
| 285 | 271 | // max (to +inf) |
| 286 | test__trunctfhf2(65520.0, 0x7c00); | |
| 287 | test__trunctfhf2(65536.0, 0x7c00); | |
| 288 | test__trunctfhf2(-65520.0, 0xfc00); | |
| 289 | ||
| 290 | test__trunctfhf2(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x508f); | |
| 291 | test__trunctfhf2(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x1b8f); | |
| 292 | test__trunctfhf2(0x1.234eebb5faa678f4488693abcdefp+453, 0x7c00); | |
| 293 | test__trunctfhf2(0x1.edcba9bb8c76a5a43dd21f334634p-43, 0x0); | |
| 272 | try test_f16_floatCast_f128(65520.0, 0x7c00); | |
| 273 | try test_f16_floatCast_f128(65536.0, 0x7c00); | |
| 274 | try test_f16_floatCast_f128(-65520.0, 0xfc00); | |
| 275 | ||
| 276 | try test_f16_floatCast_f128(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x508f); | |
| 277 | try test_f16_floatCast_f128(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x1b8f); | |
| 278 | try test_f16_floatCast_f128(0x1.234eebb5faa678f4488693abcdefp+453, 0x7c00); | |
| 279 | try test_f16_floatCast_f128(0x1.edcba9bb8c76a5a43dd21f334634p-43, 0x0); | |
| 294 | 280 | } |
| 295 | 281 | |
| 296 | test "trunctfxf2" { | |
| 297 | try test__trunctfxf2(1.5, 1.5); | |
| 298 | try test__trunctfxf2(2.5, 2.5); | |
| 299 | try test__trunctfxf2(-2.5, -2.5); | |
| 300 | try test__trunctfxf2(0.0, 0.0); | |
| 282 | fn test_f80_floatCast_f128(a: f128, expected: f80) !void { | |
| 283 | const x = f80_floatCast_f128(a); | |
| 284 | try testing.expect(x == expected); | |
| 301 | 285 | } |
| 302 | 286 | |
| 303 | fn test__trunctfxf2(a: f128, expected: f80) !void { | |
| 304 | const x = __trunctfxf2(a); | |
| 305 | try testing.expect(x == expected); | |
| 287 | test f80_floatCast_f128 { | |
| 288 | try test_f80_floatCast_f128(1.5, 1.5); | |
| 289 | try test_f80_floatCast_f128(2.5, 2.5); | |
| 290 | try test_f80_floatCast_f128(-2.5, -2.5); | |
| 291 | try test_f80_floatCast_f128(0.0, 0.0); | |
| 306 | 292 | } |
lib/compiler_rt/truncsfhf2.zig deleted-24| ... | ... | @@ -1,24 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const truncf = @import("./truncf.zig").truncf; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.gnu_f16_abi) { | |
| 7 | symbol(&__gnu_f2h_ieee, "__gnu_f2h_ieee"); | |
| 8 | } else if (compiler_rt.want_aeabi) { | |
| 9 | symbol(&__aeabi_f2h, "__aeabi_f2h"); | |
| 10 | } | |
| 11 | symbol(&__truncsfhf2, "__truncsfhf2"); | |
| 12 | } | |
| 13 | ||
| 14 | pub fn __truncsfhf2(a: f32) callconv(.c) compiler_rt.F16T(f32) { | |
| 15 | return @bitCast(truncf(f16, f32, a)); | |
| 16 | } | |
| 17 | ||
| 18 | fn __gnu_f2h_ieee(a: f32) callconv(.c) compiler_rt.F16T(f32) { | |
| 19 | return @bitCast(truncf(f16, f32, a)); | |
| 20 | } | |
| 21 | ||
| 22 | fn __aeabi_f2h(a: f32) callconv(.{ .arm_aapcs = .{} }) u16 { | |
| 23 | return @bitCast(truncf(f16, f32, a)); | |
| 24 | } |
lib/compiler_rt/trunctfdf2.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = compiler_rt.symbol; | |
| 3 | const truncf = @import("./truncf.zig").truncf; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) { | |
| 7 | symbol(&__trunctfdf2, "__trunckfdf2"); | |
| 8 | } else if (compiler_rt.want_sparc64_abi) { | |
| 9 | symbol(&_Qp_qtod, "_Qp_qtod"); | |
| 10 | } else if (compiler_rt.want_sparc32_abi) { | |
| 11 | symbol(&__trunctfdf2, "_Q_qtod"); | |
| 12 | } | |
| 13 | symbol(&__trunctfdf2, "__trunctfdf2"); | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __trunctfdf2(a: f128) callconv(.c) f64 { | |
| 17 | return truncf(f64, f128, a); | |
| 18 | } | |
| 19 | ||
| 20 | fn _Qp_qtod(a: *const f128) callconv(.c) f64 { | |
| 21 | return truncf(f64, f128, a.*); | |
| 22 | } |
lib/compiler_rt/trunctfhf2.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | const truncf = @import("./truncf.zig").truncf; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__trunctfhf2, "__trunctfhf2"); | |
| 7 | if (compiler_rt.want_ppc_abi) { | |
| 8 | symbol(&__trunctfhf2, "__trunckfhf2"); | |
| 9 | } | |
| 10 | } | |
| 11 | ||
| 12 | pub fn __trunctfhf2(a: f128) callconv(.c) compiler_rt.F16T(f128) { | |
| 13 | return @bitCast(truncf(f16, f128, a)); | |
| 14 | } |
lib/compiler_rt/trunctfsf2.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const truncf = @import("./truncf.zig").truncf; | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_ppc_abi) { | |
| 7 | symbol(&__trunctfsf2, "__trunckfsf2"); | |
| 8 | } else if (compiler_rt.want_sparc64_abi) { | |
| 9 | symbol(&_Qp_qtos, "_Qp_qtos"); | |
| 10 | } else if (compiler_rt.want_sparc32_abi) { | |
| 11 | symbol(&__trunctfsf2, "_Q_qtos"); | |
| 12 | } | |
| 13 | symbol(&__trunctfsf2, "__trunctfsf2"); | |
| 14 | } | |
| 15 | ||
| 16 | pub fn __trunctfsf2(a: f128) callconv(.c) f32 { | |
| 17 | return truncf(f32, f128, a); | |
| 18 | } | |
| 19 | ||
| 20 | fn _Qp_qtos(a: *const f128) callconv(.c) f32 { | |
| 21 | return truncf(f32, f128, a.*); | |
| 22 | } |
lib/compiler_rt/trunctfxf2.zig deleted-67| ... | ... | @@ -1,67 +0,0 @@ |
| 1 | const math = @import("std").math; | |
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 3 | const symbol = compiler_rt.symbol; | |
| 4 | const trunc_f80 = @import("./truncf.zig").trunc_f80; | |
| 5 | ||
| 6 | comptime { | |
| 7 | symbol(&__trunctfxf2, "__trunctfxf2"); | |
| 8 | } | |
| 9 | ||
| 10 | pub fn __trunctfxf2(a: f128) callconv(.c) f80 { | |
| 11 | const src_sig_bits = math.floatMantissaBits(f128); | |
| 12 | const dst_sig_bits = math.floatMantissaBits(f80) - 1; // -1 for the integer bit | |
| 13 | ||
| 14 | // Various constants whose values follow from the type parameters. | |
| 15 | // Any reasonable optimizer will fold and propagate all of these. | |
| 16 | const src_bits = @typeInfo(f128).float.bits; | |
| 17 | const src_exp_bits = src_bits - src_sig_bits - 1; | |
| 18 | const src_inf_exp = 0x7FFF; | |
| 19 | ||
| 20 | const src_inf = src_inf_exp << src_sig_bits; | |
| 21 | const src_sign_mask = 1 << (src_sig_bits + src_exp_bits); | |
| 22 | const src_abs_mask = src_sign_mask - 1; | |
| 23 | const round_mask = (1 << (src_sig_bits - dst_sig_bits)) - 1; | |
| 24 | const halfway = 1 << (src_sig_bits - dst_sig_bits - 1); | |
| 25 | ||
| 26 | // Break a into a sign and representation of the absolute value | |
| 27 | const a_rep = @as(u128, @bitCast(a)); | |
| 28 | const a_abs = a_rep & src_abs_mask; | |
| 29 | const sign: u16 = if (a_rep & src_sign_mask != 0) 0x8000 else 0; | |
| 30 | const integer_bit = 1 << 63; | |
| 31 | ||
| 32 | var res: math.F80 = undefined; | |
| 33 | ||
| 34 | if (a_abs > src_inf) { | |
| 35 | // a is NaN. | |
| 36 | // Conjure the result by beginning with infinity, setting the qNaN | |
| 37 | // bit and inserting the (truncated) trailing NaN field. | |
| 38 | res.exp = 0x7fff; | |
| 39 | res.fraction = 0x8000000000000000; | |
| 40 | res.fraction |= @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits))); | |
| 41 | } else { | |
| 42 | // The exponent of a is within the range of normal numbers in the | |
| 43 | // destination format. We can convert by simply right-shifting with | |
| 44 | // rounding, adding the explicit integer bit, and adjusting the exponent | |
| 45 | res.fraction = @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits))) | integer_bit; | |
| 46 | res.exp = @truncate(a_abs >> src_sig_bits); | |
| 47 | ||
| 48 | const round_bits = a_abs & round_mask; | |
| 49 | if (round_bits > halfway) { | |
| 50 | // Round to nearest | |
| 51 | const ov = @addWithOverflow(res.fraction, 1); | |
| 52 | res.fraction = ov[0]; | |
| 53 | res.exp += ov[1]; | |
| 54 | res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry | |
| 55 | } else if (round_bits == halfway) { | |
| 56 | // Ties to even | |
| 57 | const ov = @addWithOverflow(res.fraction, res.fraction & 1); | |
| 58 | res.fraction = ov[0]; | |
| 59 | res.exp += ov[1]; | |
| 60 | res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry | |
| 61 | } | |
| 62 | if (res.exp == 0) res.fraction &= ~@as(u64, integer_bit); // Remove integer bit for de-normals | |
| 63 | } | |
| 64 | ||
| 65 | res.exp |= sign; | |
| 66 | return res.toFloat(); | |
| 67 | } |
lib/compiler_rt/truncxfdf2.zig deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 2 | const trunc_f80 = @import("./truncf.zig").trunc_f80; | |
| 3 | ||
| 4 | comptime { | |
| 5 | symbol(&__truncxfdf2, "__truncxfdf2"); | |
| 6 | } | |
| 7 | ||
| 8 | fn __truncxfdf2(a: f80) callconv(.c) f64 { | |
| 9 | return trunc_f80(f64, a); | |
| 10 | } |
lib/compiler_rt/truncxfhf2.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | const trunc_f80 = @import("./truncf.zig").trunc_f80; | |
| 4 | ||
| 5 | comptime { | |
| 6 | symbol(&__truncxfhf2, "__truncxfhf2"); | |
| 7 | } | |
| 8 | ||
| 9 | fn __truncxfhf2(a: f80) callconv(.c) compiler_rt.F16T(f80) { | |
| 10 | return @bitCast(trunc_f80(f16, a)); | |
| 11 | } |
lib/compiler_rt/truncxfsf2.zig deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | const trunc_f80 = @import("./truncf.zig").trunc_f80; | |
| 2 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 3 | ||
| 4 | comptime { | |
| 5 | symbol(&__truncxfsf2, "__truncxfsf2"); | |
| 6 | } | |
| 7 | ||
| 8 | fn __truncxfsf2(a: f80) callconv(.c) f32 { | |
| 9 | return trunc_f80(f32, a); | |
| 10 | } |
lib/compiler_rt/udivmodei4.zig+1-1| ... | ... | @@ -6,7 +6,7 @@ const shr = std.math.shr; |
| 6 | 6 | const shl = std.math.shl; |
| 7 | 7 | |
| 8 | 8 | const compiler_rt = @import("../compiler_rt.zig"); |
| 9 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 9 | const symbol = compiler_rt.symbol; | |
| 10 | 10 | |
| 11 | 11 | const max_limbs = @divCeil(65535, 32); // max supported type is u65535 |
| 12 | 12 |
lib/compiler_rt/unorddf2.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const compiler_rt = @import("../compiler_rt.zig"); | |
| 2 | const comparef = @import("./comparef.zig"); | |
| 3 | const symbol = @import("../compiler_rt.zig").symbol; | |
| 4 | ||
| 5 | comptime { | |
| 6 | if (compiler_rt.want_aeabi) { | |
| 7 | symbol(&__aeabi_dcmpun, "__aeabi_dcmpun"); | |
| 8 | } else { | |
| 9 | symbol(&__unorddf2, "__unorddf2"); | |
| 10 | } | |
| 11 | } | |
| 12 | ||
| 13 | pub fn __unorddf2(a: f64, b: f64) callconv(.c) i32 { | |
| 14 | return comparef.unordcmp(f64, a, b); | |
| 15 | } | |
| 16 | ||
| 17 | fn __aeabi_dcmpun(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { | |
| 18 | return comparef.unordcmp(f64, a, b); | |
| 19 | } |
lib/std/crypto/Certificate.zig+1-1| ... | ... | @@ -1211,7 +1211,7 @@ pub const rsa = struct { |
| 1211 | 1211 | 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, |
| 1212 | 1212 | 0x00, 0x04, 0x40, |
| 1213 | 1213 | }, |
| 1214 | else => @compileError("unreachable"), | |
| 1214 | else => comptime unreachable, | |
| 1215 | 1215 | }; |
| 1216 | 1216 | em_index -= hash_der.len; |
| 1217 | 1217 | @memcpy(em[em_index..][0..hash_der.len], hash_der); |
lib/std/math.zig+2-2| ... | ... | @@ -75,7 +75,7 @@ pub const snan = float.snan; |
| 75 | 75 | /// |
| 76 | 76 | /// NaN values are never considered equal to any value. |
| 77 | 77 | pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool { |
| 78 | assert(@typeInfo(T) == .float or @typeInfo(T) == .comptime_float); | |
| 78 | comptime assert(@typeInfo(T) == .float or @typeInfo(T) == .comptime_float); | |
| 79 | 79 | assert(tolerance >= 0); |
| 80 | 80 | |
| 81 | 81 | // Fast path for equal values (and signed zeros and infinites). |
| ... | ... | @@ -103,7 +103,7 @@ pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool { |
| 103 | 103 | /// |
| 104 | 104 | /// NaN values are never considered equal to any value. |
| 105 | 105 | pub fn approxEqRel(comptime T: type, x: T, y: T, tolerance: T) bool { |
| 106 | assert(@typeInfo(T) == .float or @typeInfo(T) == .comptime_float); | |
| 106 | comptime assert(@typeInfo(T) == .float or @typeInfo(T) == .comptime_float); | |
| 107 | 107 | assert(tolerance > 0); |
| 108 | 108 | |
| 109 | 109 | // Fast path for equal values (and signed zeros and infinites). |
lib/std/math/atan2.zig+4-4| ... | ... | @@ -252,8 +252,8 @@ test "atan2_32.special" { |
| 252 | 252 | |
| 253 | 253 | try expect(math.isNan(atan2_32(1.0, math.nan(f32)))); |
| 254 | 254 | try expect(math.isNan(atan2_32(math.nan(f32), 1.0))); |
| 255 | try expect(atan2_32(0.0, 5.0) == 0.0); | |
| 256 | try expect(atan2_32(-0.0, 5.0) == -0.0); | |
| 255 | try expect(math.isPositiveZero(atan2_32(0.0, 5.0))); | |
| 256 | try expect(math.isNegativeZero(atan2_32(-0.0, 5.0))); | |
| 257 | 257 | try expect(math.approxEqAbs(f32, atan2_32(0.0, -5.0), math.pi, epsilon)); |
| 258 | 258 | //expect(math.approxEqAbs(f32, atan2_32(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero? |
| 259 | 259 | try expect(math.approxEqAbs(f32, atan2_32(1.0, 0.0), math.pi / 2.0, epsilon)); |
| ... | ... | @@ -276,8 +276,8 @@ test "atan2_64.special" { |
| 276 | 276 | |
| 277 | 277 | try expect(math.isNan(atan2_64(1.0, math.nan(f64)))); |
| 278 | 278 | try expect(math.isNan(atan2_64(math.nan(f64), 1.0))); |
| 279 | try expect(atan2_64(0.0, 5.0) == 0.0); | |
| 280 | try expect(atan2_64(-0.0, 5.0) == -0.0); | |
| 279 | try expect(math.isPositiveZero(atan2_64(0.0, 5.0))); | |
| 280 | try expect(math.isNegativeZero(atan2_64(-0.0, 5.0))); | |
| 281 | 281 | try expect(math.approxEqAbs(f64, atan2_64(0.0, -5.0), math.pi, epsilon)); |
| 282 | 282 | //expect(math.approxEqAbs(f64, atan2_64(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero? |
| 283 | 283 | try expect(math.approxEqAbs(f64, atan2_64(1.0, 0.0), math.pi / 2.0, epsilon)); |
lib/std/zig/target.zig+14| ... | ... | @@ -527,6 +527,20 @@ pub fn intAlignment(target: *const std.Target, bits: u16) u16 { |
| 527 | 527 | }; |
| 528 | 528 | } |
| 529 | 529 | |
| 530 | pub fn compilerRtFloatAbi(target: *const std.Target, bits: u16) std.Target.Abi.Float { | |
| 531 | if (target.cpu.has(.x86, .soft_float)) return .soft; | |
| 532 | // Marks targets where clang does not even provide a usable C type. | |
| 533 | const no_c_type_available = .soft; | |
| 534 | switch (bits) { | |
| 535 | else => unreachable, | |
| 536 | 16 => if (target.cpu.arch.isMIPS() or target.cpu.arch.isPowerPC()) return no_c_type_available, | |
| 537 | 32, 64 => {}, | |
| 538 | 80 => if (target.cTypeBitSize(.longdouble) != 80) return no_c_type_available, | |
| 539 | 128 => if (target.cTypeBitSize(.longdouble) <= 64) return no_c_type_available, | |
| 540 | } | |
| 541 | return .hard; | |
| 542 | } | |
| 543 | ||
| 530 | 544 | const std = @import("std"); |
| 531 | 545 | const assert = std.debug.assert; |
| 532 | 546 | const Allocator = std.mem.Allocator; |
src/link.zig+1-1| ... | ... | @@ -2127,7 +2127,7 @@ pub fn resolveInputs( |
| 2127 | 2127 | continue; |
| 2128 | 2128 | }, |
| 2129 | 2129 | } |
| 2130 | @compileError("unreachable"); | |
| 2130 | comptime unreachable; | |
| 2131 | 2131 | } |
| 2132 | 2132 | |
| 2133 | 2133 | if (failed_libs.items.len > 0) { |
test/behavior/cast.zig+1-1| ... | ... | @@ -1845,7 +1845,7 @@ test "coerce between pointers of compatible differently-named floats" { |
| 1845 | 1845 | 64 => f64, |
| 1846 | 1846 | 80 => f80, |
| 1847 | 1847 | 128 => f128, |
| 1848 | else => @compileError("unreachable"), | |
| 1848 | else => comptime unreachable, | |
| 1849 | 1849 | }; |
| 1850 | 1850 | var f1: F = 12.34; |
| 1851 | 1851 | const f2: *c_longdouble = &f1; |
test/behavior/floatop.zig+4-4| ... | ... | @@ -431,9 +431,9 @@ fn testSqrt(comptime T: type) !void { |
| 431 | 431 | var inf: T = math.inf(T); |
| 432 | 432 | try expect(math.isPositiveInf(@sqrt(inf))); |
| 433 | 433 | var zero: T = 0.0; |
| 434 | try expect(@sqrt(zero) == 0.0); | |
| 434 | try expect(math.isPositiveZero(@sqrt(zero))); | |
| 435 | 435 | var neg_zero: T = -0.0; |
| 436 | try expect(@sqrt(neg_zero) == 0.0); | |
| 436 | try expect(math.isNegativeZero(@sqrt(neg_zero))); | |
| 437 | 437 | var neg_one: T = -1.0; |
| 438 | 438 | try expect(math.isNan(@sqrt(neg_one))); |
| 439 | 439 | var nan: T = math.nan(T); |
| ... | ... | @@ -1501,9 +1501,9 @@ fn testNeg(comptime T: type) !void { |
| 1501 | 1501 | |
| 1502 | 1502 | // subnormals |
| 1503 | 1503 | var zero: T = 0.0; |
| 1504 | try expect(-zero == -0.0); | |
| 1504 | try expect(math.isNegativeZero(-zero)); | |
| 1505 | 1505 | var neg_zero: T = -0.0; |
| 1506 | try expect(-neg_zero == 0.0); | |
| 1506 | try expect(math.isPositiveZero(-neg_zero)); | |
| 1507 | 1507 | var true_min: T = math.floatTrueMin(T); |
| 1508 | 1508 | try expect(-true_min == -math.floatTrueMin(T)); |
| 1509 | 1509 | var neg_true_min: T = -math.floatTrueMin(T); |
test/behavior/switch.zig+1-1| ... | ... | @@ -1267,7 +1267,7 @@ test "switch with complex item expressions" { |
| 1267 | 1267 | test "switch evaluation order" { |
| 1268 | 1268 | const eu: anyerror!u32 = 0; |
| 1269 | 1269 | _ = eu catch |err| switch (err) { |
| 1270 | if (true) @compileError("unreachable") => unreachable, | |
| 1270 | if (true) comptime unreachable => unreachable, | |
| 1271 | 1271 | else => unreachable, |
| 1272 | 1272 | }; |
| 1273 | 1273 | } |
test/behavior/switch_on_captured_error.zig+3-3| ... | ... | @@ -243,7 +243,7 @@ test "switch on error union catch capture" { |
| 243 | 243 | var a: error{}!u64 = 0; |
| 244 | 244 | _ = &a; |
| 245 | 245 | const b = a catch |err| switch (err) { |
| 246 | undefined => @compileError("unreachable"), | |
| 246 | undefined => comptime unreachable, | |
| 247 | 247 | }; |
| 248 | 248 | try expectEqual(@as(u64, 0), b); |
| 249 | 249 | } |
| ... | ... | @@ -829,7 +829,7 @@ test "switch on error union if else capture" { |
| 829 | 829 | var a: error{}!u64 = 0; |
| 830 | 830 | _ = &a; |
| 831 | 831 | const b = if (a) |x| x else |err| switch (err) { |
| 832 | undefined => @compileError("unreachable"), | |
| 832 | undefined => comptime unreachable, | |
| 833 | 833 | }; |
| 834 | 834 | try expectEqual(@as(u64, 0), b); |
| 835 | 835 | } |
| ... | ... | @@ -840,7 +840,7 @@ test "switch on error union if else capture" { |
| 840 | 840 | var a: error{}!u64 = 0; |
| 841 | 841 | _ = &a; |
| 842 | 842 | const b = if (a) |*x| x.* else |err| switch (err) { |
| 843 | undefined => @compileError("unreachable"), | |
| 843 | undefined => comptime unreachable, | |
| 844 | 844 | }; |
| 845 | 845 | try expectEqual(@as(u64, 0), b); |
| 846 | 846 | } |