authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-06-24 19:25:35-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-07-27 14:35:12-04:00
loga242b0be888fbcffd4eaa2e3af9cb30bc3c71584
tree206800945aea793494fc490cd2343a77d391d244
parent0c0be6da880fd1a6bdd3266125d6c5bcaac2803f

compiler_rt: change float abi so it can become compatible with cbe


213 files changed, 6404 insertions(+), 7023 deletions(-)

lib/compiler/resinator/parse.zig+1-1
...@@ -1277,7 +1277,7 @@ pub const Parser = struct {...@@ -1277,7 +1277,7 @@ pub const Parser = struct {
1277 },1277 },
1278 else => unreachable,1278 else => unreachable,
1279 }1279 }
1280 @compileError("unreachable");1280 comptime unreachable;
1281 }1281 }
12821282
1283 pub const OptionalParamParser = struct {1283 pub const OptionalParamParser = struct {
lib/compiler_rt.zig+120-168
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2const compiler_rt = @This();
2const ofmt_c = builtin.object_format == .c;3const ofmt_c = builtin.object_format == .c;
3const native_endian = builtin.cpu.arch.endian();4const native_endian = builtin.cpu.arch.endian();
45
...@@ -84,144 +85,17 @@ comptime {...@@ -84,144 +85,17 @@ comptime {
84 // Float routines85 // Float routines
85 // conversion86 // conversion
86 _ = @import("compiler_rt/extendf.zig");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 _ = @import("compiler_rt/truncf.zig");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 _ = @import("compiler_rt/int_from_float.zig");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 _ = @import("compiler_rt/float_from_int.zig");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");
19091
191 // comparison92 // comparison
192 _ = @import("compiler_rt/comparef.zig");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");
20294
203 // arithmetic95 // arithmetic
204 _ = @import("compiler_rt/addf3.zig");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 _ = @import("compiler_rt/mulf3.zig");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");
22398
224 _ = @import("compiler_rt/divhf3.zig");
225 _ = @import("compiler_rt/divsf3.zig");99 _ = @import("compiler_rt/divsf3.zig");
226 _ = @import("compiler_rt/divdf3.zig");100 _ = @import("compiler_rt/divdf3.zig");
227 _ = @import("compiler_rt/divxf3.zig");101 _ = @import("compiler_rt/divxf3.zig");
...@@ -235,25 +109,17 @@ comptime {...@@ -235,25 +109,17 @@ comptime {
235 symbol(&__negsf2, "__negsf2");109 symbol(&__negsf2, "__negsf2");
236 symbol(&__negdf2, "__negdf2");110 symbol(&__negdf2, "__negdf2");
237 }111 }
238 if (want_ppc_abi) symbol(&__negtf2, "__negkf2");112 if (want_ppc_abi) {
239 symbol(&__negtf2, "__negtf2");113 symbol(&__negtf2, "__negkf2");
114 } else {
115 symbol(&__negtf2, "__negtf2");
116 }
240 symbol(&__negxf2, "__negxf2");117 symbol(&__negxf2, "__negxf2");
241118
242 // other119 // other
243 _ = @import("compiler_rt/powiXf2.zig");120 _ = @import("compiler_rt/powiXf2.zig");
244 _ = @import("compiler_rt/mulc3.zig");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 _ = @import("compiler_rt/divc3.zig");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");
257123
258 // Math routines. Alphabetically sorted.124 // Math routines. Alphabetically sorted.
259 _ = @import("compiler_rt/cos.zig");125 _ = @import("compiler_rt/cos.zig");
...@@ -279,7 +145,7 @@ comptime {...@@ -279,7 +145,7 @@ comptime {
279 _ = @import("compiler_rt/divmodei4.zig");145 _ = @import("compiler_rt/divmodei4.zig");
280 _ = @import("compiler_rt/udivmodei4.zig");146 _ = @import("compiler_rt/udivmodei4.zig");
281147
282 _ = @import("compiler_rt/limb64.zig");148 if (builtin.cpu.arch.isWasm()) _ = @import("compiler_rt/limb64.zig");
283149
284 // extra150 // extra
285 _ = @import("compiler_rt/os_version_check.zig");151 _ = @import("compiler_rt/os_version_check.zig");
...@@ -290,7 +156,7 @@ comptime {...@@ -290,7 +156,7 @@ comptime {
290 _ = @import("compiler_rt/clear_cache.zig");156 _ = @import("compiler_rt/clear_cache.zig");
291 _ = @import("compiler_rt/hexagon.zig");157 _ = @import("compiler_rt/hexagon.zig");
292158
293 if (@import("builtin").object_format != .c) {159 if (builtin.object_format != .c) {
294 if (builtin.zig_backend != .stage2_aarch64) _ = @import("compiler_rt/atomics.zig");160 if (builtin.zig_backend != .stage2_aarch64) _ = @import("compiler_rt/atomics.zig");
295 _ = @import("compiler_rt/stack_probe.zig");161 _ = @import("compiler_rt/stack_probe.zig");
296162
...@@ -366,10 +232,7 @@ pub const want_aeabi = switch (builtin.abi) {...@@ -366,10 +232,7 @@ pub const want_aeabi = switch (builtin.abi) {
366 .gnueabihf,232 .gnueabihf,
367 .android,233 .android,
368 .androideabi,234 .androideabi,
369 => switch (builtin.cpu.arch) {235 => builtin.cpu.arch.isArm(),
370 .arm, .armeb, .thumb, .thumbeb => true,
371 else => false,
372 },
373 else => false,236 else => false,
374};237};
375238
...@@ -443,19 +306,108 @@ pub const gnu_f16_abi = switch (builtin.cpu.arch) {...@@ -443,19 +306,108 @@ pub const gnu_f16_abi = switch (builtin.cpu.arch) {
443pub const want_sparc64_abi = builtin.cpu.arch == .sparc64;306pub const want_sparc64_abi = builtin.cpu.arch == .sparc64;
444pub const want_sparc32_abi = builtin.cpu.arch == .sparc;307pub const want_sparc32_abi = builtin.cpu.arch == .sparc;
445308
446pub fn F16T(comptime OtherType: type) type {309/// For operations converting between `f16` and another floating point type.
447 return switch (builtin.cpu.arch) {310pub fn f16Conv(comptime OtherType: type) type {
448 .x86, .x86_64 => if (builtin.target.os.tag.isDarwin()) switch (OtherType) {311 switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 16)) {
449 // Starting with LLVM 16, Darwin uses different abi for f16312 .hard => {},
450 // depending on the type of the other return/argument..???313 .soft => return softFloatAbi(f16),
451 f32, f64 => u16,314 }
452 f80, f128 => f16,315 if (builtin.cpu.arch.isX86() and builtin.os.tag.isDarwin()) switch (OtherType) {
453 else => unreachable,316 else => unreachable,
454 } else f16,317 // Starting with LLVM 16, Darwin uses different abi for f16
455 else => 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}
324pub const @"f16" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 16)) {
325 .hard => hardFloatAbi(f16),
326 .soft => softFloatAbi(f16),
327};
328pub const @"f32" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 32)) {
329 .hard => hardFloatAbi(f32),
330 .soft => softFloatAbi(f32),
331};
332pub const @"f64" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 64)) {
333 .hard => hardFloatAbi(f64),
334 .soft => softFloatAbi(f64),
335};
336pub 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};
352pub 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};
371fn 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}
383fn 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}
395fn 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}
458406
407pub fn Complex(comptime Float: type) type {
408 return struct { real: Float, imag: Float };
409}
410
459pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {411pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
460 switch (Z) {412 switch (Z) {
461 u16 => {413 u16 => {
...@@ -588,31 +540,31 @@ pub inline fn fneg(a: anytype) @TypeOf(a) {...@@ -588,31 +540,31 @@ pub inline fn fneg(a: anytype) @TypeOf(a) {
588 return @bitCast(negated);540 return @bitCast(negated);
589}541}
590542
591fn __negxf2(a: f80) callconv(.c) f80 {543fn __neghf2(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
592 return fneg(a);544 return compiler_rt.f16.toAbi(fneg(compiler_rt.f16.fromAbi(a)));
593}545}
594546
595fn __neghf2(a: f16) callconv(.c) f16 {547fn __negsf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
596 return fneg(a);548 return compiler_rt.f32.toAbi(fneg(compiler_rt.f32.fromAbi(a)));
597}549}
598550
599fn __negdf2(a: f64) callconv(.c) f64 {551fn __negdf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
600 return fneg(a);552 return compiler_rt.f64.toAbi(fneg(compiler_rt.f64.fromAbi(a)));
601}553}
602554
603fn __aeabi_dneg(a: f64) callconv(.{ .arm_aapcs = .{} }) f64 {555fn __negxf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
604 return fneg(a);556 return compiler_rt.f80.toAbi(fneg(compiler_rt.f80.fromAbi(a)));
605}557}
606558
607fn __negtf2(a: f128) callconv(.c) f128 {559fn __negtf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
608 return fneg(a);560 return compiler_rt.f128.toAbi(fneg(compiler_rt.f128.fromAbi(a)));
609}561}
610562
611fn __negsf2(a: f32) callconv(.c) f32 {563fn __aeabi_fneg(a: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
612 return fneg(a);564 return fneg(a);
613}565}
614566
615fn __aeabi_fneg(a: f32) callconv(.{ .arm_aapcs = .{} }) f32 {567fn __aeabi_dneg(a: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
616 return fneg(a);568 return fneg(a);
617}569}
618570
lib/compiler_rt/absv.zig+1-2
...@@ -14,8 +14,7 @@ pub inline fn absv(comptime ST: type, a: ST) ST {...@@ -14,8 +14,7 @@ pub inline fn absv(comptime ST: type, a: ST) ST {
14 const sign: ST = a >> N - 1;14 const sign: ST = a >> N - 1;
15 x +%= sign;15 x +%= sign;
16 x ^= sign;16 x ^= sign;
17 if (x < 0)17 if (x < 0) @panic("integer overflow");
18 @panic("compiler_rt absv: overflow");
19 return x;18 return x;
20}19}
2120
lib/compiler_rt/absvdi2.zig+3-2
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const symbol = @import("../compiler_rt.zig").symbol;1const compiler_rt = @import("../compiler_rt.zig");
2const absv = @import("./absv.zig").absv;2const symbol = compiler_rt.symbol;
3const absv = @import("absv.zig").absv;
34
4comptime {5comptime {
5 symbol(&__absvdi2, "__absvdi2");6 symbol(&__absvdi2, "__absvdi2");
lib/compiler_rt/absvsi2.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const compiler_rt = @import("../compiler_rt.zig");1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;2const symbol = compiler_rt.symbol;
3const absv = @import("./absv.zig").absv;3const absv = @import("absv.zig").absv;
44
5comptime {5comptime {
6 symbol(&__absvsi2, "__absvsi2");6 symbol(&__absvsi2, "__absvsi2");
lib/compiler_rt/absvti2.zig+3-2
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const symbol = @import("../compiler_rt.zig").symbol;1const compiler_rt = @import("../compiler_rt.zig");
2const absv = @import("./absv.zig").absv;2const symbol = compiler_rt.symbol;
3const absv = @import("absv.zig").absv;
34
4comptime {5comptime {
5 symbol(&__absvti2, "__absvti2");6 symbol(&__absvti2, "__absvti2");
lib/compiler_rt/adddf3.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const addf3 = @import("./addf3.zig").addf3;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_dadd, "__aeabi_dadd");
8 } else {
9 symbol(&__adddf3, "__adddf3");
10 }
11}
12
13fn __adddf3(a: f64, b: f64) callconv(.c) f64 {
14 return addf3(f64, a, b);
15}
16
17fn __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,12 +1,143 @@
1const std = @import("std");1const std = @import("std");
2const math = std.math;2const math = std.math;
3const compiler_rt = @import("../compiler_rt.zig");3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
4const normalize = compiler_rt.normalize;5const normalize = compiler_rt.normalize;
56
7comptime {
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
28fn __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}
31pub fn add_f16(a: f16, b: f16) f16 {
32 return addf3(f16, a, b);
33}
34
35fn __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}
38fn __aeabi_fadd(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
39 return add_f32(a, b);
40}
41pub fn add_f32(a: f32, b: f32) f32 {
42 return addf3(f32, a, b);
43}
44
45fn __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}
48fn __aeabi_dadd(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
49 return add_f64(a, b);
50}
51pub fn add_f64(a: f64, b: f64) f64 {
52 return addf3(f64, a, b);
53}
54
55fn __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}
58pub fn add_f80(a: f80, b: f80) f80 {
59 return addf3(f80, a, b);
60}
61
62fn __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}
65fn _Qp_add(c: *f128, a: *f128, b: *f128) callconv(.c) void {
66 c.* = add_f128(a.*, b.*);
67}
68pub fn add_f128(a: f128, b: f128) f128 {
69 return addf3(f128, a, b);
70}
71
72comptime {
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
93fn __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}
96pub fn sub_f16(a: f16, b: f16) f16 {
97 return add_f16(a, compiler_rt.fneg(b));
98}
99
100fn __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}
103fn __aeabi_fsub(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
104 return sub_f32(a, b);
105}
106pub fn sub_f32(a: f32, b: f32) f32 {
107 return add_f32(a, compiler_rt.fneg(b));
108}
109
110fn __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}
113fn __aeabi_dsub(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
114 return sub_f64(a, b);
115}
116pub fn sub_f64(a: f64, b: f64) f64 {
117 return add_f64(a, compiler_rt.fneg(b));
118}
119
120fn __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}
123pub fn sub_f80(a: f80, b: f80) f80 {
124 return add_f80(a, compiler_rt.fneg(b));
125}
126
127fn __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}
130fn _Qp_sub(c: *f128, a: *const f128, b: *const f128) callconv(.c) void {
131 c.* = sub_f128(a.*, b.*);
132}
133pub fn sub_f128(a: f128, b: f128) f128 {
134 return add_f128(a, compiler_rt.fneg(b));
135}
136
6/// Ported from:137/// Ported from:
7///138///
8/// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/lib/builtins/fp_add_impl.inc139/// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/lib/builtins/fp_add_impl.inc
9pub inline fn addf3(comptime T: type, a: T, b: T) T {140inline fn addf3(comptime T: type, a: T, b: T) T {
10 const bits = @typeInfo(T).float.bits;141 const bits = @typeInfo(T).float.bits;
11 const Z = @Int(.unsigned, bits);142 const Z = @Int(.unsigned, bits);
12143
lib/compiler_rt/addf3_test.zig+7-6
...@@ -8,12 +8,13 @@ const builtin = @import("builtin");...@@ -8,12 +8,13 @@ const builtin = @import("builtin");
8const math = std.math;8const math = std.math;
9const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64);9const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64);
1010
11const __addtf3 = @import("addtf3.zig").__addtf3;11const impl = @import("addf3.zig");
12const __addxf3 = @import("addxf3.zig").__addxf3;12const add_f128 = impl.add_f128;
13const __subtf3 = @import("subtf3.zig").__subtf3;13const add_f80 = impl.add_f80;
14const sub_f128 = impl.sub_f128;
1415
15fn test__addtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {16fn 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);
1718
18 const rep: u128 = @bitCast(x);19 const rep: u128 = @bitCast(x);
19 const hi: u64 = @intCast(rep >> 64);20 const hi: u64 = @intCast(rep >> 64);
...@@ -52,7 +53,7 @@ test "addtf3" {...@@ -52,7 +53,7 @@ test "addtf3" {
52}53}
5354
54fn test__subtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {55fn 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);
5657
57 const rep: u128 = @bitCast(x);58 const rep: u128 = @bitCast(x);
58 const hi: u64 = @intCast(rep >> 64);59 const hi: u64 = @intCast(rep >> 64);
...@@ -91,7 +92,7 @@ test "subtf3" {...@@ -91,7 +92,7 @@ test "subtf3" {
91const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1)));92const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1)));
9293
93fn test__addxf3(a: f80, b: f80, expected: u80) !void {94fn test__addxf3(a: f80, b: f80, expected: u80) !void {
94 const x = __addxf3(a, b);95 const x = add_f80(a, b);
95 const rep: u80 = @bitCast(x);96 const rep: u80 = @bitCast(x);
9697
97 if (rep == expected)98 if (rep == expected)
lib/compiler_rt/addhf3.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const addf3 = @import("./addf3.zig").addf3;
4
5comptime {
6 symbol(&__addhf3, "__addhf3");
7}
8
9fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const addf3 = @import("./addf3.zig").addf3;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_fadd, "__aeabi_fadd");
8 } else {
9 symbol(&__addsf3, "__addsf3");
10 }
11}
12
13fn __addsf3(a: f32, b: f32) callconv(.c) f32 {
14 return addf3(f32, a, b);
15}
16
17fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const addf3 = @import("./addf3.zig").addf3;
4
5comptime {
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
16pub fn __addtf3(a: f128, b: f128) callconv(.c) f128 {
17 return addf3(f128, a, b);
18}
19
20fn _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,4 +1,5 @@
1const symbol = @import("../compiler_rt.zig").symbol;1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
2const testing = @import("std").testing;3const testing = @import("std").testing;
34
4comptime {5comptime {
...@@ -9,7 +10,7 @@ pub fn __addvdi3(a: i64, b: i64) callconv(.c) i64 {...@@ -9,7 +10,7 @@ pub fn __addvdi3(a: i64, b: i64) callconv(.c) i64 {
9 const sum = a +% b;10 const sum = a +% b;
10 // Overflow occurred iff both operands have the same sign, and the sign of the sum does11 // Overflow occurred iff both operands have the same sign, and the sign of the sum does
11 // not match it. In other words, iff the sum sign is not the sign of either operand.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 return sum;14 return sum;
14}15}
1516
lib/compiler_rt/addvsi3.zig+1-1
...@@ -10,7 +10,7 @@ pub fn __addvsi3(a: i32, b: i32) callconv(.c) i32 {...@@ -10,7 +10,7 @@ pub fn __addvsi3(a: i32, b: i32) callconv(.c) i32 {
10 const sum = a +% b;10 const sum = a +% b;
11 // Overflow occurred iff both operands have the same sign, and the sign of the sum does11 // Overflow occurred iff both operands have the same sign, and the sign of the sum does
12 // not match it. In other words, iff the sum sign is not the sign of either operand.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 return sum;14 return sum;
15}15}
1616
lib/compiler_rt/addxf3.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const addf3 = @import("./addf3.zig").addf3;
4
5comptime {
6 symbol(&__addxf3, "__addxf3");
7}
8
9pub 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,7 +5,7 @@ const arch = cpu.arch;
5const std = @import("std");5const std = @import("std");
66
7const compiler_rt = @import("../compiler_rt.zig");7const compiler_rt = @import("../compiler_rt.zig");
8const symbol = @import("../compiler_rt.zig").symbol;8const symbol = compiler_rt.symbol;
99
10// This parameter is true iff the target architecture supports the bare minimum10// This parameter is true iff the target architecture supports the bare minimum
11// to implement the atomic load/store intrinsics.11// to implement the atomic load/store intrinsics.
lib/compiler_rt/aulldiv.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
22
3const compiler_rt = @import("../compiler_rt.zig");3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = @import("../compiler_rt.zig").symbol;4const symbol = compiler_rt.symbol;
55
6comptime {6comptime {
7 if (compiler_rt.want_windows_x86_msvc_abi) {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
3const compiler_rt = @import("../compiler_rt.zig");
4const comparef = @import("./comparef.zig");
5const symbol = @import("../compiler_rt.zig").symbol;
6
7comptime {
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`.
27fn __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."
33pub 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.
40pub 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.
47pub 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."
53pub fn __ltdf2(a: f64, b: f64) callconv(.c) i32 {
54 return __cmpdf2(a, b);
55}
56
57fn __aeabi_dcmpeq(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
58 return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) == .Equal);
59}
60
61fn __aeabi_dcmplt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
62 return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) == .Less);
63}
64
65fn __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
3const compiler_rt = @import("../compiler_rt.zig");
4const comparef = @import("./comparef.zig");
5const symbol = @import("../compiler_rt.zig").symbol;
6
7comptime {
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`.
43fn __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."
49fn __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.
56fn __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.
63fn __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."
69fn __lttf2(a: f128, b: f128) callconv(.c) i32 {
70 return __cmptf2(a, b);
71}
72
73const SparcFCMP = enum(i32) {
74 Equal = 0,
75 Less = 1,
76 Greater = 2,
77 Unordered = 3,
78};
79
80fn _Qp_cmp(a: *const f128, b: *const f128) callconv(.c) i32 {
81 return @backingInt(comparef.cmpf2(f128, SparcFCMP, a.*, b.*));
82}
83
84fn _Qp_feq(a: *const f128, b: *const f128) callconv(.c) bool {
85 return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Equal;
86}
87
88fn _Qp_fne(a: *const f128, b: *const f128) callconv(.c) bool {
89 return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) != .Equal;
90}
91
92fn _Qp_flt(a: *const f128, b: *const f128) callconv(.c) bool {
93 return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Less;
94}
95
96fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.c) bool {
97 return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Greater;
98}
99
100fn _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
107fn _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
114fn _Q_cmp(a: f128, b: f128) callconv(.c) i32 {
115 return @backingInt(comparef.cmpf2(f128, SparcFCMP, a, b));
116}
117
118fn _Q_feq(a: f128, b: f128) callconv(.c) bool {
119 return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Equal;
120}
121
122fn _Q_fne(a: f128, b: f128) callconv(.c) bool {
123 return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) != .Equal;
124}
125
126fn _Q_flt(a: f128, b: f128) callconv(.c) bool {
127 return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Less;
128}
129
130fn _Q_fgt(a: f128, b: f128) callconv(.c) bool {
131 return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Greater;
132}
133
134fn _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
141fn _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
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const comparef = @import("./comparef.zig");
6
7comptime {
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`.
21fn __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."
27fn __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.
34fn __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.
41fn __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."
47fn __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,52 +5,12 @@
5const std = @import("std");5const std = @import("std");
6const builtin = @import("builtin");6const builtin = @import("builtin");
77
8const __eqdf2 = @import("./cmpdf2.zig").__eqdf2;8const compiler_rt = @import("../compiler_rt.zig");
9const __ledf2 = @import("./cmpdf2.zig").__ledf2;
10const __ltdf2 = @import("./cmpdf2.zig").__ltdf2;
11const __nedf2 = @import("./cmpdf2.zig").__nedf2;
129
13const __gedf2 = @import("./gedf2.zig").__gedf2;10const impl = @import("comparef.zig");
14const __gtdf2 = @import("./gedf2.zig").__gtdf2;11const Order = impl.Order;
1512const cmp_f64 = impl.cmp_f64;
16const __unorddf2 = @import("./unorddf2.zig").__unorddf2;13const unord_f64 = impl.unord_f64;
17
18const 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
30fn 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}
5414
55const arguments = [_]f64{15const arguments = [_]f64{
56 std.math.nan(f64),16 std.math.nan(f64),
...@@ -73,36 +33,20 @@ const arguments = [_]f64{...@@ -73,36 +33,20 @@ const arguments = [_]f64{
73 std.math.inf(f64),33 std.math.inf(f64),
74};34};
7535
76fn generateVector(comptime a: f64, comptime b: f64) TestVector {36test "compare f64" {
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
93const test_vectors = init: {
94 @setEvalBranchQuota(10000);
95 var vectors: [arguments.len * arguments.len]TestVector = undefined;
96 for (arguments[0..], 0..) |arg_i, i| {37 for (arguments[0..], 0..) |arg_i, i| {
97 for (arguments[0..], 0..) |arg_j, j| {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
104test "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,163 +1,309 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
23
3const compiler_rt = @import("../compiler_rt.zig");4const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;5const symbol = compiler_rt.symbol;
56
6comptime {7const Unordered = if (builtin.cpu.arch == .avr)
7 if (compiler_rt.want_aeabi) {8 i8
8 symbol(&__aeabi_fcmpun, "__aeabi_fcmpun");9else if (builtin.cpu.arch.isAARCH64())
9 } else {10 i32
10 symbol(&__unordsf2, "__unordsf2");11else if (builtin.target.cTypeBitSize(.long) >= builtin.target.ptrBitWidth())
11 }12 c_long
1213else
13 symbol(&__unordxf2, "__unordxf2");14 c_longlong;
15pub const Order = enum(Unordered) { lt = -1, eq = 0, gt = 1 };
16const SparcOrder = enum(i32) { eq = 0, lt = 1, gt = 2, un = 3 };
1417
15 symbol(&__eqhf2, "__eqhf2");18comptime {
16 symbol(&__nehf2, "__nehf2");
17 symbol(&__lehf2, "__lehf2");
18 symbol(&__cmphf2, "__cmphf2");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");
2027
21 if (compiler_rt.want_aeabi) {28 if (compiler_rt.want_aeabi) {
22 symbol(&__aeabi_fcmpeq, "__aeabi_fcmpeq");29 symbol(&__aeabi_fcmpeq, "__aeabi_fcmpeq");
23 symbol(&__aeabi_fcmplt, "__aeabi_fcmplt");30 symbol(&__aeabi_fcmplt, "__aeabi_fcmplt");
24 symbol(&__aeabi_fcmple, "__aeabi_fcmple");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 } else {42 } else {
26 symbol(&__eqsf2, "__eqsf2");
27 symbol(&__nesf2, "__nesf2");
28 symbol(&__lesf2, "__lesf2");
29 symbol(&__cmpsf2, "__cmpsf2");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 }
3261
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 if (compiler_rt.want_ppc_abi) {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 symbol(&__unordtf2, "__unordkf2");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
40pub fn __unordhf2(a: f16, b: f16) callconv(.c) i32 {
41 return unordcmp(f16, a, b);
42}105}
43106
44pub fn __unordtf2(a: f128, b: f128) callconv(.c) i32 {107fn __cmphf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Order {
45 return unordcmp(f128, a, b);108 return cmp_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)) orelse .gt;
46}109}
47110fn __gehf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Order {
48/// "These functions calculate a <=> b. That is, if a is less than b, they return -1;111 return cmp_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)) orelse .lt;
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`.
54fn __cmpsf2(a: f32, b: f32) callconv(.c) i32 {
55 return @backingInt(cmpf2(f32, LE, a, b));
56}112}
57113fn __unordhf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Unordered {
58/// "These functions return a value less than or equal to zero if neither argument is NaN,114 return @intFromBool(unord_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)));
59/// and a is less than or equal to b."
60pub fn __lesf2(a: f32, b: f32) callconv(.c) i32 {
61 return __cmpsf2(a, b);
62}115}
63116pub fn cmp_f16(a: f16, b: f16) ?Order {
64/// "These functions return zero if neither argument is NaN, and a and b are equal."117 return cmpf2(f16, a, b);
65/// Note that due to some kind of historical accident, __eqsf2 and __nesf2 are defined
66/// to have the same return value.
67pub fn __eqsf2(a: f32, b: f32) callconv(.c) i32 {
68 return __cmpsf2(a, b);
69}118}
70119pub fn unord_f16(a: f16, b: f16) bool {
71/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal."120 return unord(f16, a, b);
72/// Note that due to some kind of historical accident, __eqsf2 and __nesf2 are defined
73/// to have the same return value.
74pub fn __nesf2(a: f32, b: f32) callconv(.c) i32 {
75 return __cmpsf2(a, b);
76}121}
77122
78/// "These functions return a value less than zero if neither argument is NaN, and a123fn __cmpsf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Order {
79/// is strictly less than b."124 return cmp_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)) orelse .gt;
80pub fn __ltsf2(a: f32, b: f32) callconv(.c) i32 {
81 return __cmpsf2(a, b);
82}125}
83
84fn __aeabi_fcmpeq(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {126fn __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
88fn __aeabi_fcmplt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {129fn __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
92fn __aeabi_fcmple(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {132fn __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}
95135fn __gesf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Order {
96/// "These functions calculate a <=> b. That is, if a is less than b, they return -1;136 return cmp_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)) orelse .lt;
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`.
102fn __cmphf2(a: f16, b: f16) callconv(.c) i32 {
103 return @backingInt(cmpf2(f16, LE, a, b));
104}137}
105138fn __aeabi_fcmpge(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
106/// "These functions return a value less than or equal to zero if neither argument is NaN,139 return @intFromBool(cmp_f32(a, b) orelse .lt != .lt);
107/// and a is less than or equal to b."
108fn __lehf2(a: f16, b: f16) callconv(.c) i32 {
109 return __cmphf2(a, b);
110}140}
111141fn __aeabi_fcmpgt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
112/// "These functions return zero if neither argument is NaN, and a and b are equal."142 return @intFromBool(cmp_f32(a, b) == .gt);
113/// Note that due to some kind of historical accident, __eqhf2 and __nehf2 are defined
114/// to have the same return value.
115fn __eqhf2(a: f16, b: f16) callconv(.c) i32 {
116 return __cmphf2(a, b);
117}143}
118144fn __unordsf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Unordered {
119/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal."145 return @intFromBool(unord_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)));
120/// Note that due to some kind of historical accident, __eqhf2 and __nehf2 are defined
121/// to have the same return value.
122fn __nehf2(a: f16, b: f16) callconv(.c) i32 {
123 return __cmphf2(a, b);
124}146}
125147fn __aeabi_fcmpun(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
126/// "These functions return a value less than zero if neither argument is NaN, and a148 return @intFromBool(unord_f32(a, b));
127/// is strictly less than b."
128fn __lthf2(a: f16, b: f16) callconv(.c) i32 {
129 return __cmphf2(a, b);
130}149}
131150pub fn cmp_f32(a: f32, b: f32) ?Order {
132fn __unordxf2(a: f80, b: f80) callconv(.c) i32 {151 return cmpf2(f32, a, b);
133 return unordcmp(f80, a, b);152}
153pub fn unord_f32(a: f32, b: f32) bool {
154 return unord(f32, a, b);
134}155}
135156
136pub fn __unordsf2(a: f32, b: f32) callconv(.c) i32 {157fn __cmpdf2(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) Order {
137 return unordcmp(f32, a, b);158 return cmp_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)) orelse .gt;
159}
160fn __aeabi_dcmpeq(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
161 return @intFromBool(cmp_f64(a, b) == .eq);
162}
163fn __aeabi_dcmplt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
164 return @intFromBool(cmp_f64(a, b) == .lt);
165}
166fn __aeabi_dcmple(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
167 return @intFromBool(cmp_f64(a, b) orelse .gt != .gt);
168}
169fn __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}
172fn __aeabi_dcmpge(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
173 return @intFromBool(cmp_f64(a, b) orelse .lt != .lt);
174}
175fn __aeabi_dcmpgt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
176 return @intFromBool(cmp_f64(a, b) == .gt);
177}
178fn __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}
181fn __aeabi_dcmpun(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
182 return @intFromBool(unord_f64(a, b));
183}
184pub fn cmp_f64(a: f64, b: f64) ?Order {
185 return cmpf2(f64, a, b);
186}
187pub fn unord_f64(a: f64, b: f64) bool {
188 return unord(f64, a, b);
138}189}
139190
140fn __aeabi_fcmpun(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {191fn __cmpxf2(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) Order {
141 return unordcmp(f32, a, b);192 return cmp_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b)) orelse .gt;
193}
194fn __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}
197fn __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}
200pub 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;
143207
144pub const LE = enum(i32) {208 // If either a or b is NaN, they are unordered.
145 Less = -1,209 if ((a_rep.exp & special_exp == special_exp and a_rep.fraction ^ int_bit != 0) or
146 Equal = 0,210 (b_rep.exp & special_exp == special_exp and b_rep.fraction ^ int_bit != 0))
147 Greater = 1,211 return null;
148212
149 const Unordered: LE = .Greater;213 // If a and b are both zeros, they are equal.
150};214 if ((a_rep.fraction | b_rep.fraction) | ((a_rep.exp | b_rep.exp) & special_exp) == 0)
215 return .eq;
151216
152pub const GE = enum(i32) {217 if (@intFromBool(a_rep.exp == b_rep.exp) & @intFromBool(a_rep.fraction == b_rep.fraction) != 0) {
153 Less = -1,218 return .eq;
154 Equal = 0,219 } else if (a_rep.exp & sign_bit != b_rep.exp & sign_bit) {
155 Greater = 1,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}
236pub fn unord_f80(a: f80, b: f80) bool {
237 return unord(f80, a, b);
238}
156239
157 const Unordered: GE = .Less;240fn __cmptf2(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) Order {
158};241 return cmp_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)) orelse .gt;
242}
243fn __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}
246fn __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}
249fn _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}
256fn _Qp_feq(a: *const f128, b: *const f128) callconv(.c) i32 {
257 return @intFromBool(cmp_f128(a.*, b.*) == .eq);
258}
259fn _Qp_fne(a: *const f128, b: *const f128) callconv(.c) i32 {
260 return @intFromBool(cmp_f128(a.*, b.*) != .eq);
261}
262fn _Qp_flt(a: *const f128, b: *const f128) callconv(.c) i32 {
263 return @intFromBool(cmp_f128(a.*, b.*) == .lt);
264}
265fn _Qp_fle(a: *const f128, b: *const f128) callconv(.c) i32 {
266 return @intFromBool((cmp_f128(a.*, b.*) orelse .gt) != .gt);
267}
268fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.c) i32 {
269 return @intFromBool(cmp_f128(a.*, b.*) == .gt);
270}
271fn _Qp_fge(a: *const f128, b: *const f128) callconv(.c) i32 {
272 return @intFromBool((cmp_f128(a.*, b.*) orelse .lt) != .lt);
273}
274fn _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}
281fn _Q_feq(a: f128, b: f128) callconv(.c) i32 {
282 return @intFromBool(cmp_f128(a, b) == .eq);
283}
284fn _Q_fne(a: f128, b: f128) callconv(.c) i32 {
285 return @intFromBool(cmp_f128(a, b) != .eq);
286}
287fn _Q_flt(a: f128, b: f128) callconv(.c) i32 {
288 return @intFromBool(cmp_f128(a, b) == .lt);
289}
290fn _Q_fle(a: f128, b: f128) callconv(.c) i32 {
291 return @intFromBool((cmp_f128(a, b) orelse .gt) != .gt);
292}
293fn _Q_fgt(a: f128, b: f128) callconv(.c) i32 {
294 return @intFromBool(cmp_f128(a, b) == .gt);
295}
296fn _Q_fge(a: f128, b: f128) callconv(.c) i32 {
297 return @intFromBool((cmp_f128(a, b) orelse .lt) != .lt);
298}
299pub fn cmp_f128(a: f128, b: f128) ?Order {
300 return cmpf2(f128, a, b);
301}
302pub fn unord_f128(a: f128, b: f128) bool {
303 return unord(f128, a, b);
304}
159305
160pub inline fn cmpf2(comptime T: type, comptime RT: type, a: T, b: T) RT {306inline fn cmpf2(comptime T: type, a: T, b: T) ?Order {
161 const bits = @typeInfo(T).float.bits;307 const bits = @typeInfo(T).float.bits;
162 const srep_t = @Int(.signed, bits);308 const srep_t = @Int(.signed, bits);
163 const rep_t = @Int(.unsigned, bits);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,81 +321,42 @@ pub inline fn cmpf2(comptime T: type, comptime RT: type, a: T, b: T) RT {
175 const bAbs = @as(rep_t, @bitCast(bInt)) & absMask;321 const bAbs = @as(rep_t, @bitCast(bInt)) & absMask;
176322
177 // If either a or b is NaN, they are unordered.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;
179325
180 // If a and b are both zeros, they are equal.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;
182328
183 // If at least one of a and b is positive, we get the same result comparing329 // If at least one of a and b is positive, we get the same result comparing
184 // a and b as signed integers as we would with a floating-point compare.330 // a and b as signed integers as we would with a floating-point compare.
185 if ((aInt & bInt) >= 0) {331 if ((aInt & bInt) >= 0) {
186 if (aInt < bInt) {332 if (aInt < bInt) {
187 return .Less;333 return .lt;
188 } else if (aInt == bInt) {334 } else if (aInt == bInt) {
189 return .Equal;335 return .eq;
190 } else return .Greater;336 } else return .gt;
191 } else {337 } else {
192 // Otherwise, both are negative, so we need to flip the sense of the338 // Otherwise, both are negative, so we need to flip the sense of the
193 // comparison to get the correct result. (This assumes a twos- or ones-339 // comparison to get the correct result. (This assumes a twos- or ones-
194 // complement integer representation; if integers are represented in a340 // complement integer representation; if integers are represented in a
195 // sign-magnitude representation, then this flip is incorrect).341 // sign-magnitude representation, then this flip is incorrect).
196 if (aInt > bInt) {342 if (aInt > bInt) {
197 return .Less;343 return .lt;
198 } else if (aInt == bInt) {344 } else if (aInt == bInt) {
199 return .Equal;345 return .eq;
200 } else return .Greater;346 } else return .gt;
201 }347 }
202}348}
203349
204pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT {350test cmp_f80 {
205 const a_rep = std.math.F80.fromFloat(a);351 try std.testing.expect(cmp_f80(1.0, 1.0) == .eq);
206 const b_rep = std.math.F80.fromFloat(b);352 try std.testing.expect(cmp_f80(0.0, -0.0) == .eq);
207 const sig_bits = std.math.floatMantissaBits(f80);353 try std.testing.expect(cmp_f80(2.0, 4.0) == .lt);
208 const int_bit = 0x8000000000000000;354 try std.testing.expect(cmp_f80(2.0, -4.0) == .gt);
209 const sign_bit = 0x8000;355 try std.testing.expect(cmp_f80(-2.0, -4.0) == .gt);
210 const special_exp = 0x7FFF;356 try std.testing.expect(cmp_f80(-2.0, 4.0) == .lt);
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
241test "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 }
250}357}
251358
252pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 {359inline fn unord(comptime T: type, a: T, b: T) bool {
253 const rep_t = @Int(.unsigned, @typeInfo(T).float.bits);360 const rep_t = @Int(.unsigned, @typeInfo(T).float.bits);
254361
255 const significandBits = std.math.floatMantissaBits(T);362 const significandBits = std.math.floatMantissaBits(T);
...@@ -261,7 +368,7 @@ pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 {...@@ -261,7 +368,7 @@ pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 {
261 const aAbs: rep_t = @as(rep_t, @bitCast(a)) & absMask;368 const aAbs: rep_t = @as(rep_t, @bitCast(a)) & absMask;
262 const bAbs: rep_t = @as(rep_t, @bitCast(b)) & absMask;369 const bAbs: rep_t = @as(rep_t, @bitCast(b)) & absMask;
263370
264 return @intFromBool(aAbs > infRep or bAbs > infRep);371 return aAbs > infRep or bAbs > infRep;
265}372}
266373
267test {374test {
lib/compiler_rt/comparesf2_test.zig+17-73
...@@ -5,52 +5,12 @@...@@ -5,52 +5,12 @@
5const std = @import("std");5const std = @import("std");
6const builtin = @import("builtin");6const builtin = @import("builtin");
77
8const __eqsf2 = @import("./comparef.zig").__eqsf2;8const compiler_rt = @import("../compiler_rt.zig");
9const __lesf2 = @import("./comparef.zig").__lesf2;
10const __ltsf2 = @import("./comparef.zig").__ltsf2;
11const __nesf2 = @import("./comparef.zig").__nesf2;
129
13const __gesf2 = @import("./gesf2.zig").__gesf2;10const impl = @import("comparef.zig");
14const __gtsf2 = @import("./gesf2.zig").__gtsf2;11const Order = impl.Order;
1512const cmp_f32 = impl.cmp_f32;
16const __unordsf2 = @import("./comparef.zig").__unordsf2;13const unord_f32 = impl.unord_f32;
17
18const 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
30fn 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}
5414
55const arguments = [_]f32{15const arguments = [_]f32{
56 std.math.nan(f32),16 std.math.nan(f32),
...@@ -73,36 +33,20 @@ const arguments = [_]f32{...@@ -73,36 +33,20 @@ const arguments = [_]f32{
73 std.math.inf(f32),33 std.math.inf(f32),
74};34};
7535
76fn generateVector(comptime a: f32, comptime b: f32) TestVector {36test "compare f32" {
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
93const test_vectors = init: {
94 @setEvalBranchQuota(10000);
95 var vectors: [arguments.len * arguments.len]TestVector = undefined;
96 for (arguments[0..], 0..) |arg_i, i| {37 for (arguments[0..], 0..) |arg_i, i| {
97 for (arguments[0..], 0..) |arg_j, j| {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
104test "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,31 +13,35 @@ const expect = std.testing.expect;
13const expectApproxEqAbs = std.testing.expectApproxEqAbs;13const expectApproxEqAbs = std.testing.expectApproxEqAbs;
1414
15const compiler_rt = @import("../compiler_rt.zig");15const compiler_rt = @import("../compiler_rt.zig");
16const symbol = @import("../compiler_rt.zig").symbol;16const symbol = compiler_rt.symbol;
17const trig = @import("trig.zig");17const trig = @import("trig.zig");
18const rem_pio2 = @import("rem_pio2.zig").rem_pio2;18const rem_pio2 = @import("rem_pio2.zig").rem_pio2;
19const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;19const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;
20const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l;20const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l;
2121
22comptime {22comptime {
23 symbol(&cosh, "__cosh");23 symbol(&__cosh, "__cosh");
24 symbol(&cosl, "__cosl");
25 symbol(&cosf, "cosf");24 symbol(&cosf, "cosf");
26 symbol(&cos, "cos");25 symbol(&cos, "cos");
27 symbol(&cosx, "__cosx");26 symbol(&__cosx, "__cosx");
28 if (compiler_rt.want_ppc_abi) {27 if (compiler_rt.want_ppc_abi) symbol(&cosq, "cosf128");
29 symbol(&cosq, "cosf128");
30 }
31 symbol(&cosq, "cosq");28 symbol(&cosq, "cosq");
32 symbol(&cosl, "cosl");29 symbol(&cosl, "cosl");
30 symbol(&cosl, "__cosl"); // required by musl
33}31}
3432
35pub fn cosh(a: f16) callconv(.c) f16 {33fn __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}
36pub fn cos_f16(x: f16) f16 {
36 // TODO: more efficient implementation37 // TODO: more efficient implementation
37 return @floatCast(cosf(a));38 return @floatCast(cos_f32(x));
38}39}
3940
40pub fn cosf(x: f32) callconv(.c) f32 {41fn 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}
44pub fn cos_f32(x: f32) f32 {
41 // Small multiples of pi/2 rounded to double precision.45 // Small multiples of pi/2 rounded to double precision.
42 const c1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D1846 const c1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18
43 const c2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D1847 const c2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18
...@@ -94,7 +98,10 @@ pub fn cosf(x: f32) callconv(.c) f32 {...@@ -94,7 +98,10 @@ pub fn cosf(x: f32) callconv(.c) f32 {
94 };98 };
95}99}
96100
97pub fn cos(x: f64) callconv(.c) f64 {101fn 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}
104pub fn cos_f64(x: f64) f64 {
98 var ix = @as(u64, @bitCast(x)) >> 32;105 var ix = @as(u64, @bitCast(x)) >> 32;
99 ix &= 0x7fffffff;106 ix &= 0x7fffffff;
100107
...@@ -123,7 +130,10 @@ pub fn cos(x: f64) callconv(.c) f64 {...@@ -123,7 +130,10 @@ pub fn cos(x: f64) callconv(.c) f64 {
123 };130 };
124}131}
125132
126pub fn cosx(x: f80) callconv(.c) f80 {133fn __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}
136pub fn cos_f80(x: f80) f80 {
127 const se = ld.signExponent(x) & 0x7fff;137 const se = ld.signExponent(x) & 0x7fff;
128 if (se == 0x7fff) {138 if (se == 0x7fff) {
129 return x - x;139 return x - x;
...@@ -147,7 +157,10 @@ pub fn cosx(x: f80) callconv(.c) f80 {...@@ -147,7 +157,10 @@ pub fn cosx(x: f80) callconv(.c) f80 {
147 };157 };
148}158}
149159
150pub fn cosq(x: f128) callconv(.c) f128 {160fn 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}
163pub fn cos_f128(x: f128) f128 {
151 const se = ld.signExponent(x) & 0x7fff;164 const se = ld.signExponent(x) & 0x7fff;
152 if (se == 0x7fff) {165 if (se == 0x7fff) {
153 return x - x;166 return x - x;
...@@ -173,20 +186,21 @@ pub fn cosq(x: f128) callconv(.c) f128 {...@@ -173,20 +186,21 @@ pub fn cosq(x: f128) callconv(.c) f128 {
173186
174pub fn cosl(x: c_longdouble) callconv(.c) c_longdouble {187pub fn cosl(x: c_longdouble) callconv(.c) c_longdouble {
175 switch (@typeInfo(c_longdouble).float.bits) {188 switch (@typeInfo(c_longdouble).float.bits) {
176 64 => return cos(x),189 64 => return cos_f64(x),
177 80 => return cosx(x),190 80 => return cos_f80(x),
178 128 => return cosq(x),191 128 => return cos_f128(x),
179 else => @compileError("unreachable"),192 else => comptime unreachable,
180 }193 }
181}194}
182195
183fn testCosSpecial(comptime T: type) !void {196fn testCosSpecial(comptime T: type) !void {
184 const f = switch (T) {197 const f = switch (T) {
185 f32 => cosf,198 f16 => cos_f16,
186 f64 => cos,199 f32 => cos_f32,
187 f80 => cosx,200 f64 => cos_f64,
188 f128 => cosq,201 f80 => cos_f80,
189 else => @compileError("unimplemented"),202 f128 => cos_f128,
203 else => comptime unreachable,
190 };204 };
191205
192 try expect(f(0.0) == 1.0);206 try expect(f(0.0) == 1.0);
...@@ -198,13 +212,13 @@ fn testCosSpecial(comptime T: type) !void {...@@ -198,13 +212,13 @@ fn testCosSpecial(comptime T: type) !void {
198212
199test "cos32.normal" {213test "cos32.normal" {
200 const epsilon = math.floatEps(f32);214 const epsilon = math.floatEps(f32);
201 try expectApproxEqAbs(@as(f32, 1.0), cosf(0.0), epsilon);215 try expectApproxEqAbs(@as(f32, 1.0), cos_f32(0.0), epsilon);
202 try expectApproxEqAbs(@as(f32, 0.9800666), cosf(0.2), epsilon);216 try expectApproxEqAbs(@as(f32, 0.9800666), cos_f32(0.2), epsilon);
203 try expectApproxEqAbs(@as(f32, 0.6276231), cosf(0.8923), epsilon);217 try expectApproxEqAbs(@as(f32, 0.6276231), cos_f32(0.8923), epsilon);
204 try expectApproxEqAbs(@as(f32, 0.0707372), cosf(1.5), epsilon);218 try expectApproxEqAbs(@as(f32, 0.0707372), cos_f32(1.5), epsilon);
205 try expectApproxEqAbs(@as(f32, 0.0707372), cosf(-1.5), epsilon);219 try expectApproxEqAbs(@as(f32, 0.0707372), cos_f32(-1.5), epsilon);
206 try expectApproxEqAbs(@as(f32, 0.96913195), cosf(37.45), epsilon);220 try expectApproxEqAbs(@as(f32, 0.96913195), cos_f32(37.45), epsilon);
207 try expectApproxEqAbs(@as(f32, 0.40079966), cosf(89.123), epsilon);221 try expectApproxEqAbs(@as(f32, 0.40079966), cos_f32(89.123), epsilon);
208}222}
209223
210test "cos32.special" {224test "cos32.special" {
...@@ -213,13 +227,13 @@ test "cos32.special" {...@@ -213,13 +227,13 @@ test "cos32.special" {
213227
214test "cos64.normal" {228test "cos64.normal" {
215 const epsilon = math.floatEps(f64);229 const epsilon = math.floatEps(f64);
216 try expectApproxEqAbs(@as(f64, 1.0), cos(0.0), epsilon);230 try expectApproxEqAbs(@as(f64, 1.0), cos_f64(0.0), epsilon);
217 try expectApproxEqAbs(@as(f64, 0.9800665778412416), cos(0.2), epsilon);231 try expectApproxEqAbs(@as(f64, 0.9800665778412416), cos_f64(0.2), epsilon);
218 try expectApproxEqAbs(@as(f64, 0.6276230983360804), cos(0.8923), epsilon);232 try expectApproxEqAbs(@as(f64, 0.6276230983360804), cos_f64(0.8923), epsilon);
219 try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos(1.5), epsilon);233 try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos_f64(1.5), epsilon);
220 try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos(-1.5), epsilon);234 try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos_f64(-1.5), epsilon);
221 try expectApproxEqAbs(@as(f64, 0.9691317730707778), cos(37.45), epsilon);235 try expectApproxEqAbs(@as(f64, 0.9691317730707778), cos_f64(37.45), epsilon);
222 try expectApproxEqAbs(@as(f64, 0.4008006809354791), cos(89.123), epsilon);236 try expectApproxEqAbs(@as(f64, 0.4008006809354791), cos_f64(89.123), epsilon);
223}237}
224238
225test "cos64.special" {239test "cos64.special" {
...@@ -228,13 +242,13 @@ test "cos64.special" {...@@ -228,13 +242,13 @@ test "cos64.special" {
228242
229test "cos80.normal" {243test "cos80.normal" {
230 const epsilon = math.floatEps(f80);244 const epsilon = math.floatEps(f80);
231 try expectApproxEqAbs(@as(f80, 1.0), cosx(0.0), epsilon);245 try expectApproxEqAbs(@as(f80, 1.0), cos_f80(0.0), epsilon);
232 try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), cosx(0.2), epsilon);246 try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), cos_f80(0.2), epsilon);
233 try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), cosx(0.8923), epsilon);247 try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), cos_f80(0.8923), epsilon);
234 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(1.5), epsilon);248 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cos_f80(1.5), epsilon);
235 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(-1.5), epsilon);249 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cos_f80(-1.5), epsilon);
236 try expectApproxEqAbs(@as(f80, 0.9691317730707771246), cosx(37.45), epsilon);250 try expectApproxEqAbs(@as(f80, 0.9691317730707771246), cos_f80(37.45), epsilon);
237 try expectApproxEqAbs(@as(f80, 0.4008006809354834001), cosx(89.123), epsilon);251 try expectApproxEqAbs(@as(f80, 0.4008006809354834001), cos_f80(89.123), epsilon);
238}252}
239253
240test "cos80.special" {254test "cos80.special" {
...@@ -243,13 +257,13 @@ test "cos80.special" {...@@ -243,13 +257,13 @@ test "cos80.special" {
243257
244test "cos128.normal" {258test "cos128.normal" {
245 const epsilon = math.floatEps(f128);259 const epsilon = math.floatEps(f128);
246 try expectApproxEqAbs(@as(f128, 1.0), cosq(0.0), epsilon);260 try expectApproxEqAbs(@as(f128, 1.0), cos_f128(0.0), epsilon);
247 try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), cosq(0.2), epsilon);261 try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), cos_f128(0.2), epsilon);
248 try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), cosq(0.8923), epsilon);262 try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), cos_f128(0.8923), epsilon);
249 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cosq(1.5), epsilon);263 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cos_f128(1.5), epsilon);
250 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cosq(-1.5), epsilon);264 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cos_f128(-1.5), epsilon);
251 try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), cosq(37.45), epsilon);265 try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), cos_f128(37.45), epsilon);
252 try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), cosq(89.123), epsilon);266 try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), cos_f128(89.123), epsilon);
253}267}
254268
255test "cos128.special" {269test "cos128.special" {
lib/compiler_rt/count0bits.zig+2-1
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2const std = @import("std");2const std = @import("std");
3const symbol = @import("../compiler_rt.zig").symbol;3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
45
5comptime {6comptime {
6 symbol(&__clzsi2, "__clzsi2");7 symbol(&__clzsi2, "__clzsi2");
lib/compiler_rt/divc3.zig+78-5
...@@ -7,12 +7,81 @@ const maxInt = std.math.maxInt;...@@ -7,12 +7,81 @@ const maxInt = std.math.maxInt;
7const minInt = std.math.minInt;7const minInt = std.math.minInt;
8const isFinite = std.math.isFinite;8const isFinite = std.math.isFinite;
9const copysign = std.math.copysign;9const copysign = std.math.copysign;
10const Complex = @import("mulc3.zig").Complex;10
11const compiler_rt = @import("../compiler_rt.zig");
12const symbol = compiler_rt.symbol;
13const Complex = compiler_rt.Complex;
14
15comptime {
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
29fn __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}
35pub fn div_cf16(a: Complex(f16), b: Complex(f16)) Complex(f16) {
36 return divc3(f16, a, b);
37}
38
39fn __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}
45pub fn div_cf32(a: Complex(f32), b: Complex(f32)) Complex(f32) {
46 return divc3(f32, a, b);
47}
48
49fn __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}
55pub fn div_cf64(a: Complex(f64), b: Complex(f64)) Complex(f64) {
56 return divc3(f64, a, b);
57}
58
59fn __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}
65pub fn div_cf80(a: Complex(f80), b: Complex(f80)) Complex(f80) {
66 return divc3(f80, a, b);
67}
68
69fn __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}
75pub fn div_cf128(a: Complex(f128), b: Complex(f128)) Complex(f128) {
76 return divc3(f128, a, b);
77}
1178
12/// Implementation based on Annex G of C17 Standard (N2176)79/// Implementation based on Annex G of C17 Standard (N2176)
13pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) {80inline fn divc3(comptime T: type, lhs: Complex(T), rhs: Complex(T)) Complex(T) {
14 var c = c_in;81 const a = lhs.real;
15 var d = d_in;82 const b = lhs.imag;
83 var c = rhs.real;
84 var d = rhs.imag;
1685
17 // logbw used to prevent under/over-flow86 // logbw used to prevent under/over-flow
18 const logbw = ilogb(@max(@abs(c), @abs(d)));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,7 +92,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) {
23 break :b logbw;92 break :b logbw;
24 } else 0;93 } else 0;
25 const denom = c * c + d * d;94 const denom = c * c + d * d;
26 const result = Complex(T){95 const result: Complex(T) = .{
27 .real = scalbn((a * c + b * d) / denom, -ilogbw),96 .real = scalbn((a * c + b * d) / denom, -ilogbw),
28 .imag = scalbn((b * c - a * d) / denom, -ilogbw),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,3 +127,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) {
58127
59 return result;128 return result;
60}129}
130
131test {
132 _ = @import("divc3_test.zig");
133}
lib/compiler_rt/divc3_test.zig+28-51
...@@ -2,76 +2,53 @@ const std = @import("std");...@@ -2,76 +2,53 @@ const std = @import("std");
2const math = std.math;2const math = std.math;
3const expect = std.testing.expect;3const expect = std.testing.expect;
44
5const Complex = @import("./mulc3.zig").Complex;5const Complex = @import("../compiler_rt.zig").Complex;
6const __divhc3 = @import("./divhc3.zig").__divhc3;6
7const __divsc3 = @import("./divsc3.zig").__divsc3;7const impl = @import("divc3.zig");
8const __divdc3 = @import("./divdc3.zig").__divdc3;8const div_cf16 = impl.div_cf16;
9const __divxc3 = @import("./divxc3.zig").__divxc3;9const div_cf32 = impl.div_cf32;
10const __divtc3 = @import("./divtc3.zig").__divtc3;10const div_cf64 = impl.div_cf64;
11const div_cf80 = impl.div_cf80;
12const div_cf128 = impl.div_cf128;
1113
12test "divc3" {14test "divc3" {
13 try testDiv(f16, __divhc3);15 try testDiv(f16, div_cf16);
14 try testDiv(f32, __divsc3);16 try testDiv(f32, div_cf32);
15 try testDiv(f64, __divdc3);17 try testDiv(f64, div_cf64);
16 try testDiv(f80, __divxc3);18 try testDiv(f80, div_cf80);
17 try testDiv(f128, __divtc3);19 try testDiv(f128, div_cf128);
18}20}
1921
20fn testDiv(comptime T: type, comptime f: fn (T, T, T, T) callconv(.c) Complex(T)) !void {22fn testDiv(comptime T: type, comptime f: fn (Complex(T), Complex(T)) Complex(T)) !void {
21 {23 {
22 const a: T = 1.0;24 const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -1.0, .imag = 0.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);
28 try expect(result.real == -1.0);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;29 const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -4.0, .imag = 0.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);
38 try expect(result.real == -0.25);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 // if the first operand is an infinity and the second operand is a finite number, then the34 // 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;35 // resultult of the / operator is an infinity;
44 const a: T = -math.inf(T);36 const result = f(.{ .real = -math.inf(T), .imag = 0.0 }, .{ .real = -4.0, .imag = 1.0 });
45 const b: T = 0.0;37 try expect(math.isPositiveInf(result.real));
46 const c: T = -4.0;38 try expect(math.isPositiveInf(result.imag));
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));
52 }39 }
53 {40 {
54 // if the first operand is a finite number and the second operand is an infinity, then the41 // if the first operand is a finite number and the second operand is an infinity, then the
55 // result of the / operator is a zero;42 // result of the / operator is a zero;
56 const a: T = 17.2;43 const result = f(.{ .real = 17.2, .imag = 0.0 }, .{ .real = -math.inf(T), .imag = 0.0 });
57 const b: T = 0.0;44 try expect(math.isNegativeZero(result.real));
58 const c: T = -math.inf(T);45 try expect(math.isNegativeZero(result.imag));
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);
64 }46 }
65 {47 {
66 // if the first operand is a nonzero finite number or an infinity and the second operand is48 // if the first operand is a nonzero finite number or an infinity and the second operand is
67 // a zero, then the result of the / operator is an infinity49 // a zero, then the result of the / operator is an infinity
68 const a: T = 1.1;50 const result = f(.{ .real = 1.1, .imag = 0.1 }, .{ .real = 0.0, .imag = 0.0 });
69 const b: T = 0.1;51 try expect(math.isPositiveInf(result.real));
70 const c: T = 0.0;52 try expect(math.isPositiveInf(result.imag));
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));
76 }53 }
77}54}
lib/compiler_rt/divdc3.zig deleted-13
...@@ -1,13 +0,0 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const divc3 = @import("./divc3.zig");
3const Complex = @import("./mulc3.zig").Complex;
4
5comptime {
6 if (@import("builtin").zig_backend != .stage2_c) {
7 symbol(&__divdc3, "__divdc3");
8 }
9}
10
11pub 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,15 +17,15 @@ comptime {
17 }17 }
18}18}
1919
20pub fn __divdf3(a: f64, b: f64) callconv(.c) f64 {20fn __divdf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
21 return div(a, b);21 return compiler_rt.f64.toAbi(div_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)));
22}22}
2323
24fn __aeabi_ddiv(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 {24fn __aeabi_ddiv(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
25 return div(a, b);25 return div_f64(a, b);
26}26}
2727
28inline fn div(a: f64, b: f64) f64 {28pub fn div_f64(a: f64, b: f64) f64 {
29 const Z = @Int(.unsigned, 64);29 const Z = @Int(.unsigned, 64);
30 const SignedZ = @Int(.signed, 64);30 const SignedZ = @Int(.signed, 64);
3131
lib/compiler_rt/divdf3_test.zig+2-2
...@@ -6,7 +6,7 @@ const std = @import("std");...@@ -6,7 +6,7 @@ const std = @import("std");
6const math = std.math;6const math = std.math;
7const testing = std.testing;7const testing = std.testing;
88
9const __divdf3 = @import("divdf3.zig").__divdf3;9const div_f64 = @import("divdf3.zig").div_f64;
1010
11const nanRep: u64 = @as(u64, @bitCast(math.nan(f64)));11const nanRep: u64 = @as(u64, @bitCast(math.nan(f64)));
12const infRep: u64 = @as(u64, @bitCast(math.inf(f64)));12const infRep: u64 = @as(u64, @bitCast(math.inf(f64)));
...@@ -30,7 +30,7 @@ fn compareResultD(result: f64, expected: u64) bool {...@@ -30,7 +30,7 @@ fn compareResultD(result: f64, expected: u64) bool {
30}30}
3131
32fn test__divdf3(a: f64, b: f64, expected: u64) !void {32fn test__divdf3(a: f64, b: f64, expected: u64) !void {
33 const x = __divdf3(a, b);33 const x = div_f64(a, b);
34 const ret = compareResultD(x, expected);34 const ret = compareResultD(x, expected);
35 try testing.expect(ret == true);35 try testing.expect(ret == true);
36}36}
lib/compiler_rt/divhc3.zig deleted-14
...@@ -1,14 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const divc3 = @import("./divc3.zig");
4const Complex = @import("./mulc3.zig").Complex;
5
6comptime {
7 if (@import("builtin").zig_backend != .stage2_c) {
8 symbol(&__divhc3, "__divhc3");
9 }
10}
11
12pub 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 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const divsf3 = @import("./divsf3.zig");
3
4comptime {
5 symbol(&__divhf3, "__divhf3");
6}
7
8pub 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,7 +5,7 @@ const std = @import("std");
55
6const compiler_rt = @import("../compiler_rt.zig");6const compiler_rt = @import("../compiler_rt.zig");
7const udivmod = @import("udivmodei4.zig").divmod;7const udivmod = @import("udivmodei4.zig").divmod;
8const symbol = @import("../compiler_rt.zig").symbol;8const symbol = compiler_rt.symbol;
99
10comptime {10comptime {
11 symbol(&__divei4, "__divei4");11 symbol(&__divei4, "__divei4");
lib/compiler_rt/divsc3.zig deleted-13
...@@ -1,13 +0,0 @@
1const divc3 = @import("./divc3.zig");
2const Complex = @import("./mulc3.zig").Complex;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (@import("builtin").zig_backend != .stage2_c) {
7 symbol(&__divsc3, "__divsc3");
8 }
9}
10
11pub 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,6 +9,7 @@ const symbol = compiler_rt.symbol;
9const normalize = compiler_rt.normalize;9const normalize = compiler_rt.normalize;
1010
11comptime {11comptime {
12 symbol(&__divhf3, "__divhf3");
12 if (compiler_rt.want_aeabi) {13 if (compiler_rt.want_aeabi) {
13 symbol(&__aeabi_fdiv, "__aeabi_fdiv");14 symbol(&__aeabi_fdiv, "__aeabi_fdiv");
14 } else {15 } else {
...@@ -16,15 +17,23 @@ comptime {...@@ -16,15 +17,23 @@ comptime {
16 }17 }
17}18}
1819
19pub fn __divsf3(a: f32, b: f32) callconv(.c) f32 {20fn __divhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
20 return div(a, b);21 return compiler_rt.f16.toAbi(div_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)));
22}
23pub fn div_f16(a: f16, b: f16) f16 {
24 // TODO: more efficient implementation
25 return @floatCast(div_f32(a, b));
26}
27
28fn __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}
2231
23fn __aeabi_fdiv(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 {32fn __aeabi_fdiv(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
24 return div(a, b);33 return div_f32(a, b);
25}34}
2635
27inline fn div(a: f32, b: f32) f32 {36pub fn div_f32(a: f32, b: f32) f32 {
28 const Z = @Int(.unsigned, 32);37 const Z = @Int(.unsigned, 32);
2938
30 const significandBits = std.math.floatMantissaBits(f32);39 const significandBits = std.math.floatMantissaBits(f32);
lib/compiler_rt/divsf3_test.zig+2-2
...@@ -6,7 +6,7 @@ const std = @import("std");...@@ -6,7 +6,7 @@ const std = @import("std");
6const math = std.math;6const math = std.math;
7const testing = std.testing;7const testing = std.testing;
88
9const __divsf3 = @import("divsf3.zig").__divsf3;9const div_f32 = @import("divsf3.zig").div_f32;
1010
11const nanRep: u32 = @as(u32, @bitCast(math.nan(f32)));11const nanRep: u32 = @as(u32, @bitCast(math.nan(f32)));
12const infRep: u32 = @as(u32, @bitCast(math.inf(f32)));12const infRep: u32 = @as(u32, @bitCast(math.inf(f32)));
...@@ -30,7 +30,7 @@ fn compareResultF(result: f32, expected: u32) bool {...@@ -30,7 +30,7 @@ fn compareResultF(result: f32, expected: u32) bool {
30}30}
3131
32fn test__divsf3(a: f32, b: f32, expected: u32) !void {32fn test__divsf3(a: f32, b: f32, expected: u32) !void {
33 const x = __divsf3(a, b);33 const x = div_f32(a, b);
34 const ret = compareResultF(x, expected);34 const ret = compareResultF(x, expected);
35 try testing.expect(ret == true);35 try testing.expect(ret == true);
36}36}
lib/compiler_rt/divtc3.zig deleted-16
...@@ -1,16 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const divc3 = @import("./divc3.zig");
3const Complex = @import("./mulc3.zig").Complex;
4const symbol = @import("../compiler_rt.zig").symbol;
5
6comptime {
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
14pub 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,19 +13,20 @@ comptime {
13 symbol(&_Qp_div, "_Qp_div");13 symbol(&_Qp_div, "_Qp_div");
14 } else if (compiler_rt.want_sparc32_abi) {14 } else if (compiler_rt.want_sparc32_abi) {
15 symbol(&__divtf3, "_Q_div");15 symbol(&__divtf3, "_Q_div");
16 } else {
17 symbol(&__divtf3, "__divtf3");
16 }18 }
17 symbol(&__divtf3, "__divtf3");
18}19}
1920
20pub fn __divtf3(a: f128, b: f128) callconv(.c) f128 {21fn __divtf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
21 return div(a, b);22 return compiler_rt.f128.toAbi(div_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)));
22}23}
2324
24fn _Qp_div(c: *f128, a: *const f128, b: *const f128) callconv(.c) void {25fn _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}
2728
28inline fn div(a: f128, b: f128) f128 {29pub fn div_f128(a: f128, b: f128) f128 {
29 const Z = @Int(.unsigned, 128);30 const Z = @Int(.unsigned, 128);
3031
31 const significandBits = std.math.floatMantissaBits(f128);32 const significandBits = std.math.floatMantissaBits(f128);
lib/compiler_rt/divtf3_test.zig+2-2
...@@ -2,7 +2,7 @@ const std = @import("std");...@@ -2,7 +2,7 @@ const std = @import("std");
2const math = std.math;2const math = std.math;
3const testing = std.testing;3const testing = std.testing;
44
5const __divtf3 = @import("divtf3.zig").__divtf3;5const div_f128 = @import("divtf3.zig").div_f128;
66
7fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {7fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {
8 const rep: u128 = @bitCast(result);8 const rep: u128 = @bitCast(result);
...@@ -24,7 +24,7 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {...@@ -24,7 +24,7 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {
24}24}
2525
26fn test__divtf3(a: f128, b: f128, expectedHi: u64, expectedLo: u64) !void {26fn 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 const ret = compareResultLD(x, expectedHi, expectedLo);28 const ret = compareResultLD(x, expectedHi, expectedLo);
29 try testing.expect(ret == true);29 try testing.expect(ret == true);
30}30}
lib/compiler_rt/divxc3.zig deleted-13
...@@ -1,13 +0,0 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const divc3 = @import("./divc3.zig");
3const Complex = @import("./mulc3.zig").Complex;
4
5comptime {
6 if (@import("builtin").zig_backend != .stage2_c) {
7 symbol(&__divxc3, "__divxc3");
8 }
9}
10
11pub 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,7 +11,10 @@ comptime {
11 symbol(&__divxf3, "__divxf3");11 symbol(&__divxf3, "__divxf3");
12}12}
1313
14pub fn __divxf3(a: f80, b: f80) callconv(.c) f80 {14fn __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}
17pub fn div_f80(a: f80, b: f80) f80 {
15 const T = f80;18 const T = f80;
16 const Z = @Int(.unsigned, @bitSizeOf(T));19 const Z = @Int(.unsigned, @bitSizeOf(T));
1720
lib/compiler_rt/divxf3_test.zig+3-3
...@@ -2,7 +2,7 @@ const std = @import("std");...@@ -2,7 +2,7 @@ const std = @import("std");
2const math = std.math;2const math = std.math;
3const testing = std.testing;3const testing = std.testing;
44
5const __divxf3 = @import("divxf3.zig").__divxf3;5const div_f80 = @import("divxf3.zig").div_f80;
66
7const nanRep: u80 = @as(u80, @bitCast(math.nan(f80)));7const nanRep: u80 = @as(u80, @bitCast(math.nan(f80)));
8const infRep: u80 = @as(u80, @bitCast(math.inf(f80)));8const infRep: u80 = @as(u80, @bitCast(math.inf(f80)));
...@@ -19,14 +19,14 @@ fn compareResult(result: f80, expected: u80) bool {...@@ -19,14 +19,14 @@ fn compareResult(result: f80, expected: u80) bool {
19}19}
2020
21fn expect__divxf3_result(a: f80, b: f80, expected: u80) !void {21fn expect__divxf3_result(a: f80, b: f80, expected: u80) !void {
22 const x = __divxf3(a, b);22 const x = div_f80(a, b);
23 const ret = compareResult(x, expected);23 const ret = compareResult(x, expected);
24 try testing.expect(ret == true);24 try testing.expect(ret == true);
25}25}
2626
27fn test__divxf3(a: f80, b: f80) !void {27fn test__divxf3(a: f80, b: f80) !void {
28 const integerBit = 1 << math.floatFractionalBits(f80);28 const integerBit = 1 << math.floatFractionalBits(f80);
29 const x = __divxf3(a, b);29 const x = div_f80(a, b);
3030
31 // Next float (assuming normal, non-zero result)31 // Next float (assuming normal, non-zero result)
32 const x_plus_eps: f80 = @bitCast((@as(u80, @bitCast(x)) + 1) | integerBit);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,7 +14,7 @@ const expect = std.testing.expect;
14const expectEqual = std.testing.expectEqual;14const expectEqual = std.testing.expectEqual;
1515
16const compiler_rt = @import("../compiler_rt.zig");16const compiler_rt = @import("../compiler_rt.zig");
17const symbol = @import("../compiler_rt.zig").symbol;17const symbol = compiler_rt.symbol;
1818
19comptime {19comptime {
20 symbol(&__exph, "__exph");20 symbol(&__exph, "__exph");
...@@ -28,12 +28,18 @@ comptime {...@@ -28,12 +28,18 @@ comptime {
28 symbol(&expl, "expl");28 symbol(&expl, "expl");
29}29}
3030
31pub fn __exph(a: f16) callconv(.c) f16 {31fn __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}
34pub fn exp_f16(x: f16) f16 {
32 // TODO: more efficient implementation35 // TODO: more efficient implementation
33 return @floatCast(expf(a));36 return @floatCast(exp_f32(x));
34}37}
3538
36pub fn expf(x_: f32) callconv(.c) f32 {39fn 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}
42pub fn exp_f32(x_: f32) f32 {
37 const half = [_]f32{ 0.5, -0.5 };43 const half = [_]f32{ 0.5, -0.5 };
38 const ln2hi = 6.9314575195e-1;44 const ln2hi = 6.9314575195e-1;
39 const ln2lo = 1.4286067653e-6;45 const ln2lo = 1.4286067653e-6;
...@@ -108,7 +114,10 @@ pub fn expf(x_: f32) callconv(.c) f32 {...@@ -108,7 +114,10 @@ pub fn expf(x_: f32) callconv(.c) f32 {
108 }114 }
109}115}
110116
111pub fn exp(x_: f64) callconv(.c) f64 {117fn 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}
120pub fn exp_f64(x_: f64) f64 {
112 const half = [_]f64{ 0.5, -0.5 };121 const half = [_]f64{ 0.5, -0.5 };
113 const ln2hi: f64 = 6.93147180369123816490e-01;122 const ln2hi: f64 = 6.93147180369123816490e-01;
114 const ln2lo: f64 = 1.90821492927058770002e-10;123 const ln2lo: f64 = 1.90821492927058770002e-10;
...@@ -189,116 +198,121 @@ pub fn exp(x_: f64) callconv(.c) f64 {...@@ -189,116 +198,121 @@ pub fn exp(x_: f64) callconv(.c) f64 {
189 }198 }
190}199}
191200
192pub fn __expx(a: f80) callconv(.c) f80 {201fn __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}
204pub fn exp_f80(x: f80) f80 {
193 // TODO: more efficient implementation205 // TODO: more efficient implementation
194 return @floatCast(expq(a));206 return @floatCast(exp_f128(x));
195}207}
196208
197const expq = @import("exp_f128.zig").exp;209fn 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}
212pub const exp_f128 = @import("exp_f128.zig").exp;
198213
199pub fn expl(x: c_longdouble) callconv(.c) c_longdouble {214pub fn expl(x: c_longdouble) callconv(.c) c_longdouble {
200 switch (@typeInfo(c_longdouble).float.bits) {215 switch (@typeInfo(c_longdouble).float.bits) {
201 64 => return exp(x),216 64 => return exp_f64(x),
202 80 => return __expx(x),217 80 => return exp_f80(x),
203 128 => return expq(x),218 128 => return exp_f128(x),
204 else => @compileError("unreachable"),219 else => comptime unreachable,
205 }220 }
206}221}
207222
208test "expf() special" {223test "expf() special" {
209 try expectEqual(expf(0.0), 1.0);224 try expectEqual(exp_f32(0.0), 1.0);
210 try expectEqual(expf(-0.0), 1.0);225 try expectEqual(exp_f32(-0.0), 1.0);
211 try expectEqual(expf(1.0), math.e);226 try expectEqual(exp_f32(1.0), math.e);
212 try expectEqual(expf(math.ln2), 2.0);227 try expectEqual(exp_f32(math.ln2), 2.0);
213 try expectEqual(expf(math.inf(f32)), math.inf(f32));228 try expectEqual(exp_f32(math.inf(f32)), math.inf(f32));
214 try expect(math.isPositiveZero(expf(-math.inf(f32))));229 try expect(math.isPositiveZero(exp_f32(-math.inf(f32))));
215 try expect(math.isNan(expf(math.nan(f32))));230 try expect(math.isNan(exp_f32(math.nan(f32))));
216 try expect(math.isNan(expf(math.snan(f32))));231 try expect(math.isNan(exp_f32(math.snan(f32))));
217}232}
218233
219test "expf() sanity" {234test "expf() sanity" {
220 try expectEqual(expf(-0x1.0223a0p+3), 0x1.490320p-12);235 try expectEqual(exp_f32(-0x1.0223a0p+3), 0x1.490320p-12);
221 try expectEqual(expf(0x1.161868p+2), 0x1.34712ap+6);236 try expectEqual(exp_f32(0x1.161868p+2), 0x1.34712ap+6);
222 try expectEqual(expf(-0x1.0c34b4p+3), 0x1.e06b1ap-13);237 try expectEqual(exp_f32(-0x1.0c34b4p+3), 0x1.e06b1ap-13);
223 try expectEqual(expf(-0x1.a206f0p+2), 0x1.7dd484p-10);238 try expectEqual(exp_f32(-0x1.a206f0p+2), 0x1.7dd484p-10);
224 try expectEqual(expf(0x1.288bbcp+3), 0x1.4abc80p+13);239 try expectEqual(exp_f32(0x1.288bbcp+3), 0x1.4abc80p+13);
225 try expectEqual(expf(0x1.52efd0p-1), 0x1.f04a9cp+0);240 try expectEqual(exp_f32(0x1.52efd0p-1), 0x1.f04a9cp+0);
226 try expectEqual(expf(-0x1.a05cc8p-2), 0x1.54f1e0p-1);241 try expectEqual(exp_f32(-0x1.a05cc8p-2), 0x1.54f1e0p-1);
227 try expectEqual(expf(0x1.1f9efap-1), 0x1.c0f628p+0);242 try expectEqual(exp_f32(0x1.1f9efap-1), 0x1.c0f628p+0);
228 try expectEqual(expf(0x1.8c5db0p-1), 0x1.1599b2p+1);243 try expectEqual(exp_f32(0x1.8c5db0p-1), 0x1.1599b2p+1);
229 try expectEqual(expf(-0x1.5b86eap-1), 0x1.03b572p-1);244 try expectEqual(exp_f32(-0x1.5b86eap-1), 0x1.03b572p-1);
230 try expectEqual(expf(-0x1.57f25cp+2), 0x1.2fbea2p-8);245 try expectEqual(exp_f32(-0x1.57f25cp+2), 0x1.2fbea2p-8);
231 try expectEqual(expf(0x1.c7d310p+3), 0x1.76eefp+20);246 try expectEqual(exp_f32(0x1.c7d310p+3), 0x1.76eefp+20);
232 try expectEqual(expf(0x1.19be70p+4), 0x1.52d3dep+25);247 try expectEqual(exp_f32(0x1.19be70p+4), 0x1.52d3dep+25);
233 try expectEqual(expf(-0x1.ab6d70p+3), 0x1.a88adep-20);248 try expectEqual(exp_f32(-0x1.ab6d70p+3), 0x1.a88adep-20);
234 try expectEqual(expf(-0x1.5ac18ep+2), 0x1.22b328p-8);249 try expectEqual(exp_f32(-0x1.5ac18ep+2), 0x1.22b328p-8);
235 try expectEqual(expf(-0x1.925982p-1), 0x1.d2acc0p-2);250 try expectEqual(exp_f32(-0x1.925982p-1), 0x1.d2acc0p-2);
236 try expectEqual(expf(0x1.7221cep+3), 0x1.9c2ceap+16);251 try expectEqual(exp_f32(0x1.7221cep+3), 0x1.9c2ceap+16);
237 try expectEqual(expf(0x1.11a0d4p+4), 0x1.980ee6p+24);252 try expectEqual(exp_f32(0x1.11a0d4p+4), 0x1.980ee6p+24);
238 try expectEqual(expf(-0x1.ae41a2p+1), 0x1.1c28d0p-5);253 try expectEqual(exp_f32(-0x1.ae41a2p+1), 0x1.1c28d0p-5);
239 try expectEqual(expf(-0x1.329154p+4), 0x1.47ef94p-28);254 try expectEqual(exp_f32(-0x1.329154p+4), 0x1.47ef94p-28);
240}255}
241256
242test "expf() boundary" {257test "expf() boundary" {
243 try expectEqual(expf(0x1.62e42ep+6), 0x1.ffff08p+127); // The last value before the result gets infinite258 try expectEqual(exp_f32(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 inf259 try expectEqual(exp_f32(0x1.62e430p+6), math.inf(f32)); // The first value that gives inf
245 try expectEqual(expf(0x1.fffffep+127), math.inf(f32)); // Max input value260 try expectEqual(exp_f32(0x1.fffffep+127), math.inf(f32)); // Max input value
246 try expectEqual(expf(0x1p-149), 1.0); // Min positive input value261 try expectEqual(exp_f32(0x1p-149), 1.0); // Min positive input value
247 try expectEqual(expf(-0x1p-149), 1.0); // Min negative input value262 try expectEqual(exp_f32(-0x1p-149), 1.0); // Min negative input value
248 try expectEqual(expf(0x1p-126), 1.0); // First positive subnormal input263 try expectEqual(exp_f32(0x1p-126), 1.0); // First positive subnormal input
249 try expectEqual(expf(-0x1p-126), 1.0); // First negative subnormal input264 try expectEqual(exp_f32(-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 zero265 try expectEqual(exp_f32(-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 zero266 try expectEqual(exp_f32(-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 subnormal267 try expectEqual(exp_f32(-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 subnormal268 try expectEqual(exp_f32(-0x1.5d58a0p+6), 0x1.ffff98p-127); // The first value for which the result flushes to subnormal
254
255}269}
256270
257test "exp() special" {271test "exp() special" {
258 try expectEqual(exp(0.0), 1.0);272 try expectEqual(exp_f64(0.0), 1.0);
259 try expectEqual(exp(-0.0), 1.0);273 try expectEqual(exp_f64(-0.0), 1.0);
260 // TODO: Accuracy error - off in the last bit in 64-bit, disagreeing with GCC274 // TODO: Accuracy error - off in the last bit in 64-bit, disagreeing with GCC
261 // try expectEqual(exp(1.0), math.e);275 // try expectEqual(exp(1.0), math.e);
262 try expectEqual(exp(math.ln2), 2.0);276 try expectEqual(exp_f64(math.ln2), 2.0);
263 try expectEqual(exp(math.inf(f64)), math.inf(f64));277 try expectEqual(exp_f64(math.inf(f64)), math.inf(f64));
264 try expect(math.isPositiveZero(exp(-math.inf(f64))));278 try expect(math.isPositiveZero(exp_f64(-math.inf(f64))));
265 try expect(math.isNan(exp(math.nan(f64))));279 try expect(math.isNan(exp_f64(math.nan(f64))));
266 try expect(math.isNan(exp(math.snan(f64))));280 try expect(math.isNan(exp_f64(math.snan(f64))));
267}281}
268282
269test "exp() sanity" {283test "exp() sanity" {
270 try expectEqual(exp(-0x1.02239f3c6a8f1p+3), 0x1.490327ea61235p-12);284 try expectEqual(exp_f64(-0x1.02239f3c6a8f1p+3), 0x1.490327ea61235p-12);
271 try expectEqual(exp(0x1.161868e18bc67p+2), 0x1.34712ed238c04p+6);285 try expectEqual(exp_f64(0x1.161868e18bc67p+2), 0x1.34712ed238c04p+6);
272 try expectEqual(exp(-0x1.0c34b3e01e6e7p+3), 0x1.e06b1b6c18e64p-13);286 try expectEqual(exp_f64(-0x1.0c34b3e01e6e7p+3), 0x1.e06b1b6c18e64p-13);
273 try expectEqual(exp(-0x1.a206f0a19dcc4p+2), 0x1.7dd47f810e68cp-10);287 try expectEqual(exp_f64(-0x1.a206f0a19dcc4p+2), 0x1.7dd47f810e68cp-10);
274 try expectEqual(exp(0x1.288bbb0d6a1e6p+3), 0x1.4abc77496e07ep+13);288 try expectEqual(exp_f64(0x1.288bbb0d6a1e6p+3), 0x1.4abc77496e07ep+13);
275 try expectEqual(exp(0x1.52efd0cd80497p-1), 0x1.f04a9c1080500p+0);289 try expectEqual(exp_f64(0x1.52efd0cd80497p-1), 0x1.f04a9c1080500p+0);
276 try expectEqual(exp(-0x1.a05cc754481d1p-2), 0x1.54f1e0fd3ea0dp-1);290 try expectEqual(exp_f64(-0x1.a05cc754481d1p-2), 0x1.54f1e0fd3ea0dp-1);
277 try expectEqual(exp(0x1.1f9ef934745cbp-1), 0x1.c0f6266a6a547p+0);291 try expectEqual(exp_f64(0x1.1f9ef934745cbp-1), 0x1.c0f6266a6a547p+0);
278 try expectEqual(exp(0x1.8c5db097f7442p-1), 0x1.1599b1d4a25fbp+1);292 try expectEqual(exp_f64(0x1.8c5db097f7442p-1), 0x1.1599b1d4a25fbp+1);
279 try expectEqual(exp(-0x1.5b86ea8118a0ep-1), 0x1.03b5728a00229p-1);293 try expectEqual(exp_f64(-0x1.5b86ea8118a0ep-1), 0x1.03b5728a00229p-1);
280 try expectEqual(exp(-0x1.57f25b2b5006dp+2), 0x1.2fbea6a01cab9p-8);294 try expectEqual(exp_f64(-0x1.57f25b2b5006dp+2), 0x1.2fbea6a01cab9p-8);
281 try expectEqual(exp(0x1.c7d30fb825911p+3), 0x1.76eeed45a0634p+20);295 try expectEqual(exp_f64(0x1.c7d30fb825911p+3), 0x1.76eeed45a0634p+20);
282 try expectEqual(exp(0x1.19be709de7505p+4), 0x1.52d3eb7be6844p+25);296 try expectEqual(exp_f64(0x1.19be709de7505p+4), 0x1.52d3eb7be6844p+25);
283 try expectEqual(exp(-0x1.ab6d6fba96889p+3), 0x1.a88ae12f985d6p-20);297 try expectEqual(exp_f64(-0x1.ab6d6fba96889p+3), 0x1.a88ae12f985d6p-20);
284 try expectEqual(exp(-0x1.5ac18e27084ddp+2), 0x1.22b327da9cca6p-8);298 try expectEqual(exp_f64(-0x1.5ac18e27084ddp+2), 0x1.22b327da9cca6p-8);
285 try expectEqual(exp(-0x1.925981b093c41p-1), 0x1.d2acc046b55f7p-2);299 try expectEqual(exp_f64(-0x1.925981b093c41p-1), 0x1.d2acc046b55f7p-2);
286 try expectEqual(exp(0x1.7221cd18455f5p+3), 0x1.9c2cde8699cfbp+16);300 try expectEqual(exp_f64(0x1.7221cd18455f5p+3), 0x1.9c2cde8699cfbp+16);
287 try expectEqual(exp(0x1.11a0d4a51b239p+4), 0x1.980ef612ff182p+24);301 try expectEqual(exp_f64(0x1.11a0d4a51b239p+4), 0x1.980ef612ff182p+24);
288 try expectEqual(exp(-0x1.ae41a1079de4dp+1), 0x1.1c28d16bb3222p-5);302 try expectEqual(exp_f64(-0x1.ae41a1079de4dp+1), 0x1.1c28d16bb3222p-5);
289 try expectEqual(exp(-0x1.329153103b871p+4), 0x1.47efa6ddd0d22p-28);303 try expectEqual(exp_f64(-0x1.329153103b871p+4), 0x1.47efa6ddd0d22p-28);
290}304}
291305
292test "exp() boundary" {306test "exp() boundary" {
293 try expectEqual(exp(0x1.62e42fefa39efp+9), 0x1.fffffffffff2ap+1023); // The last value before the result gets infinite307 try expectEqual(exp_f64(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 inf308 try expectEqual(exp_f64(0x1.62e42fefa39f0p+9), math.inf(f64)); // The first value that gives inf
295 try expectEqual(exp(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value309 try expectEqual(exp_f64(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value
296 try expectEqual(exp(0x1p-1074), 1.0); // Min positive input value310 try expectEqual(exp_f64(0x1p-1074), 1.0); // Min positive input value
297 try expectEqual(exp(-0x1p-1074), 1.0); // Min negative input value311 try expectEqual(exp_f64(-0x1p-1074), 1.0); // Min negative input value
298 try expectEqual(exp(0x1p-1022), 1.0); // First positive subnormal input312 try expectEqual(exp_f64(0x1p-1022), 1.0); // First positive subnormal input
299 try expectEqual(exp(-0x1p-1022), 1.0); // First negative subnormal input313 try expectEqual(exp_f64(-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 zero314 try expectEqual(exp_f64(-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 zero315 try expectEqual(exp_f64(-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 subnormal316 try expectEqual(exp_f64(-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 subnormal317 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,12 +26,18 @@ comptime {
26 symbol(&exp2l, "exp2l");26 symbol(&exp2l, "exp2l");
27}27}
2828
29pub fn __exp2h(x: f16) callconv(.c) f16 {29fn __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}
32pub fn exp2_f16(x: f16) f16 {
30 // TODO: more efficient implementation33 // TODO: more efficient implementation
31 return @floatCast(exp2f(x));34 return @floatCast(exp2_f32(x));
32}35}
3336
34pub fn exp2f(x: f32) callconv(.c) f32 {37fn 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}
40pub fn exp2_f32(x: f32) f32 {
35 const tblsiz: u32 = @intCast(exp2ft.len);41 const tblsiz: u32 = @intCast(exp2ft.len);
36 const redux: f32 = 0x1.8p23 / @as(f32, @floatFromInt(tblsiz));42 const redux: f32 = 0x1.8p23 / @as(f32, @floatFromInt(tblsiz));
37 const P1: f32 = 0x1.62e430p-1;43 const P1: f32 = 0x1.62e430p-1;
...@@ -88,7 +94,10 @@ pub fn exp2f(x: f32) callconv(.c) f32 {...@@ -88,7 +94,10 @@ pub fn exp2f(x: f32) callconv(.c) f32 {
88 return @floatCast(r * uk);94 return @floatCast(r * uk);
89}95}
9096
91pub fn exp2(x: f64) callconv(.c) f64 {97fn 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}
100pub fn exp2_f64(x: f64) f64 {
92 const tblsiz: u32 = @intCast(exp2dt.len / 2);101 const tblsiz: u32 = @intCast(exp2dt.len / 2);
93 const redux: f64 = 0x1.8p52 / @as(f64, @floatFromInt(tblsiz));102 const redux: f64 = 0x1.8p52 / @as(f64, @floatFromInt(tblsiz));
94 const P1: f64 = 0x1.62e42fefa39efp-1;103 const P1: f64 = 0x1.62e42fefa39efp-1;
...@@ -156,19 +165,25 @@ pub fn exp2(x: f64) callconv(.c) f64 {...@@ -156,19 +165,25 @@ pub fn exp2(x: f64) callconv(.c) f64 {
156 return math.scalbn(r, ik);165 return math.scalbn(r, ik);
157}166}
158167
159pub fn __exp2x(x: f80) callconv(.c) f80 {168fn __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}
171pub fn exp2_f80(x: f80) f80 {
160 // TODO: more efficient implementation172 // TODO: more efficient implementation
161 return @floatCast(exp2q(x));173 return @floatCast(exp2_f128(x));
162}174}
163175
164pub const exp2q = @import("exp_f128.zig").exp2;176fn 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}
179pub const exp2_f128 = @import("exp_f128.zig").exp2;
165180
166pub fn exp2l(x: c_longdouble) callconv(.c) c_longdouble {181pub fn exp2l(x: c_longdouble) callconv(.c) c_longdouble {
167 switch (@typeInfo(c_longdouble).float.bits) {182 switch (@typeInfo(c_longdouble).float.bits) {
168 64 => return exp2(x),183 64 => return exp2_f64(x),
169 80 => return __exp2x(x),184 80 => return exp2_f80(x),
170 128 => return exp2q(x),185 128 => return exp2_f128(x),
171 else => @compileError("unreachable"),186 else => comptime unreachable,
172 }187 }
173}188}
174189
...@@ -452,77 +467,77 @@ const exp2dt = [_]f64{...@@ -452,77 +467,77 @@ const exp2dt = [_]f64{
452};467};
453468
454test "exp2f() special" {469test "exp2f() special" {
455 try expectEqual(exp2f(0.0), 1.0);470 try expectEqual(exp2_f32(0.0), 1.0);
456 try expectEqual(exp2f(-0.0), 1.0);471 try expectEqual(exp2_f32(-0.0), 1.0);
457 try expectEqual(exp2f(1.0), 2.0);472 try expectEqual(exp2_f32(1.0), 2.0);
458 try expectEqual(exp2f(-1.0), 0.5);473 try expectEqual(exp2_f32(-1.0), 0.5);
459 try expectEqual(exp2f(math.inf(f32)), math.inf(f32));474 try expectEqual(exp2_f32(math.inf(f32)), math.inf(f32));
460 try expect(math.isPositiveZero(exp2f(-math.inf(f32))));475 try expect(math.isPositiveZero(exp2_f32(-math.inf(f32))));
461 try expect(math.isNan(exp2f(math.nan(f32))));476 try expect(math.isNan(exp2_f32(math.nan(f32))));
462 try expect(math.isNan(exp2f(math.snan(f32))));477 try expect(math.isNan(exp2_f32(math.snan(f32))));
463}478}
464479
465test "exp2f() sanity" {480test "exp2f() sanity" {
466 try expectEqual(exp2f(-0x1.0223a0p+3), 0x1.e8d134p-9);481 try expectEqual(exp2_f32(-0x1.0223a0p+3), 0x1.e8d134p-9);
467 try expectEqual(exp2f(0x1.161868p+2), 0x1.453672p+4);482 try expectEqual(exp2_f32(0x1.161868p+2), 0x1.453672p+4);
468 try expectEqual(exp2f(-0x1.0c34b4p+3), 0x1.890ca0p-9);483 try expectEqual(exp2_f32(-0x1.0c34b4p+3), 0x1.890ca0p-9);
469 try expectEqual(exp2f(-0x1.a206f0p+2), 0x1.622d4ep-7);484 try expectEqual(exp2_f32(-0x1.a206f0p+2), 0x1.622d4ep-7);
470 try expectEqual(exp2f(0x1.288bbcp+3), 0x1.340ecep+9);485 try expectEqual(exp2_f32(0x1.288bbcp+3), 0x1.340ecep+9);
471 try expectEqual(exp2f(0x1.52efd0p-1), 0x1.950eeep+0);486 try expectEqual(exp2_f32(0x1.52efd0p-1), 0x1.950eeep+0);
472 try expectEqual(exp2f(-0x1.a05cc8p-2), 0x1.824056p-1);487 try expectEqual(exp2_f32(-0x1.a05cc8p-2), 0x1.824056p-1);
473 try expectEqual(exp2f(0x1.1f9efap-1), 0x1.79dfa2p+0);488 try expectEqual(exp2_f32(0x1.1f9efap-1), 0x1.79dfa2p+0);
474 try expectEqual(exp2f(0x1.8c5db0p-1), 0x1.b5ceacp+0);489 try expectEqual(exp2_f32(0x1.8c5db0p-1), 0x1.b5ceacp+0);
475 try expectEqual(exp2f(-0x1.5b86eap-1), 0x1.3fd8bap-1);490 try expectEqual(exp2_f32(-0x1.5b86eap-1), 0x1.3fd8bap-1);
476}491}
477492
478test "exp2f() boundary" {493test "exp2f() boundary" {
479 try expectEqual(exp2f(0x1.fffffep+6), 0x1.ffff4ep+127); // The last value before the result gets infinite494 try expectEqual(exp2_f32(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 result495 try expectEqual(exp2_f32(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 zero496 try expectEqual(exp2_f32(-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 zero497 try expectEqual(exp2_f32(-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 subnormal498 try expectEqual(exp2_f32(-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 subnormal499 try expectEqual(exp2_f32(-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 value500 try expectEqual(exp2_f32(0x1.fffffep+127), math.inf(f32)); // Max input value
486 try expectEqual(exp2f(0x1p-149), 1); // Min positive input value501 try expectEqual(exp2_f32(0x1p-149), 1); // Min positive input value
487 try expectEqual(exp2f(-0x1p-149), 1); // Min negative input value502 try expectEqual(exp2_f32(-0x1p-149), 1); // Min negative input value
488 try expectEqual(exp2f(0x1p-126), 1); // First positive subnormal input503 try expectEqual(exp2_f32(0x1p-126), 1); // First positive subnormal input
489 try expectEqual(exp2f(-0x1p-126), 1); // First negative subnormal input504 try expectEqual(exp2_f32(-0x1p-126), 1); // First negative subnormal input
490}505}
491506
492test "exp2() special" {507test "exp2() special" {
493 try expectEqual(exp2(0.0), 1.0);508 try expectEqual(exp2_f64(0.0), 1.0);
494 try expectEqual(exp2(-0.0), 1.0);509 try expectEqual(exp2_f64(-0.0), 1.0);
495 try expectEqual(exp2(1.0), 2.0);510 try expectEqual(exp2_f64(1.0), 2.0);
496 try expectEqual(exp2(-1.0), 0.5);511 try expectEqual(exp2_f64(-1.0), 0.5);
497 try expectEqual(exp2(math.inf(f64)), math.inf(f64));512 try expectEqual(exp2_f64(math.inf(f64)), math.inf(f64));
498 try expect(math.isPositiveZero(exp2(-math.inf(f64))));513 try expect(math.isPositiveZero(exp2_f64(-math.inf(f64))));
499 try expect(math.isNan(exp2(math.nan(f64))));514 try expect(math.isNan(exp2_f64(math.nan(f64))));
500 try expect(math.isNan(exp2(math.snan(f64))));515 try expect(math.isNan(exp2_f64(math.snan(f64))));
501}516}
502517
503test "exp2() sanity" {518test "exp2() sanity" {
504 try expectEqual(exp2(-0x1.02239f3c6a8f1p+3), 0x1.e8d13c396f452p-9);519 try expectEqual(exp2_f64(-0x1.02239f3c6a8f1p+3), 0x1.e8d13c396f452p-9);
505 try expectEqual(exp2(0x1.161868e18bc67p+2), 0x1.4536746bb6f12p+4);520 try expectEqual(exp2_f64(0x1.161868e18bc67p+2), 0x1.4536746bb6f12p+4);
506 try expectEqual(exp2(-0x1.0c34b3e01e6e7p+3), 0x1.890ca0c00b9a2p-9);521 try expectEqual(exp2_f64(-0x1.0c34b3e01e6e7p+3), 0x1.890ca0c00b9a2p-9);
507 try expectEqual(exp2(-0x1.a206f0a19dcc4p+2), 0x1.622d4b0ebc6c1p-7);522 try expectEqual(exp2_f64(-0x1.a206f0a19dcc4p+2), 0x1.622d4b0ebc6c1p-7);
508 try expectEqual(exp2(0x1.288bbb0d6a1e6p+3), 0x1.340ec7f3e607ep+9);523 try expectEqual(exp2_f64(0x1.288bbb0d6a1e6p+3), 0x1.340ec7f3e607ep+9);
509 try expectEqual(exp2(0x1.52efd0cd80497p-1), 0x1.950eef4bc5451p+0);524 try expectEqual(exp2_f64(0x1.52efd0cd80497p-1), 0x1.950eef4bc5451p+0);
510 try expectEqual(exp2(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1);525 try expectEqual(exp2_f64(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1);
511 try expectEqual(exp2(0x1.1f9ef934745cbp-1), 0x1.79dfa14ab121ep+0);526 try expectEqual(exp2_f64(0x1.1f9ef934745cbp-1), 0x1.79dfa14ab121ep+0);
512 try expectEqual(exp2(0x1.8c5db097f7442p-1), 0x1.b5cead2247372p+0);527 try expectEqual(exp2_f64(0x1.8c5db097f7442p-1), 0x1.b5cead2247372p+0);
513 try expectEqual(exp2(-0x1.5b86ea8118a0ep-1), 0x1.3fd8ba33216b9p-1);528 try expectEqual(exp2_f64(-0x1.5b86ea8118a0ep-1), 0x1.3fd8ba33216b9p-1);
514}529}
515530
516test "exp2() boundary" {531test "exp2() boundary" {
517 try expectEqual(exp2(0x1.fffffffffffffp+9), 0x1.ffffffffffd3ap+1023); // The last value before the result gets infinite532 try expectEqual(exp2_f64(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 result533 try expectEqual(exp2_f64(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 zero534 try expectEqual(exp2_f64(-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 zero535 try expectEqual(exp2_f64(-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 subnormal536 try expectEqual(exp2_f64(-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 subnormal537 try expectEqual(exp2_f64(-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 value538 try expectEqual(exp2_f64(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value
524 try expectEqual(exp2(0x1p-1074), 1); // Min positive input value539 try expectEqual(exp2_f64(0x1p-1074), 1); // Min positive input value
525 try expectEqual(exp2(-0x1p-1074), 1); // Min negative input value540 try expectEqual(exp2_f64(-0x1p-1074), 1); // Min negative input value
526 try expectEqual(exp2(0x1p-1022), 1); // First positive subnormal input541 try expectEqual(exp2_f64(0x1p-1022), 1); // First positive subnormal input
527 try expectEqual(exp2(-0x1p-1022), 1); // First negative subnormal input542 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,7 +26,7 @@ const exp_f128 = @This();
26const std = @import("std");26const std = @import("std");
27const math = std.math;27const math = std.math;
2828
29pub fn exp(x: f128) callconv(.c) f128 {29pub fn exp(x: f128) f128 {
30 if (!math.isFinite(x)) {30 if (!math.isFinite(x)) {
31 if (math.isNan(x)) {31 if (math.isNan(x)) {
32 if (math.isSignalNan(x)) math.raiseInvalid();32 if (math.isSignalNan(x)) math.raiseInvalid();
...@@ -91,7 +91,7 @@ fn expPoly(r_hi: f128, r_lo: f128) f128 {...@@ -91,7 +91,7 @@ fn expPoly(r_hi: f128, r_lo: f128) f128 {
91}91}
9292
93/// Computes 2^x93/// Computes 2^x
94pub fn exp2(x: f128) callconv(.c) f128 {94pub fn exp2(x: f128) f128 {
95 if (!math.isFinite(x)) {95 if (!math.isFinite(x)) {
96 if (math.isNan(x)) {96 if (math.isNan(x)) {
97 if (math.isSignalNan(x)) math.raiseInvalid();97 if (math.isSignalNan(x)) math.raiseInvalid();
lib/compiler_rt/extenddftf2.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const extendf = @import("./extendf.zig").extendf;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
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
16pub fn __extenddftf2(a: f64) callconv(.c) f128 {
17 return extendf(f128, f64, @as(u64, @bitCast(a)));
18}
19
20fn _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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const extend_f80 = @import("./extendf.zig").extend_f80;
4
5comptime {
6 symbol(&__extenddfxf2, "__extenddfxf2");
7}
8
9pub 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,10 +1,175 @@
1const std = @import("std");1const std = @import("std");
22
3pub inline fn extendf(3const compiler_rt = @import("../compiler_rt.zig");
4 comptime dst_t: type,4const symbol = compiler_rt.symbol;
5 comptime src_t: type,5
6 a: @Int(.unsigned, @typeInfo(src_t).float.bits),6comptime {
7) dst_t {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
59fn __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}
62fn __aeabi_h2f(a: u16) callconv(.{ .arm_aapcs = .{} }) u32 {
63 return @bitCast(f32_floatCast_f16(@bitCast(a)));
64}
65pub fn f32_floatCast_f16(a: f16) f32 {
66 return extendf(f32, f16, a);
67}
68
69fn __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}
72pub fn f64_floatCast_f16(a: f16) f64 {
73 return extendf(f64, f16, a);
74}
75
76fn __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}
79pub fn f80_floatCast_f16(a: f16) f80 {
80 return extend_f80(f16, a);
81}
82
83fn __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}
86pub fn f128_floatCast_f16(a: f16) f128 {
87 return extendf(f128, f16, a);
88}
89
90fn __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}
93fn __aeabi_f2d(a: f32) callconv(.{ .arm_aapcs = .{} }) f64 {
94 return f64_floatCast_f32(a);
95}
96pub fn f64_floatCast_f32(a: f32) f64 {
97 return extendf(f64, f32, a);
98}
99
100fn __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}
103pub fn f80_floatCast_f32(a: f32) f80 {
104 return extend_f80(f32, a);
105}
106
107pub 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}
110fn _Qp_stoq(c: *f128, a: f32) callconv(.c) void {
111 c.* = f128_floatCast_f32(a);
112}
113pub fn f128_floatCast_f32(a: f32) f128 {
114 return extendf(f128, f32, a);
115}
116
117fn __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}
120pub fn f80_floatCast_f64(a: f64) f80 {
121 return extend_f80(f64, a);
122}
123
124fn __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}
127fn _Qp_dtoq(c: *f128, a: f64) callconv(.c) void {
128 c.* = f128_floatCast_f64(a);
129}
130pub fn f128_floatCast_f64(a: f64) f128 {
131 return extendf(f128, f64, a);
132}
133
134fn __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}
137pub 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
172inline fn extendf(comptime dst_t: type, comptime src_t: type, f: src_t) dst_t {
8 const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits);173 const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits);
9 const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits);174 const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits);
10 const srcSigBits = std.math.floatMantissaBits(src_t);175 const srcSigBits = std.math.floatMantissaBits(src_t);
...@@ -31,6 +196,7 @@ pub inline fn extendf(...@@ -31,6 +196,7 @@ pub inline fn extendf(
31196
32 const dstMinNormal: dst_rep_t = @as(dst_rep_t, 1) << dstSigBits;197 const dstMinNormal: dst_rep_t = @as(dst_rep_t, 1) << dstSigBits;
33198
199 const a: src_rep_t = @bitCast(f);
34 // Break a into a sign and representation of the absolute value200 // Break a into a sign and representation of the absolute value
35 const aRep: src_rep_t = @bitCast(a);201 const aRep: src_rep_t = @bitCast(a);
36 const aAbs: src_rep_t = aRep & srcAbsMask;202 const aAbs: src_rep_t = aRep & srcAbsMask;
...@@ -66,11 +232,11 @@ pub inline fn extendf(...@@ -66,11 +232,11 @@ pub inline fn extendf(
66 }232 }
67233
68 // Apply the signbit to (dst_t)abs(a).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 return @bitCast(result);236 return @bitCast(result);
71}237}
72238
73pub inline fn extend_f80(comptime src_t: type, a: @Int(.unsigned, @typeInfo(src_t).float.bits)) f80 {239inline fn extend_f80(comptime src_t: type, f: src_t) f80 {
74 const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits);240 const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits);
75 const src_sig_bits = std.math.floatMantissaBits(src_t);241 const src_sig_bits = std.math.floatMantissaBits(src_t);
76 const dst_int_bit = 0x8000000000000000;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,6 +258,7 @@ pub inline fn extend_f80(comptime src_t: type, a: @Int(.unsigned, @typeInfo(src_
92258
93 var dst: std.math.F80 = undefined;259 var dst: std.math.F80 = undefined;
94260
261 const a: src_rep_t = @bitCast(f);
95 // Break a into a sign and representation of the absolute value262 // Break a into a sign and representation of the absolute value
96 const a_abs = a & src_abs_mask;263 const a_abs = a & src_abs_mask;
97 const sign: u16 = if (a & src_sign_mask != 0) 0x8000 else 0;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,31 +1,37 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2
3const std = @import("std");2const std = @import("std");
4const math = std.math;3const testing = std.testing;
4
5const impl = @import("extendf.zig");
6
7const f32_floatCast_f16 = impl.f32_floatCast_f16;
8const f64_floatCast_f16 = impl.f64_floatCast_f16;
9const f80_floatCast_f16 = impl.f80_floatCast_f16;
10const f128_floatCast_f16 = impl.f128_floatCast_f16;
11
12const f64_floatCast_f32 = impl.f64_floatCast_f32;
13const f80_floatCast_f32 = impl.f80_floatCast_f32;
14const f128_floatCast_f32 = impl.f128_floatCast_f32;
515
6const __extendhfsf2 = @import("extendhfsf2.zig").__extendhfsf2;16const f80_floatCast_f64 = impl.f80_floatCast_f64;
7const __extendhftf2 = @import("extendhftf2.zig").__extendhftf2;17const f128_floatCast_f64 = impl.f128_floatCast_f64;
8const __extendsftf2 = @import("extendsftf2.zig").__extendsftf2;
9const __extenddftf2 = @import("extenddftf2.zig").__extenddftf2;
10const __extenddfxf2 = @import("extenddfxf2.zig").__extenddfxf2;
11const F16T = @import("../compiler_rt.zig").F16T;
1218
13fn test__extenddfxf2(a: f64, expected: u80) !void {19const f128_floatCast_f80 = impl.f128_floatCast_f80;
14 const x = __extenddfxf2(a);20
21fn test_f80_floatCast_f64(a: f64, expected: u80) !void {
22 const x = f80_floatCast_f64(a);
1523
16 const rep: u80 = @bitCast(x);24 const rep: u80 = @bitCast(x);
17 if (rep == expected)25 if (rep == expected)
18 return;26 return;
19
20 // test other possible NaN representation(signal NaN)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 return;29 return;
2330 return error.TestFailure;
24 @panic("__extenddfxf2 test failure");
25}31}
2632
27fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void {33fn test_f128_floatCast_f64(a: f64, expected_hi: u64, expected_lo: u64) !void {
28 const x = __extenddftf2(a);34 const x = f128_floatCast_f64(a);
2935
30 const rep: u128 = @bitCast(x);36 const rep: u128 = @bitCast(x);
31 const hi: u64 = @intCast(rep >> 64);37 const hi: u64 = @intCast(rep >> 64);
...@@ -33,7 +39,6 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void {...@@ -33,7 +39,6 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void {
3339
34 if (hi == expected_hi and lo == expected_lo)40 if (hi == expected_hi and lo == expected_lo)
35 return;41 return;
36
37 // test other possible NaN representation(signal NaN)42 // test other possible NaN representation(signal NaN)
38 if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) {43 if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) {
39 if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and44 if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and
...@@ -42,12 +47,11 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void {...@@ -42,12 +47,11 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void {
42 return;47 return;
43 }48 }
44 }49 }
4550 return error.TestFailure;
46 @panic("__extenddftf2 test failure");
47}51}
4852
49fn test__extendhfsf2(a: u16, expected: u32) !void {53fn test_f32_floatCast_f16(a: u16, expected: u32) !void {
50 const x = __extendhfsf2(@as(F16T(f32), @bitCast(a)));54 const x = f32_floatCast_f16(@bitCast(a));
51 const rep: u32 = @bitCast(x);55 const rep: u32 = @bitCast(x);
5256
53 if (rep == expected) {57 if (rep == expected) {
...@@ -58,12 +62,11 @@ fn test__extendhfsf2(a: u16, expected: u32) !void {...@@ -58,12 +62,11 @@ fn test__extendhfsf2(a: u16, expected: u32) !void {
58 return;62 return;
59 }63 }
60 }64 }
61
62 return error.TestFailure;65 return error.TestFailure;
63}66}
6467
65fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void {68fn test_f128_floatCast_f32(a: f32, expected_hi: u64, expected_lo: u64) !void {
66 const x = __extendsftf2(a);69 const x = f128_floatCast_f32(a);
6770
68 const rep: u128 = @bitCast(x);71 const rep: u128 = @bitCast(x);
69 const hi: u64 = @intCast(rep >> 64);72 const hi: u64 = @intCast(rep >> 64);
...@@ -71,7 +74,6 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void {...@@ -71,7 +74,6 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void {
7174
72 if (hi == expected_hi and lo == expected_lo)75 if (hi == expected_hi and lo == expected_lo)
73 return;76 return;
74
75 // test other possible NaN representation(signal NaN)77 // test other possible NaN representation(signal NaN)
76 if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) {78 if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) {
77 if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and79 if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and
...@@ -80,111 +82,108 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void {...@@ -80,111 +82,108 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void {
80 return;82 return;
81 }83 }
82 }84 }
83
84 return error.TestFailure;85 return error.TestFailure;
85}86}
8687
87test "extenddfxf2" {88test f80_floatCast_f64 {
88 // qNaN89 // qNaN
89 try test__extenddfxf2(makeQNaN64(), 0x7fffc000000000000000);90 try test_f80_floatCast_f64(makeQNaN64(), 0x7fffc000000000000000);
9091
91 // NaN92 // NaN
92 try test__extenddfxf2(makeNaN64(0x7100000000000), 0x7fffe080000000000000);93 try test_f80_floatCast_f64(makeNaN64(0x7100000000000), 0x7fffe080000000000000);
93 // This is bad?94 // This is bad?
9495
95 // inf96 // inf
96 try test__extenddfxf2(makeInf64(), 0x7fff8000000000000000);97 try test_f80_floatCast_f64(makeInf64(), 0x7fff8000000000000000);
9798
98 // zero99 // zero
99 try test__extenddfxf2(0.0, 0x0);100 try test_f80_floatCast_f64(0.0, 0x0);
100101
101 try test__extenddfxf2(0x0.a3456789abcdefp+6, 0x4004a3456789abcdf000);102 try test_f80_floatCast_f64(0x0.a3456789abcdefp+6, 0x4004a3456789abcdf000);
102103
103 try test__extenddfxf2(0x0.edcba987654321fp-8, 0x3ff6edcba98765432000);104 try test_f80_floatCast_f64(0x0.edcba987654321fp-8, 0x3ff6edcba98765432000);
104105
105 try test__extenddfxf2(0x0.a3456789abcdefp+46, 0x402ca3456789abcdf000);106 try test_f80_floatCast_f64(0x0.a3456789abcdefp+46, 0x402ca3456789abcdf000);
106107
107 try test__extenddfxf2(0x0.edcba987654321fp-44, 0x3fd2edcba98765432000);108 try test_f80_floatCast_f64(0x0.edcba987654321fp-44, 0x3fd2edcba98765432000);
108109
109 // subnormal110 // subnormal
110 try test__extenddfxf2(0x1.8000000000001p-1022, 0x3c01c000000000000800);111 try test_f80_floatCast_f64(0x1.8000000000001p-1022, 0x3c01c000000000000800);
111 try test__extenddfxf2(0x1.8000000000002p-1023, 0x3c00c000000000001000);112 try test_f80_floatCast_f64(0x1.8000000000002p-1023, 0x3c00c000000000001000);
112}113}
113114
114test "extenddftf2" {115test f128_floatCast_f64 {
115 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
116
117 // qNaN116 // qNaN
118 try test__extenddftf2(makeQNaN64(), 0x7fff800000000000, 0x0);117 try test_f128_floatCast_f64(makeQNaN64(), 0x7fff800000000000, 0x0);
119118
120 // NaN119 // NaN
121 try test__extenddftf2(makeNaN64(0x7100000000000), 0x7fff710000000000, 0x0);120 try test_f128_floatCast_f64(makeNaN64(0x7100000000000), 0x7fff710000000000, 0x0);
122121
123 // inf122 // inf
124 try test__extenddftf2(makeInf64(), 0x7fff000000000000, 0x0);123 try test_f128_floatCast_f64(makeInf64(), 0x7fff000000000000, 0x0);
125124
126 // zero125 // zero
127 try test__extenddftf2(0.0, 0x0, 0x0);126 try test_f128_floatCast_f64(0.0, 0x0, 0x0);
128127
129 try test__extenddftf2(0x1.23456789abcdefp+5, 0x400423456789abcd, 0xf000000000000000);128 try test_f128_floatCast_f64(0x1.23456789abcdefp+5, 0x400423456789abcd, 0xf000000000000000);
130129
131 try test__extenddftf2(0x1.edcba987654321fp-9, 0x3ff6edcba9876543, 0x2000000000000000);130 try test_f128_floatCast_f64(0x1.edcba987654321fp-9, 0x3ff6edcba9876543, 0x2000000000000000);
132131
133 try test__extenddftf2(0x1.23456789abcdefp+45, 0x402c23456789abcd, 0xf000000000000000);132 try test_f128_floatCast_f64(0x1.23456789abcdefp+45, 0x402c23456789abcd, 0xf000000000000000);
134133
135 try test__extenddftf2(0x1.edcba987654321fp-45, 0x3fd2edcba9876543, 0x2000000000000000);134 try test_f128_floatCast_f64(0x1.edcba987654321fp-45, 0x3fd2edcba9876543, 0x2000000000000000);
136135
137 // subnormal136 // subnormal
138 try test__extenddftf2(0x1.8p-1022, 0x3c01800000000000, 0x0);137 try test_f128_floatCast_f64(0x1.8p-1022, 0x3c01800000000000, 0x0);
139 try test__extenddftf2(0x1.8p-1023, 0x3c00800000000000, 0x0);138 try test_f128_floatCast_f64(0x1.8p-1023, 0x3c00800000000000, 0x0);
140}139}
141140
142test "extendhfsf2" {141test f32_floatCast_f16 {
143 try test__extendhfsf2(0x7e00, 0x7fc00000); // qNaN142 try test_f32_floatCast_f16(0x7e00, 0x7fc00000); // qNaN
144 try test__extendhfsf2(0x7f00, 0x7fe00000); // sNaN143 try test_f32_floatCast_f16(0x7f00, 0x7fe00000); // sNaN
145 // On x86 the NaN becomes quiet because the return is pushed on the x87144 // On x86 the NaN becomes quiet because the return is pushed on the x87
146 // stack due to ABI requirements145 // stack due to ABI requirements
147 if (builtin.target.cpu.arch != .x86 and builtin.target.os.tag == .windows)146 if (builtin.target.cpu.arch != .x86 and builtin.target.os.tag == .windows)
148 try test__extendhfsf2(0x7c01, 0x7f802000); // sNaN147 try test_f32_floatCast_f16(0x7c01, 0x7f802000); // sNaN
149148
150 try test__extendhfsf2(0, 0); // 0149 try test_f32_floatCast_f16(0, 0); // 0
151 try test__extendhfsf2(0x8000, 0x80000000); // -0150 try test_f32_floatCast_f16(0x8000, 0x80000000); // -0
152151
153 try test__extendhfsf2(0x7c00, 0x7f800000); // inf152 try test_f32_floatCast_f16(0x7c00, 0x7f800000); // inf
154 try test__extendhfsf2(0xfc00, 0xff800000); // -inf153 try test_f32_floatCast_f16(0xfc00, 0xff800000); // -inf
155154
156 try test__extendhfsf2(0x0001, 0x33800000); // denormal (min), 2**-24155 try test_f32_floatCast_f16(0x0001, 0x33800000); // denormal (min), 2**-24
157 try test__extendhfsf2(0x8001, 0xb3800000); // denormal (min), -2**-24156 try test_f32_floatCast_f16(0x8001, 0xb3800000); // denormal (min), -2**-24
158157
159 try test__extendhfsf2(0x03ff, 0x387fc000); // denormal (max), 2**-14 - 2**-24158 try test_f32_floatCast_f16(0x03ff, 0x387fc000); // denormal (max), 2**-14 - 2**-24
160 try test__extendhfsf2(0x83ff, 0xb87fc000); // denormal (max), -2**-14 + 2**-24159 try test_f32_floatCast_f16(0x83ff, 0xb87fc000); // denormal (max), -2**-14 + 2**-24
161160
162 try test__extendhfsf2(0x0400, 0x38800000); // normal (min), 2**-14161 try test_f32_floatCast_f16(0x0400, 0x38800000); // normal (min), 2**-14
163 try test__extendhfsf2(0x8400, 0xb8800000); // normal (min), -2**-14162 try test_f32_floatCast_f16(0x8400, 0xb8800000); // normal (min), -2**-14
164163
165 try test__extendhfsf2(0x7bff, 0x477fe000); // normal (max), 65504164 try test_f32_floatCast_f16(0x7bff, 0x477fe000); // normal (max), 65504
166 try test__extendhfsf2(0xfbff, 0xc77fe000); // normal (max), -65504165 try test_f32_floatCast_f16(0xfbff, 0xc77fe000); // normal (max), -65504
167166
168 try test__extendhfsf2(0x3c01, 0x3f802000); // normal, 1 + 2**-10167 try test_f32_floatCast_f16(0x3c01, 0x3f802000); // normal, 1 + 2**-10
169 try test__extendhfsf2(0xbc01, 0xbf802000); // normal, -1 - 2**-10168 try test_f32_floatCast_f16(0xbc01, 0xbf802000); // normal, -1 - 2**-10
170169
171 try test__extendhfsf2(0x3555, 0x3eaaa000); // normal, approx. 1/3170 try test_f32_floatCast_f16(0x3555, 0x3eaaa000); // normal, approx. 1/3
172 try test__extendhfsf2(0xb555, 0xbeaaa000); // normal, approx. -1/3171 try test_f32_floatCast_f16(0xb555, 0xbeaaa000); // normal, approx. -1/3
173}172}
174173
175test "extendsftf2" {174test f128_floatCast_f32 {
176 // qNaN175 // qNaN
177 try test__extendsftf2(makeQNaN32(), 0x7fff800000000000, 0x0);176 try test_f128_floatCast_f32(makeQNaN32(), 0x7fff800000000000, 0x0);
178 // NaN177 // NaN
179 try test__extendsftf2(makeNaN32(0x410000), 0x7fff820000000000, 0x0);178 try test_f128_floatCast_f32(makeNaN32(0x410000), 0x7fff820000000000, 0x0);
180 // inf179 // inf
181 try test__extendsftf2(makeInf32(), 0x7fff000000000000, 0x0);180 try test_f128_floatCast_f32(makeInf32(), 0x7fff000000000000, 0x0);
182 // zero181 // zero
183 try test__extendsftf2(0.0, 0x0, 0x0);182 try test_f128_floatCast_f32(0.0, 0x0, 0x0);
184 try test__extendsftf2(0x1.23456p+5, 0x4004234560000000, 0x0);183 try test_f128_floatCast_f32(0x1.23456p+5, 0x4004234560000000, 0x0);
185 try test__extendsftf2(0x1.edcbap-9, 0x3ff6edcba0000000, 0x0);184 try test_f128_floatCast_f32(0x1.edcbap-9, 0x3ff6edcba0000000, 0x0);
186 try test__extendsftf2(0x1.23456p+45, 0x402c234560000000, 0x0);185 try test_f128_floatCast_f32(0x1.23456p+45, 0x402c234560000000, 0x0);
187 try test__extendsftf2(0x1.edcbap-45, 0x3fd2edcba0000000, 0x0);186 try test_f128_floatCast_f32(0x1.edcbap-45, 0x3fd2edcba0000000, 0x0);
188}187}
189188
190fn makeQNaN64() f64 {189fn makeQNaN64() f64 {
...@@ -211,8 +210,8 @@ fn makeInf32() f32 {...@@ -211,8 +210,8 @@ fn makeInf32() f32 {
211 return @bitCast(@as(u32, 0x7f800000));210 return @bitCast(@as(u32, 0x7f800000));
212}211}
213212
214fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void {213fn test_f128_floatCast_f16(a: u16, expected_hi: u64, expected_lo: u64) !void {
215 const x = __extendhftf2(@as(F16T(f128), @bitCast(a)));214 const x = f128_floatCast_f16(@bitCast(a));
216215
217 const rep: u128 = @bitCast(x);216 const rep: u128 = @bitCast(x);
218 const hi: u64 = @intCast(rep >> 64);217 const hi: u64 = @intCast(rep >> 64);
...@@ -233,26 +232,26 @@ fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void {...@@ -233,26 +232,26 @@ fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void {
233 return error.TestFailure;232 return error.TestFailure;
234}233}
235234
236test "extendhftf2" {235test f128_floatCast_f16 {
237 // qNaN236 // qNaN
238 try test__extendhftf2(0x7e00, 0x7fff800000000000, 0x0);237 try test_f128_floatCast_f16(0x7e00, 0x7fff800000000000, 0x0);
239 // NaN238 // NaN
240 try test__extendhftf2(0x7d00, 0x7fff400000000000, 0x0);239 try test_f128_floatCast_f16(0x7d00, 0x7fff400000000000, 0x0);
241 // inf240 // inf
242 try test__extendhftf2(0x7c00, 0x7fff000000000000, 0x0);241 try test_f128_floatCast_f16(0x7c00, 0x7fff000000000000, 0x0);
243 try test__extendhftf2(0xfc00, 0xffff000000000000, 0x0);242 try test_f128_floatCast_f16(0xfc00, 0xffff000000000000, 0x0);
244 // zero243 // zero
245 try test__extendhftf2(0x0000, 0x0000000000000000, 0x0);244 try test_f128_floatCast_f16(0x0000, 0x0000000000000000, 0x0);
246 try test__extendhftf2(0x8000, 0x8000000000000000, 0x0);245 try test_f128_floatCast_f16(0x8000, 0x8000000000000000, 0x0);
247 // denormal246 // denormal
248 try test__extendhftf2(0x0010, 0x3feb000000000000, 0x0);247 try test_f128_floatCast_f16(0x0010, 0x3feb000000000000, 0x0);
249 try test__extendhftf2(0x0001, 0x3fe7000000000000, 0x0);248 try test_f128_floatCast_f16(0x0001, 0x3fe7000000000000, 0x0);
250 try test__extendhftf2(0x8001, 0xbfe7000000000000, 0x0);249 try test_f128_floatCast_f16(0x8001, 0xbfe7000000000000, 0x0);
251250
252 // pi251 // pi
253 try test__extendhftf2(0x4248, 0x4000920000000000, 0x0);252 try test_f128_floatCast_f16(0x4248, 0x4000920000000000, 0x0);
254 try test__extendhftf2(0xc248, 0xc000920000000000, 0x0);253 try test_f128_floatCast_f16(0xc248, 0xc000920000000000, 0x0);
255254
256 try test__extendhftf2(0x508c, 0x4004230000000000, 0x0);255 try test_f128_floatCast_f16(0x508c, 0x4004230000000000, 0x0);
257 try test__extendhftf2(0x1bb7, 0x3ff6edc000000000, 0x0);256 try test_f128_floatCast_f16(0x1bb7, 0x3ff6edc000000000, 0x0);
258}257}
lib/compiler_rt/extendhfdf2.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const extendf = @import("./extendf.zig").extendf;
4
5comptime {
6 symbol(&__extendhfdf2, "__extendhfdf2");
7}
8
9pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const extendf = @import("./extendf.zig").extendf;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
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
14pub fn __extendhfsf2(a: compiler_rt.F16T(f32)) callconv(.c) f32 {
15 return extendf(f32, f16, @as(u16, @bitCast(a)));
16}
17
18fn __gnu_h2f_ieee(a: compiler_rt.F16T(f32)) callconv(.c) f32 {
19 return extendf(f32, f16, @as(u16, @bitCast(a)));
20}
21
22fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const extendf = @import("./extendf.zig").extendf;
4
5comptime {
6 symbol(&__extendhftf2, "__extendhftf2");
7}
8
9pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const extend_f80 = @import("./extendf.zig").extend_f80;
4
5comptime {
6 symbol(&__extendhfxf2, "__extendhfxf2");
7}
8
9fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const extendf = @import("./extendf.zig").extendf;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_f2d, "__aeabi_f2d");
8 } else {
9 symbol(&__extendsfdf2, "__extendsfdf2");
10 }
11}
12
13fn __extendsfdf2(a: f32) callconv(.c) f64 {
14 return extendf(f64, f32, @as(u32, @bitCast(a)));
15}
16
17fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const extendf = @import("./extendf.zig").extendf;
4
5comptime {
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
16pub fn __extendsftf2(a: f32) callconv(.c) f128 {
17 return extendf(f128, f32, @as(u32, @bitCast(a)));
18}
19
20fn _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 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const extend_f80 = @import("./extendf.zig").extend_f80;
3
4comptime {
5 symbol(&__extendsfxf2, "__extendsfxf2");
6}
7
8fn __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 @@
1const std = @import("std");
2
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 symbol(&__extendxftf2, "__extendxftf2");
7}
8
9fn __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,32 +16,47 @@ comptime {
16 symbol(&fabsl, "fabsl");16 symbol(&fabsl, "fabsl");
17}17}
1818
19pub fn __fabsh(a: f16) callconv(.c) f16 {19fn __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}
22pub fn fabs_f16(a: f16) f16 {
20 return generic_fabs(a);23 return generic_fabs(a);
21}24}
2225
23pub fn fabsf(a: f32) callconv(.c) f32 {26fn 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}
29pub fn fabs_f32(a: f32) f32 {
24 return generic_fabs(a);30 return generic_fabs(a);
25}31}
2632
27pub fn fabs(a: f64) callconv(.c) f64 {33fn 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}
36pub fn fabs_f64(a: f64) f64 {
28 return generic_fabs(a);37 return generic_fabs(a);
29}38}
3039
31pub fn __fabsx(a: f80) callconv(.c) f80 {40fn __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}
43pub fn fabs_f80(a: f80) f80 {
32 return generic_fabs(a);44 return generic_fabs(a);
33}45}
3446
35pub fn fabsq(a: f128) callconv(.c) f128 {47fn 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}
50pub fn fabs_f128(a: f128) f128 {
36 return generic_fabs(a);51 return generic_fabs(a);
37}52}
3853
39pub fn fabsl(x: c_longdouble) callconv(.c) c_longdouble {54pub fn fabsl(x: c_longdouble) callconv(.c) c_longdouble {
40 switch (@typeInfo(c_longdouble).float.bits) {55 switch (@typeInfo(c_longdouble).float.bits) {
41 64 => return fabs(x),56 64 => return fabs_f64(x),
42 80 => return __fabsx(x),57 80 => return fabs_f80(x),
43 128 => return fabsq(x),58 128 => return fabs_f128(x),
44 else => @compileError("unreachable"),59 else => comptime unreachable,
45 }60 }
46}61}
4762
lib/compiler_rt/fixdfdi.zig deleted-23
...@@ -1,23 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const intFromFloat = @import("./int_from_float.zig").intFromFloat;
5
6comptime {
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
17pub fn __fixdfdi(a: f64) callconv(.c) i64 {
18 return intFromFloat(i64, a);
19}
20
21fn __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 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
6
7comptime {
8 symbol(&__fixdfei, "__fixdfei");
9}
10
11pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const intFromFloat = @import("./int_from_float.zig").intFromFloat;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_d2iz, "__aeabi_d2iz");
8 } else {
9 symbol(&__fixdfsi, "__fixdfsi");
10 }
11}
12
13pub fn __fixdfsi(a: f64) callconv(.c) i32 {
14 return intFromFloat(i32, a);
15}
16
17fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const intFromFloat = @import("./int_from_float.zig").intFromFloat;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 symbol(&__fixdfti, "__fixdfti");
7}
8
9pub fn __fixdfti(a: f64) callconv(.c) i128 {
10 return intFromFloat(i128, a);
11}
lib/compiler_rt/fixhfei.zig deleted-14
...@@ -1,14 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
6
7comptime {
8 symbol(&__fixhfei, "__fixhfei");
9}
10
11pub 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 @@
1const std = @import("std");
2const math = std.math;
3const testing = std.testing;
4
5const fixint = @import("fixint.zig").fixint;
6
7fn 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
12test "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
32test "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
53test "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
78test "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
102test "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
127test "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 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4const symbol = @import("../compiler_rt.zig").symbol;
5
6comptime {
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
17pub fn __fixsfdi(a: f32) callconv(.c) i64 {
18 return intFromFloat(i64, a);
19}
20
21fn __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 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
6
7comptime {
8 symbol(&__fixsfei, "__fixsfei");
9}
10
11pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_f2iz, "__aeabi_f2iz");
8 } else {
9 symbol(&__fixsfsi, "__fixsfsi");
10 }
11}
12
13pub fn __fixsfsi(a: f32) callconv(.c) i32 {
14 return intFromFloat(i32, a);
15}
16
17fn __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 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const intFromFloat = @import("./int_from_float.zig").intFromFloat;
5
6comptime {
7 symbol(&__fixsfti, "__fixsfti");
8}
9
10pub fn __fixsfti(a: f32) callconv(.c) i128 {
11 return intFromFloat(i128, a);
12}
lib/compiler_rt/fixtfdi.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const intFromFloat = @import("./int_from_float.zig").intFromFloat;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
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
16pub fn __fixtfdi(a: f128) callconv(.c) i64 {
17 return intFromFloat(i64, a);
18}
19
20fn _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 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
6
7comptime {
8 symbol(&__fixtfei, "__fixtfei");
9}
10
11pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
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
16pub fn __fixtfsi(a: f128) callconv(.c) i32 {
17 return intFromFloat(i32, a);
18}
19
20fn _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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const intFromFloat = @import("./int_from_float.zig").intFromFloat;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_ppc_abi)
7 symbol(&__fixtfti, "__fixkfti");
8 symbol(&__fixtfti, "__fixtfti");
9}
10
11pub fn __fixtfti(a: f128) callconv(.c) i128 {
12 return intFromFloat(i128, a);
13}
lib/compiler_rt/fixunsdfdi.zig deleted-23
...@@ -1,23 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const intFromFloat = @import("./int_from_float.zig").intFromFloat;
5
6comptime {
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
17pub fn __fixunsdfdi(a: f64) callconv(.c) u64 {
18 return intFromFloat(u64, a);
19}
20
21fn __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 @@
1const builtin = @import("builtin");
2
3const std = @import("std");
4
5const symbol = @import("../compiler_rt.zig").symbol;
6const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
7
8comptime {
9 symbol(&__fixunsdfei, "__fixunsdfei");
10}
11
12pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_d2uiz, "__aeabi_d2uiz");
8 } else {
9 symbol(&__fixunsdfsi, "__fixunsdfsi");
10 }
11}
12
13pub fn __fixunsdfsi(a: f64) callconv(.c) u32 {
14 return intFromFloat(u32, a);
15}
16
17fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 symbol(&__fixunsdfti, "__fixunsdfti");
7}
8
9pub fn __fixunsdfti(a: f64) callconv(.c) u128 {
10 return intFromFloat(u128, a);
11}
lib/compiler_rt/fixunshfdi.zig deleted-10
...@@ -1,10 +0,0 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const intFromFloat = @import("./int_from_float.zig").intFromFloat;
3
4comptime {
5 symbol(&__fixunshfdi, "__fixunshfdi");
6}
7
8fn __fixunshfdi(a: f16) callconv(.c) u64 {
9 return intFromFloat(u64, a);
10}
lib/compiler_rt/fixunshfei.zig deleted-15
...@@ -1,15 +0,0 @@
1const builtin = @import("builtin");
2
3const std = @import("std");
4
5const symbol = @import("../compiler_rt.zig").symbol;
6const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
7
8comptime {
9 symbol(&__fixunshfei, "__fixunshfei");
10}
11
12pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 symbol(&__fixunshfsi, "__fixunshfsi");
7}
8
9fn __fixunshfsi(a: f16) callconv(.c) u32 {
10 return intFromFloat(u32, a);
11}
lib/compiler_rt/fixunshfti.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const intFromFloat = @import("./int_from_float.zig").intFromFloat;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 symbol(&__fixunshfti, "__fixunshfti");
7}
8
9pub fn __fixunshfti(a: f16) callconv(.c) u128 {
10 return intFromFloat(u128, a);
11}
lib/compiler_rt/fixunssfdi.zig deleted-23
...@@ -1,23 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const intFromFloat = @import("./int_from_float.zig").intFromFloat;
5
6comptime {
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
17pub fn __fixunssfdi(a: f32) callconv(.c) u64 {
18 return intFromFloat(u64, a);
19}
20
21fn __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 @@
1const builtin = @import("builtin");
2
3const std = @import("std");
4
5const symbol = @import("../compiler_rt.zig").symbol;
6const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
7
8comptime {
9 symbol(&__fixunssfei, "__fixunssfei");
10}
11
12pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_f2uiz, "__aeabi_f2uiz");
8 } else {
9 symbol(&__fixunssfsi, "__fixunssfsi");
10 }
11}
12
13pub fn __fixunssfsi(a: f32) callconv(.c) u32 {
14 return intFromFloat(u32, a);
15}
16
17fn __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 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4const symbol = @import("../compiler_rt.zig").symbol;
5
6comptime {
7 symbol(&__fixunssfti, "__fixunssfti");
8}
9
10pub fn __fixunssfti(a: f32) callconv(.c) u128 {
11 return intFromFloat(u128, a);
12}
lib/compiler_rt/fixunstfdi.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
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
16pub fn __fixunstfdi(a: f128) callconv(.c) u64 {
17 return intFromFloat(u64, a);
18}
19
20fn _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 @@
1const builtin = @import("builtin");
2
3const std = @import("std");
4
5const symbol = @import("../compiler_rt.zig").symbol;
6const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
7
8comptime {
9 symbol(&__fixunstfei, "__fixunstfei");
10}
11
12pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
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
16pub fn __fixunstfsi(a: f128) callconv(.c) u32 {
17 return intFromFloat(u32, a);
18}
19
20fn _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 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const intFromFloat = @import("./int_from_float.zig").intFromFloat;
5
6comptime {
7 if (compiler_rt.want_ppc_abi)
8 symbol(&__fixunstfti, "__fixunskfti");
9 symbol(&__fixunstfti, "__fixunstfti");
10}
11
12pub fn __fixunstfti(a: f128) callconv(.c) u128 {
13 return intFromFloat(u128, a);
14}
lib/compiler_rt/fixunsxfdi.zig deleted-10
...@@ -1,10 +0,0 @@
1const intFromFloat = @import("./int_from_float.zig").intFromFloat;
2const symbol = @import("../compiler_rt.zig").symbol;
3
4comptime {
5 symbol(&__fixunsxfdi, "__fixunsxfdi");
6}
7
8fn __fixunsxfdi(a: f80) callconv(.c) u64 {
9 return intFromFloat(u64, a);
10}
lib/compiler_rt/fixunsxfei.zig deleted-13
...@@ -1,13 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const symbol = @import("../compiler_rt.zig").symbol;
4const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
5
6comptime {
7 symbol(&__fixunsxfei, "__fixunsxfei");
8}
9
10pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 symbol(&__fixunsxfsi, "__fixunsxfsi");
7}
8
9fn __fixunsxfsi(a: f80) callconv(.c) u32 {
10 return intFromFloat(u32, a);
11}
lib/compiler_rt/fixunsxfti.zig deleted-12
...@@ -1,12 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const intFromFloat = @import("./int_from_float.zig").intFromFloat;
5
6comptime {
7 symbol(&__fixunsxfti, "__fixunsxfti");
8}
9
10pub fn __fixunsxfti(a: f80) callconv(.c) u128 {
11 return intFromFloat(u128, a);
12}
lib/compiler_rt/fixxfdi.zig deleted-10
...@@ -1,10 +0,0 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const intFromFloat = @import("./int_from_float.zig").intFromFloat;
3
4comptime {
5 symbol(&__fixxfdi, "__fixxfdi");
6}
7
8fn __fixxfdi(a: f80) callconv(.c) i64 {
9 return intFromFloat(i64, a);
10}
lib/compiler_rt/fixxfei.zig deleted-14
...@@ -1,14 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat;
6
7comptime {
8 symbol(&__fixxfei, "__fixxfei");
9}
10
11pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const intFromFloat = @import("./int_from_float.zig").intFromFloat;
4
5comptime {
6 symbol(&__fixxfsi, "__fixxfsi");
7}
8
9fn __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,7 +1,475 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const math = std.math;3const math = std.math;
34
4pub fn floatFromInt(comptime T: type, x: anytype) T {5const compiler_rt = @import("../compiler_rt.zig");
6const symbol = compiler_rt.symbol;
7
8comptime {
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
67fn __floatsihf(a: i32) callconv(.c) compiler_rt.f16.Abi {
68 return compiler_rt.f16.toAbi(f16_floatFromInt_i32(a));
69}
70pub fn f16_floatFromInt_i32(a: i32) f16 {
71 return floatFromInt(f16, a);
72}
73
74fn __floatdihf(a: i64) callconv(.c) compiler_rt.f16.Abi {
75 return compiler_rt.f16.toAbi(f16_floatFromInt_i64(a));
76}
77pub fn f16_floatFromInt_i64(a: i64) f16 {
78 return floatFromInt(f16, a);
79}
80
81fn __floattihf(a: i128) callconv(.c) compiler_rt.f16.Abi {
82 return compiler_rt.f16.toAbi(f16_floatFromInt_i128(a));
83}
84pub fn f16_floatFromInt_i128(a: i128) f16 {
85 return floatFromInt(f16, a);
86}
87
88fn __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}
92pub fn f16_floatFromInt_signed(a: []const u8) f16 {
93 return floatFromBigInt(f16, .signed, @ptrCast(@alignCast(a)));
94}
95
96fn __floatsisf(a: i32) callconv(.c) compiler_rt.f32.Abi {
97 return compiler_rt.f32.toAbi(f32_floatFromInt_i32(a));
98}
99fn __aeabi_i2f(a: i32) callconv(.{ .arm_aapcs = .{} }) f32 {
100 return f32_floatFromInt_i32(a);
101}
102pub fn f32_floatFromInt_i32(a: i32) f32 {
103 return floatFromInt(f32, a);
104}
105
106fn __floatdisf(a: i64) callconv(.c) compiler_rt.f32.Abi {
107 return compiler_rt.f32.toAbi(f32_floatFromInt_i64(a));
108}
109fn __aeabi_l2f(a: i64) callconv(.{ .arm_aapcs = .{} }) f32 {
110 return f32_floatFromInt_i64(a);
111}
112pub fn f32_floatFromInt_i64(a: i64) f32 {
113 return floatFromInt(f32, a);
114}
115
116fn __floattisf(a: i128) callconv(.c) compiler_rt.f32.Abi {
117 return compiler_rt.f32.toAbi(f32_floatFromInt_i128(a));
118}
119pub fn f32_floatFromInt_i128(a: i128) f32 {
120 return floatFromInt(f32, a);
121}
122
123fn __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}
127pub fn f32_floatFromInt_signed(a: []const u8) f32 {
128 return floatFromBigInt(f32, .signed, @ptrCast(@alignCast(a)));
129}
130
131fn __floatsidf(a: i32) callconv(.c) compiler_rt.f64.Abi {
132 return compiler_rt.f64.toAbi(f64_floatFromInt_i32(a));
133}
134fn __aeabi_i2d(a: i32) callconv(.{ .arm_aapcs = .{} }) f64 {
135 return f64_floatFromInt_i32(a);
136}
137pub fn f64_floatFromInt_i32(a: i32) f64 {
138 return floatFromInt(f64, a);
139}
140
141fn __floatdidf(a: i64) callconv(.c) compiler_rt.f64.Abi {
142 return compiler_rt.f64.toAbi(f64_floatFromInt_i64(a));
143}
144fn __aeabi_l2d(a: i64) callconv(.{ .arm_aapcs = .{} }) f64 {
145 return f64_floatFromInt_i64(a);
146}
147pub fn f64_floatFromInt_i64(a: i64) f64 {
148 return floatFromInt(f64, a);
149}
150
151fn __floattidf(a: i128) callconv(.c) compiler_rt.f64.Abi {
152 return compiler_rt.f64.toAbi(f64_floatFromInt_i128(a));
153}
154pub fn f64_floatFromInt_i128(a: i128) f64 {
155 return floatFromInt(f64, a);
156}
157
158fn __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}
162pub fn f64_floatFromInt_signed(a: []const u8) f64 {
163 return floatFromBigInt(f64, .signed, @ptrCast(@alignCast(a)));
164}
165
166fn __floatsixf(a: i32) callconv(.c) compiler_rt.f80.Abi {
167 return compiler_rt.f80.toAbi(f80_floatFromInt_i32(a));
168}
169pub fn f80_floatFromInt_i32(a: i32) f80 {
170 return floatFromInt(f80, a);
171}
172
173fn __floatdixf(a: i64) callconv(.c) compiler_rt.f80.Abi {
174 return compiler_rt.f80.toAbi(f80_floatFromInt_i64(a));
175}
176pub fn f80_floatFromInt_i64(a: i64) f80 {
177 return floatFromInt(f80, a);
178}
179
180fn __floattixf(a: i128) callconv(.c) compiler_rt.f80.Abi {
181 return compiler_rt.f80.toAbi(f80_floatFromInt_i128(a));
182}
183pub fn f80_floatFromInt_i128(a: i128) f80 {
184 return floatFromInt(f80, a);
185}
186
187fn __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}
191pub fn f80_floatFromInt_signed(a: []const u8) f80 {
192 return floatFromBigInt(f80, .signed, @ptrCast(@alignCast(a)));
193}
194
195fn __floatsitf(a: i32) callconv(.c) compiler_rt.f128.Abi {
196 return compiler_rt.f128.toAbi(f128_floatFromInt_i32(a));
197}
198fn _Qp_itoq(c: *f128, a: i32) callconv(.c) void {
199 c.* = f128_floatFromInt_i32(a);
200}
201pub fn f128_floatFromInt_i32(a: i32) f128 {
202 return floatFromInt(f128, a);
203}
204
205fn __floatditf(a: i64) callconv(.c) compiler_rt.f128.Abi {
206 return compiler_rt.f128.toAbi(f128_floatFromInt_i64(a));
207}
208fn _Qp_xtoq(c: *f128, a: i64) callconv(.c) void {
209 c.* = f128_floatFromInt_i64(a);
210}
211pub fn f128_floatFromInt_i64(a: i64) f128 {
212 return floatFromInt(f128, a);
213}
214
215fn __floattitf(a: i128) callconv(.c) compiler_rt.f128.Abi {
216 return compiler_rt.f128.toAbi(f128_floatFromInt_i128(a));
217}
218fn __floattitf_x86(a: f128) callconv(.c) compiler_rt.f128.Abi {
219 return compiler_rt.f128.toAbi(f128_floatFromInt_i128(@bitCast(a)));
220}
221pub fn f128_floatFromInt_i128(a: i128) f128 {
222 return floatFromInt(f128, a);
223}
224
225fn __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}
229pub fn f128_floatFromInt_signed(a: []const u8) f128 {
230 return floatFromBigInt(f128, .signed, @ptrCast(@alignCast(a)));
231}
232
233comptime {
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
301fn __floatunsihf(a: u32) callconv(.c) compiler_rt.f16.Abi {
302 return compiler_rt.f16.toAbi(f16_floatFromInt_u32(a));
303}
304pub fn f16_floatFromInt_u32(a: u32) f16 {
305 return floatFromInt(f16, a);
306}
307
308fn __floatundihf(a: u64) callconv(.c) compiler_rt.f16.Abi {
309 return compiler_rt.f16.toAbi(f16_floatFromInt_u64(a));
310}
311pub fn f16_floatFromInt_u64(a: u64) f16 {
312 return floatFromInt(f16, a);
313}
314
315fn __floatuntihf(a: u128) callconv(.c) compiler_rt.f16.Abi {
316 return compiler_rt.f16.toAbi(f16_floatFromInt_u128(a));
317}
318pub fn f16_floatFromInt_u128(a: u128) f16 {
319 return floatFromInt(f16, a);
320}
321
322fn __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}
326pub fn f16_floatFromInt_unsigned(a: []const u8) f16 {
327 return floatFromBigInt(f16, .unsigned, @ptrCast(@alignCast(a)));
328}
329
330fn __floatunsisf(a: u32) callconv(.c) compiler_rt.f32.Abi {
331 return compiler_rt.f32.toAbi(f32_floatFromInt_u32(a));
332}
333fn __aeabi_ui2f(a: u32) callconv(.{ .arm_aapcs = .{} }) f32 {
334 return f32_floatFromInt_u32(a);
335}
336pub fn f32_floatFromInt_u32(a: u32) f32 {
337 return floatFromInt(f32, a);
338}
339
340fn __floatundisf(a: u64) callconv(.c) compiler_rt.f32.Abi {
341 return compiler_rt.f32.toAbi(f32_floatFromInt_u64(a));
342}
343fn __aeabi_ul2f(a: u64) callconv(.{ .arm_aapcs = .{} }) f32 {
344 return f32_floatFromInt_u64(a);
345}
346pub fn f32_floatFromInt_u64(a: u64) f32 {
347 return floatFromInt(f32, a);
348}
349
350fn __floatuntisf(a: u128) callconv(.c) compiler_rt.f32.Abi {
351 return compiler_rt.f32.toAbi(f32_floatFromInt_u128(a));
352}
353pub fn f32_floatFromInt_u128(a: u128) f32 {
354 return floatFromInt(f32, a);
355}
356
357fn __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}
361pub fn f32_floatFromInt_unsigned(a: []const u8) f32 {
362 return floatFromBigInt(f32, .unsigned, @ptrCast(@alignCast(a)));
363}
364
365fn __floatunsidf(a: u32) callconv(.c) compiler_rt.f64.Abi {
366 return compiler_rt.f64.toAbi(f64_floatFromInt_u32(a));
367}
368fn __aeabi_ui2d(a: u32) callconv(.{ .arm_aapcs = .{} }) f64 {
369 return f64_floatFromInt_u32(a);
370}
371pub fn f64_floatFromInt_u32(a: u32) f64 {
372 return floatFromInt(f64, a);
373}
374
375fn __floatundidf(a: u64) callconv(.c) compiler_rt.f64.Abi {
376 return compiler_rt.f64.toAbi(f64_floatFromInt_u64(a));
377}
378fn __aeabi_ul2d(a: u64) callconv(.{ .arm_aapcs = .{} }) f64 {
379 return f64_floatFromInt_u64(a);
380}
381pub fn f64_floatFromInt_u64(a: u64) f64 {
382 return floatFromInt(f64, a);
383}
384
385fn __floatuntidf(a: u128) callconv(.c) compiler_rt.f64.Abi {
386 return compiler_rt.f64.toAbi(f64_floatFromInt_u128(a));
387}
388pub fn f64_floatFromInt_u128(a: u128) f64 {
389 return floatFromInt(f64, a);
390}
391
392fn __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}
396pub fn f64_floatFromInt_unsigned(a: []const u8) f64 {
397 return floatFromBigInt(f64, .unsigned, @ptrCast(@alignCast(a)));
398}
399
400fn __floatunsixf(a: u32) callconv(.c) compiler_rt.f80.Abi {
401 return compiler_rt.f80.toAbi(f80_floatFromInt_u32(a));
402}
403pub fn f80_floatFromInt_u32(a: u32) f80 {
404 return floatFromInt(f80, a);
405}
406
407fn __floatundixf(a: u64) callconv(.c) compiler_rt.f80.Abi {
408 return compiler_rt.f80.toAbi(f80_floatFromInt_u64(a));
409}
410pub fn f80_floatFromInt_u64(a: u64) f80 {
411 return floatFromInt(f80, a);
412}
413
414fn __floatuntixf(a: u128) callconv(.c) compiler_rt.f80.Abi {
415 return compiler_rt.f80.toAbi(f80_floatFromInt_u128(a));
416}
417pub fn f80_floatFromInt_u128(a: u128) f80 {
418 return floatFromInt(f80, a);
419}
420
421fn __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}
425pub fn f80_floatFromInt_unsigned(a: []const u8) f80 {
426 return floatFromBigInt(f80, .unsigned, @ptrCast(@alignCast(a)));
427}
428
429fn __floatunsitf(a: u32) callconv(.c) compiler_rt.f128.Abi {
430 return compiler_rt.f128.toAbi(f128_floatFromInt_u32(a));
431}
432fn _Qp_uitoq(c: *f128, a: u32) callconv(.c) void {
433 c.* = f128_floatFromInt_u32(a);
434}
435pub fn f128_floatFromInt_u32(a: u32) f128 {
436 return floatFromInt(f128, a);
437}
438
439fn __floatunditf(a: u64) callconv(.c) compiler_rt.f128.Abi {
440 return compiler_rt.f128.toAbi(f128_floatFromInt_u64(a));
441}
442fn _Qp_uxtoq(c: *f128, a: u64) callconv(.c) void {
443 c.* = f128_floatFromInt_u64(a);
444}
445pub fn f128_floatFromInt_u64(a: u64) f128 {
446 return floatFromInt(f128, a);
447}
448
449fn __floatuntitf(a: u128) callconv(.c) compiler_rt.f128.Abi {
450 return compiler_rt.f128.toAbi(f128_floatFromInt_u128(a));
451}
452fn __floatuntitf_x86(a: f128) callconv(.c) compiler_rt.f128.Abi {
453 return compiler_rt.f128.toAbi(f128_floatFromInt_u128(@bitCast(a)));
454}
455fn __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}
460pub fn f128_floatFromInt_u128(a: u128) f128 {
461 return floatFromInt(f128, a);
462}
463
464fn __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}
468pub fn f128_floatFromInt_unsigned(a: []const u8) f128 {
469 return floatFromBigInt(f128, .unsigned, @ptrCast(@alignCast(a)));
470}
471
472inline fn floatFromInt(comptime T: type, x: anytype) T {
5 if (x == 0) return 0;473 if (x == 0) return 0;
6474
7 // Various constants whose values follow from the type parameters.475 // Various constants whose values follow from the type parameters.
...@@ -53,7 +521,7 @@ pub fn floatFromInt(comptime T: type, x: anytype) T {...@@ -53,7 +521,7 @@ pub fn floatFromInt(comptime T: type, x: anytype) T {
53 return @bitCast(sign_bit | result);521 return @bitCast(sign_bit | result);
54}522}
55523
56const endian = @import("builtin").cpu.arch.endian();524const endian = builtin.cpu.arch.endian();
57inline fn limb(limbs: []const u32, index: usize) u32 {525inline fn limb(limbs: []const u32, index: usize) u32 {
58 return switch (endian) {526 return switch (endian) {
59 .little => limbs[index],527 .little => limbs[index],
...@@ -61,11 +529,11 @@ inline fn limb(limbs: []const u32, index: usize) u32 {...@@ -61,11 +529,11 @@ inline fn limb(limbs: []const u32, index: usize) u32 {
61 };529 };
62}530}
63531
64pub inline fn floatFromBigInt(comptime T: type, comptime signedness: std.builtin.Signedness, x: []const u32) T {532inline fn floatFromBigInt(comptime T: type, comptime signedness: std.lang.Signedness, x: []const u32) T {
65 switch (x.len) {533 switch (x.len) {
66 0 => return 0,534 0 => return 0,
67 inline 1...4 => |limbs_len| {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 .little => x[0..limbs_len].*,537 .little => x[0..limbs_len].*,
70 .big => switch (limbs_len) {538 .big => switch (limbs_len) {
71 1 => .{x[0]},539 1 => .{x[0]},
lib/compiler_rt/float_from_int_test.zig+757-733
...@@ -2,571 +2,593 @@ const std = @import("std");...@@ -2,571 +2,593 @@ const std = @import("std");
2const testing = std.testing;2const testing = std.testing;
3const math = std.math;3const math = std.math;
44
5const __floatunsihf = @import("floatunsihf.zig").__floatunsihf;5const impl = @import("float_from_int.zig");
66
7// Conversion to f327const f16_floatFromInt_i32 = impl.f16_floatFromInt_i32;
8const __floatsisf = @import("floatsisf.zig").__floatsisf;8const f16_floatFromInt_u32 = impl.f16_floatFromInt_u32;
9const __floatunsisf = @import("floatunsisf.zig").__floatunsisf;9const f16_floatFromInt_i64 = impl.f16_floatFromInt_i64;
10const __floatdisf = @import("floatdisf.zig").__floatdisf;10const f16_floatFromInt_u64 = impl.f16_floatFromInt_u64;
11const __floatundisf = @import("floatundisf.zig").__floatundisf;11const f16_floatFromInt_i128 = impl.f16_floatFromInt_i128;
12const __floattisf = @import("floattisf.zig").__floattisf;12const f16_floatFromInt_u128 = impl.f16_floatFromInt_u128;
13const __floatuntisf = @import("floatuntisf.zig").__floatuntisf;13const f16_floatFromInt_signed = impl.f16_floatFromInt_signed;
14const __floateisf = @import("floateisf.zig").__floateisf;14const f16_floatFromInt_unsigned = impl.f16_floatFromInt_unsigned;
15const __floatuneisf = @import("floatuneisf.zig").__floatuneisf;15
1616const f32_floatFromInt_i32 = impl.f32_floatFromInt_i32;
17// Conversion to f6417const f32_floatFromInt_u32 = impl.f32_floatFromInt_u32;
18const __floatsidf = @import("floatsidf.zig").__floatsidf;18const f32_floatFromInt_i64 = impl.f32_floatFromInt_i64;
19const __floatunsidf = @import("floatunsidf.zig").__floatunsidf;19const f32_floatFromInt_u64 = impl.f32_floatFromInt_u64;
20const __floatdidf = @import("floatdidf.zig").__floatdidf;20const f32_floatFromInt_i128 = impl.f32_floatFromInt_i128;
21const __floatundidf = @import("floatundidf.zig").__floatundidf;21const f32_floatFromInt_u128 = impl.f32_floatFromInt_u128;
22const __floattidf = @import("floattidf.zig").__floattidf;22const f32_floatFromInt_signed = impl.f32_floatFromInt_signed;
23const __floatuntidf = @import("floatuntidf.zig").__floatuntidf;23const f32_floatFromInt_unsigned = impl.f32_floatFromInt_unsigned;
2424
25// Conversion to f12825const f64_floatFromInt_i32 = impl.f64_floatFromInt_i32;
26const __floatsitf = @import("floatsitf.zig").__floatsitf;26const f64_floatFromInt_u32 = impl.f64_floatFromInt_u32;
27const __floatunsitf = @import("floatunsitf.zig").__floatunsitf;27const f64_floatFromInt_i64 = impl.f64_floatFromInt_i64;
28const __floatditf = @import("floatditf.zig").__floatditf;28const f64_floatFromInt_u64 = impl.f64_floatFromInt_u64;
29const __floatunditf = @import("floatunditf.zig").__floatunditf;29const f64_floatFromInt_i128 = impl.f64_floatFromInt_i128;
30const __floattitf = @import("floattitf.zig").__floattitf;30const f64_floatFromInt_u128 = impl.f64_floatFromInt_u128;
31const __floatuntitf = @import("floatuntitf.zig").__floatuntitf;31const f64_floatFromInt_signed = impl.f64_floatFromInt_signed;
3232const f64_floatFromInt_unsigned = impl.f64_floatFromInt_unsigned;
33fn test__floatsisf(a: i32, expected: u32) !void {33
34 const r = __floatsisf(a);34const f80_floatFromInt_i32 = impl.f80_floatFromInt_i32;
35const f80_floatFromInt_u32 = impl.f80_floatFromInt_u32;
36const f80_floatFromInt_i64 = impl.f80_floatFromInt_i64;
37const f80_floatFromInt_u64 = impl.f80_floatFromInt_u64;
38const f80_floatFromInt_i128 = impl.f80_floatFromInt_i128;
39const f80_floatFromInt_u128 = impl.f80_floatFromInt_u128;
40const f80_floatFromInt_signed = impl.f80_floatFromInt_signed;
41const f80_floatFromInt_unsigned = impl.f80_floatFromInt_unsigned;
42
43const f128_floatFromInt_i32 = impl.f128_floatFromInt_i32;
44const f128_floatFromInt_u32 = impl.f128_floatFromInt_u32;
45const f128_floatFromInt_i64 = impl.f128_floatFromInt_i64;
46const f128_floatFromInt_u64 = impl.f128_floatFromInt_u64;
47const f128_floatFromInt_i128 = impl.f128_floatFromInt_i128;
48const f128_floatFromInt_u128 = impl.f128_floatFromInt_u128;
49const f128_floatFromInt_signed = impl.f128_floatFromInt_signed;
50const f128_floatFromInt_unsigned = impl.f128_floatFromInt_unsigned;
51
52fn test_f32_floatFromInt_i32(a: i32, expected: u32) !void {
53 const r = f32_floatFromInt_i32(a);
35 try std.testing.expect(@as(u32, @bitCast(r)) == expected);54 try std.testing.expect(@as(u32, @bitCast(r)) == expected);
36}55}
3756
38fn test_one_floatunsisf(a: u32, expected: u32) !void {57fn test_f32_floatFromInt_u32(a: u32, expected: u32) !void {
39 const r = __floatunsisf(a);58 const r = f32_floatFromInt_u32(a);
40 try std.testing.expect(@as(u32, @bitCast(r)) == expected);59 try std.testing.expect(@as(u32, @bitCast(r)) == expected);
41}60}
4261
43test "floatsisf" {62test f32_floatFromInt_i32 {
44 try test__floatsisf(0, 0x00000000);63 try test_f32_floatFromInt_i32(0, 0x00000000);
45 try test__floatsisf(1, 0x3f800000);64 try test_f32_floatFromInt_i32(1, 0x3f800000);
46 try test__floatsisf(-1, 0xbf800000);65 try test_f32_floatFromInt_i32(-1, 0xbf800000);
47 try test__floatsisf(0x7FFFFFFF, 0x4f000000);66 try test_f32_floatFromInt_i32(0x7FFFFFFF, 0x4f000000);
48 try test__floatsisf(@bitCast(@as(u32, @intCast(0x80000000))), 0xcf000000);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}
5071
51test "floatunsisf" {72test f32_floatFromInt_u32 {
52 // Test the produced bit pattern73 // Test the produced bit pattern
53 try test_one_floatunsisf(0, 0);74 try test_f32_floatFromInt_u32(0, 0);
54 try test_one_floatunsisf(1, 0x3f800000);75 try test_f32_floatFromInt_u32(1, 0x3f800000);
55 try test_one_floatunsisf(0x7FFFFFFF, 0x4f000000);76 try test_f32_floatFromInt_u32(0x7FFFFFFF, 0x4f000000);
56 try test_one_floatunsisf(0x80000000, 0x4f000000);77 try test_f32_floatFromInt_u32(0x80000000, 0x4f000000);
57 try test_one_floatunsisf(0xFFFFFFFF, 0x4f800000);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
90fn test_f32_floatFromInt_i64(a: i64, expected: f32) !void {
91 const x = f32_floatFromInt_i64(a);
92 try testing.expect(x == expected);
58}93}
5994
60fn test__floatdisf(a: i64, expected: f32) !void {95fn test_f32_floatFromInt_u64(a: u64, expected: f32) !void {
61 const x = __floatdisf(a);96 const x = f32_floatFromInt_u64(a);
62 try testing.expect(x == expected);97 try testing.expect(x == expected);
63}98}
6499
65fn test__floatundisf(a: u64, expected: f32) !void {100test f32_floatFromInt_i64 {
66 try std.testing.expectEqual(expected, __floatundisf(a));101 try test_f32_floatFromInt_i64(0, 0.0);
67}102 try test_f32_floatFromInt_i64(1, 1.0);
68103 try test_f32_floatFromInt_i64(2, 2.0);
69test "floatdisf" {104 try test_f32_floatFromInt_i64(-1, -1.0);
70 try test__floatdisf(0, 0.0);105 try test_f32_floatFromInt_i64(-2, -2.0);
71 try test__floatdisf(1, 1.0);106 try test_f32_floatFromInt_i64(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
72 try test__floatdisf(2, 2.0);107 try test_f32_floatFromInt_i64(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
73 try test__floatdisf(-1, -1.0);108 try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000008000000000)), -0x1.FFFFFEp+62);
74 try test__floatdisf(-2, -2.0);109 try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000010000000000)), -0x1.FFFFFCp+62);
75 try test__floatdisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);110 try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000000)), -0x1.000000p+63);
76 try test__floatdisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);111 try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000001)), -0x1.000000p+63);
77 try test__floatdisf(@bitCast(@as(u64, 0x8000008000000000)), -0x1.FFFFFEp+62);112 try test_f32_floatFromInt_i64(0x0007FB72E8000000, 0x1.FEDCBAp+50);
78 try test__floatdisf(@bitCast(@as(u64, 0x8000010000000000)), -0x1.FFFFFCp+62);113 try test_f32_floatFromInt_i64(0x0007FB72EA000000, 0x1.FEDCBAp+50);
79 try test__floatdisf(@bitCast(@as(u64, 0x8000000000000000)), -0x1.000000p+63);114 try test_f32_floatFromInt_i64(0x0007FB72EB000000, 0x1.FEDCBAp+50);
80 try test__floatdisf(@bitCast(@as(u64, 0x8000000000000001)), -0x1.000000p+63);115 try test_f32_floatFromInt_i64(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
81 try test__floatdisf(0x0007FB72E8000000, 0x1.FEDCBAp+50);116 try test_f32_floatFromInt_i64(0x0007FB72EC000000, 0x1.FEDCBCp+50);
82 try test__floatdisf(0x0007FB72EA000000, 0x1.FEDCBAp+50);117 try test_f32_floatFromInt_i64(0x0007FB72E8000001, 0x1.FEDCBAp+50);
83 try test__floatdisf(0x0007FB72EB000000, 0x1.FEDCBAp+50);118 try test_f32_floatFromInt_i64(0x0007FB72E6000000, 0x1.FEDCBAp+50);
84 try test__floatdisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);119 try test_f32_floatFromInt_i64(0x0007FB72E7000000, 0x1.FEDCBAp+50);
85 try test__floatdisf(0x0007FB72EC000000, 0x1.FEDCBCp+50);120 try test_f32_floatFromInt_i64(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
86 try test__floatdisf(0x0007FB72E8000001, 0x1.FEDCBAp+50);121 try test_f32_floatFromInt_i64(0x0007FB72E4000001, 0x1.FEDCBAp+50);
87 try test__floatdisf(0x0007FB72E6000000, 0x1.FEDCBAp+50);122 try test_f32_floatFromInt_i64(0x0007FB72E4000000, 0x1.FEDCB8p+50);
88 try test__floatdisf(0x0007FB72E7000000, 0x1.FEDCBAp+50);123}
89 try test__floatdisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);124
90 try test__floatdisf(0x0007FB72E4000001, 0x1.FEDCBAp+50);125test f32_floatFromInt_u64 {
91 try test__floatdisf(0x0007FB72E4000000, 0x1.FEDCB8p+50);126 try test_f32_floatFromInt_u64(0, 0.0);
92}127 try test_f32_floatFromInt_u64(1, 1.0);
93128 try test_f32_floatFromInt_u64(2, 2.0);
94test "floatundisf" {129 try test_f32_floatFromInt_u64(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
95 try test__floatundisf(0, 0.0);130 try test_f32_floatFromInt_u64(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
96 try test__floatundisf(1, 1.0);131 try test_f32_floatFromInt_u64(0x8000008000000000, 0x1p+63);
97 try test__floatundisf(2, 2.0);132 try test_f32_floatFromInt_u64(0x8000010000000000, 0x1.000002p+63);
98 try test__floatundisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);133 try test_f32_floatFromInt_u64(0x8000000000000000, 0x1p+63);
99 try test__floatundisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);134 try test_f32_floatFromInt_u64(0x8000000000000001, 0x1p+63);
100 try test__floatundisf(0x8000008000000000, 0x1p+63);135 try test_f32_floatFromInt_u64(0xFFFFFFFFFFFFFFFE, 0x1p+64);
101 try test__floatundisf(0x8000010000000000, 0x1.000002p+63);136 try test_f32_floatFromInt_u64(0xFFFFFFFFFFFFFFFF, 0x1p+64);
102 try test__floatundisf(0x8000000000000000, 0x1p+63);137 try test_f32_floatFromInt_u64(0x0007FB72E8000000, 0x1.FEDCBAp+50);
103 try test__floatundisf(0x8000000000000001, 0x1p+63);138 try test_f32_floatFromInt_u64(0x0007FB72EA000000, 0x1.FEDCBAp+50);
104 try test__floatundisf(0xFFFFFFFFFFFFFFFE, 0x1p+64);139 try test_f32_floatFromInt_u64(0x0007FB72EB000000, 0x1.FEDCBAp+50);
105 try test__floatundisf(0xFFFFFFFFFFFFFFFF, 0x1p+64);140 try test_f32_floatFromInt_u64(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
106 try test__floatundisf(0x0007FB72E8000000, 0x1.FEDCBAp+50);141 try test_f32_floatFromInt_u64(0x0007FB72EC000000, 0x1.FEDCBCp+50);
107 try test__floatundisf(0x0007FB72EA000000, 0x1.FEDCBAp+50);142 try test_f32_floatFromInt_u64(0x0007FB72E8000001, 0x1.FEDCBAp+50);
108 try test__floatundisf(0x0007FB72EB000000, 0x1.FEDCBAp+50);143 try test_f32_floatFromInt_u64(0x0007FB72E6000000, 0x1.FEDCBAp+50);
109 try test__floatundisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);144 try test_f32_floatFromInt_u64(0x0007FB72E7000000, 0x1.FEDCBAp+50);
110 try test__floatundisf(0x0007FB72EC000000, 0x1.FEDCBCp+50);145 try test_f32_floatFromInt_u64(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
111 try test__floatundisf(0x0007FB72E8000001, 0x1.FEDCBAp+50);146 try test_f32_floatFromInt_u64(0x0007FB72E4000001, 0x1.FEDCBAp+50);
112 try test__floatundisf(0x0007FB72E6000000, 0x1.FEDCBAp+50);147 try test_f32_floatFromInt_u64(0x0007FB72E4000000, 0x1.FEDCB8p+50);
113 try test__floatundisf(0x0007FB72E7000000, 0x1.FEDCBAp+50);148}
114 try test__floatundisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);149
115 try test__floatundisf(0x0007FB72E4000001, 0x1.FEDCBAp+50);150fn test_f32_floatFromInt_i128(a: i128, expected: f32) !void {
116 try test__floatundisf(0x0007FB72E4000000, 0x1.FEDCB8p+50);151 const x = f32_floatFromInt_i128(a);
117}
118
119fn test__floattisf(a: i128, expected: f32) !void {
120 const x = __floattisf(a);
121 try testing.expect(x == expected);152 try testing.expect(x == expected);
122}153}
123154
124fn test__floatuntisf(a: u128, expected: f32) !void {155fn test_f32_floatFromInt_u128(a: u128, expected: f32) !void {
125 const x = __floatuntisf(a);156 const x = f32_floatFromInt_u128(a);
126 try testing.expect(x == expected);157 try testing.expect(x == expected);
127}158}
128159
129test "floattisf" {160test f32_floatFromInt_i128 {
130 try test__floattisf(0, 0.0);161 try test_f32_floatFromInt_i128(0, 0.0);
131162
132 try test__floattisf(1, 1.0);163 try test_f32_floatFromInt_i128(1, 1.0);
133 try test__floattisf(2, 2.0);164 try test_f32_floatFromInt_i128(2, 2.0);
134 try test__floattisf(-1, -1.0);165 try test_f32_floatFromInt_i128(-1, -1.0);
135 try test__floattisf(-2, -2.0);166 try test_f32_floatFromInt_i128(-2, -2.0);
136167
137 try test__floattisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);168 try test_f32_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
138 try test__floattisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);169 try test_f32_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
139170
140 try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000008000000000), -0x1.FFFFFEp+62);171 try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000008000000000), -0x1.FFFFFEp+62);
141 try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000010000000000), -0x1.FFFFFCp+62);172 try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000010000000000), -0x1.FFFFFCp+62);
142173
143 try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000000), -0x1.000000p+63);174 try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000000), -0x1.000000p+63);
144 try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000001), -0x1.000000p+63);175 try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000001), -0x1.000000p+63);
145176
146 try test__floattisf(0x0007FB72E8000000, 0x1.FEDCBAp+50);177 try test_f32_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
147178
148 try test__floattisf(0x0007FB72EA000000, 0x1.FEDCBAp+50);179 try test_f32_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBAp+50);
149 try test__floattisf(0x0007FB72EB000000, 0x1.FEDCBAp+50);180 try test_f32_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBAp+50);
150 try test__floattisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);181 try test_f32_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
151 try test__floattisf(0x0007FB72EC000000, 0x1.FEDCBCp+50);182 try test_f32_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBCp+50);
152 try test__floattisf(0x0007FB72E8000001, 0x1.FEDCBAp+50);183 try test_f32_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBAp+50);
153184
154 try test__floattisf(0x0007FB72E6000000, 0x1.FEDCBAp+50);185 try test_f32_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCBAp+50);
155 try test__floattisf(0x0007FB72E7000000, 0x1.FEDCBAp+50);186 try test_f32_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCBAp+50);
156 try test__floattisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);187 try test_f32_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
157 try test__floattisf(0x0007FB72E4000001, 0x1.FEDCBAp+50);188 try test_f32_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCBAp+50);
158 try test__floattisf(0x0007FB72E4000000, 0x1.FEDCB8p+50);189 try test_f32_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB8p+50);
159190
160 try test__floattisf(make_ti(0x0007FB72E8000000, 0), 0x1.FEDCBAp+114);191 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E8000000, 0), 0x1.FEDCBAp+114);
161192
162 try test__floattisf(make_ti(0x0007FB72EA000000, 0), 0x1.FEDCBAp+114);193 try test_f32_floatFromInt_i128(make_ti(0x0007FB72EA000000, 0), 0x1.FEDCBAp+114);
163 try test__floattisf(make_ti(0x0007FB72EB000000, 0), 0x1.FEDCBAp+114);194 try test_f32_floatFromInt_i128(make_ti(0x0007FB72EB000000, 0), 0x1.FEDCBAp+114);
164 try test__floattisf(make_ti(0x0007FB72EBFFFFFF, 0), 0x1.FEDCBAp+114);195 try test_f32_floatFromInt_i128(make_ti(0x0007FB72EBFFFFFF, 0), 0x1.FEDCBAp+114);
165 try test__floattisf(make_ti(0x0007FB72EC000000, 0), 0x1.FEDCBCp+114);196 try test_f32_floatFromInt_i128(make_ti(0x0007FB72EC000000, 0), 0x1.FEDCBCp+114);
166 try test__floattisf(make_ti(0x0007FB72E8000001, 0), 0x1.FEDCBAp+114);197 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E8000001, 0), 0x1.FEDCBAp+114);
167198
168 try test__floattisf(make_ti(0x0007FB72E6000000, 0), 0x1.FEDCBAp+114);199 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E6000000, 0), 0x1.FEDCBAp+114);
169 try test__floattisf(make_ti(0x0007FB72E7000000, 0), 0x1.FEDCBAp+114);200 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E7000000, 0), 0x1.FEDCBAp+114);
170 try test__floattisf(make_ti(0x0007FB72E7FFFFFF, 0), 0x1.FEDCBAp+114);201 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E7FFFFFF, 0), 0x1.FEDCBAp+114);
171 try test__floattisf(make_ti(0x0007FB72E4000001, 0), 0x1.FEDCBAp+114);202 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E4000001, 0), 0x1.FEDCBAp+114);
172 try test__floattisf(make_ti(0x0007FB72E4000000, 0), 0x1.FEDCB8p+114);203 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E4000000, 0), 0x1.FEDCB8p+114);
173}204}
174205
175test "floatuntisf" {206test f32_floatFromInt_u128 {
176 try test__floatuntisf(0, 0.0);207 try test_f32_floatFromInt_u128(0, 0.0);
177208
178 try test__floatuntisf(1, 1.0);209 try test_f32_floatFromInt_u128(1, 1.0);
179 try test__floatuntisf(2, 2.0);210 try test_f32_floatFromInt_u128(2, 2.0);
180 try test__floatuntisf(20, 20.0);211 try test_f32_floatFromInt_u128(20, 20.0);
181212
182 try test__floatuntisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);213 try test_f32_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
183 try test__floatuntisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);214 try test_f32_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
184215
185 try test__floatuntisf(make_uti(0x8000008000000000, 0), 0x1.000001p+127);216 try test_f32_floatFromInt_u128(make_uti(0x8000008000000000, 0), 0x1.000001p+127);
186 try test__floatuntisf(make_uti(0x8000000000000800, 0), 0x1.0p+127);217 try test_f32_floatFromInt_u128(make_uti(0x8000000000000800, 0), 0x1.0p+127);
187 try test__floatuntisf(make_uti(0x8000010000000000, 0), 0x1.000002p+127);218 try test_f32_floatFromInt_u128(make_uti(0x8000010000000000, 0), 0x1.000002p+127);
188219
189 try test__floatuntisf(make_uti(0x8000000000000000, 0), 0x1.000000p+127);220 try test_f32_floatFromInt_u128(make_uti(0x8000000000000000, 0), 0x1.000000p+127);
190221
191 try test__floatuntisf(0x0007FB72E8000000, 0x1.FEDCBAp+50);222 try test_f32_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
192223
193 try test__floatuntisf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);224 try test_f32_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
194 try test__floatuntisf(0x0007FB72EB000000, 0x1.FEDCBACp+50);225 try test_f32_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50);
195226
196 try test__floatuntisf(0x0007FB72EC000000, 0x1.FEDCBBp+50);227 try test_f32_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50);
197228
198 try test__floatuntisf(0x0007FB72E6000000, 0x1.FEDCB98p+50);229 try test_f32_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50);
199 try test__floatuntisf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);230 try test_f32_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
200 try test__floatuntisf(0x0007FB72E4000000, 0x1.FEDCB9p+50);231 try test_f32_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50);
201232
202 try test__floatuntisf(0xFFFFFFFFFFFFFFFE, 0x1p+64);233 try test_f32_floatFromInt_u128(0xFFFFFFFFFFFFFFFE, 0x1p+64);
203 try test__floatuntisf(0xFFFFFFFFFFFFFFFF, 0x1p+64);234 try test_f32_floatFromInt_u128(0xFFFFFFFFFFFFFFFF, 0x1p+64);
204235
205 try test__floatuntisf(0x0007FB72E8000000, 0x1.FEDCBAp+50);236 try test_f32_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
206237
207 try test__floatuntisf(0x0007FB72EA000000, 0x1.FEDCBAp+50);238 try test_f32_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBAp+50);
208 try test__floatuntisf(0x0007FB72EB000000, 0x1.FEDCBAp+50);239 try test_f32_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBAp+50);
209 try test__floatuntisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);240 try test_f32_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
210 try test__floatuntisf(0x0007FB72EC000000, 0x1.FEDCBCp+50);241 try test_f32_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBCp+50);
211 try test__floatuntisf(0x0007FB72E8000001, 0x1.FEDCBAp+50);242 try test_f32_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBAp+50);
212243
213 try test__floatuntisf(0x0007FB72E6000000, 0x1.FEDCBAp+50);244 try test_f32_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCBAp+50);
214 try test__floatuntisf(0x0007FB72E7000000, 0x1.FEDCBAp+50);245 try test_f32_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCBAp+50);
215 try test__floatuntisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);246 try test_f32_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
216 try test__floatuntisf(0x0007FB72E4000001, 0x1.FEDCBAp+50);247 try test_f32_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCBAp+50);
217 try test__floatuntisf(0x0007FB72E4000000, 0x1.FEDCB8p+50);248 try test_f32_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB8p+50);
218249
219 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCB90000000000001), 0x1.FEDCBAp+76);250 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCB90000000000001), 0x1.FEDCBAp+76);
220 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBA0000000000000), 0x1.FEDCBAp+76);251 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBA0000000000000), 0x1.FEDCBAp+76);
221 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBAFFFFFFFFFFFFF), 0x1.FEDCBAp+76);252 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBAFFFFFFFFFFFFF), 0x1.FEDCBAp+76);
222 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBB0000000000000), 0x1.FEDCBCp+76);253 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBB0000000000000), 0x1.FEDCBCp+76);
223 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBB0000000000001), 0x1.FEDCBCp+76);254 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBB0000000000001), 0x1.FEDCBCp+76);
224 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBBFFFFFFFFFFFFF), 0x1.FEDCBCp+76);255 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBBFFFFFFFFFFFFF), 0x1.FEDCBCp+76);
225 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBC0000000000000), 0x1.FEDCBCp+76);256 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBC0000000000000), 0x1.FEDCBCp+76);
226 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBC0000000000001), 0x1.FEDCBCp+76);257 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBC0000000000001), 0x1.FEDCBCp+76);
227 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBD0000000000000), 0x1.FEDCBCp+76);258 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBD0000000000000), 0x1.FEDCBCp+76);
228 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBD0000000000001), 0x1.FEDCBEp+76);259 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBD0000000000001), 0x1.FEDCBEp+76);
229 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBDFFFFFFFFFFFFF), 0x1.FEDCBEp+76);260 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBDFFFFFFFFFFFFF), 0x1.FEDCBEp+76);
230 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBE0000000000000), 0x1.FEDCBEp+76);261 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBE0000000000000), 0x1.FEDCBEp+76);
231262
232 // Test overflow to infinity263 // 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}
235266
236fn test_floateisf(expected: u32, comptime T: type, a: T) !void {267fn test_f32_floatFromInt(expected: u32, comptime T: type, a: T) !void {
237 const int = @typeInfo(T).int;268 const int = @typeInfo(T).int;
238 const r = switch (int.signedness) {269 const r = switch (int.signedness) {
239 .signed => __floateisf,270 .signed => f32_floatFromInt_signed,
240 .unsigned => __floatuneisf,271 .unsigned => f32_floatFromInt_unsigned,
241 }(@ptrCast(&a), int.bits);272 }(@ptrCast(&a));
242 try testing.expect(expected == @as(u32, @bitCast(r)));273 try testing.expect(expected == @as(u32, @bitCast(r)));
243}274}
244275
245test "floateisf" {276test f32_floatFromInt_signed {
246 try test_floateisf(0xFF000000, i256, -1 << 127);277 try test_f32_floatFromInt(0xFF000000, i256, -1 << 127);
247 try test_floateisf(0xFF000000, i256, -math.maxInt(u127));278 try test_f32_floatFromInt(0xFF000000, i256, -math.maxInt(u127));
248 try test_floateisf(0xDF012347, i256, -0x8123468100000000);279 try test_f32_floatFromInt(0xDF012347, i256, -0x8123468100000000);
249 try test_floateisf(0xDF012347, i256, -0x8123468000000001);280 try test_f32_floatFromInt(0xDF012347, i256, -0x8123468000000001);
250 try test_floateisf(0xDF012346, i256, -0x8123468000000000);281 try test_f32_floatFromInt(0xDF012346, i256, -0x8123468000000000);
251 try test_floateisf(0xDF012346, i256, -0x8123458100000000);282 try test_f32_floatFromInt(0xDF012346, i256, -0x8123458100000000);
252 try test_floateisf(0xDF012346, i256, -0x8123458000000001);283 try test_f32_floatFromInt(0xDF012346, i256, -0x8123458000000001);
253 try test_floateisf(0xDF012346, i256, -0x8123458000000000);284 try test_f32_floatFromInt(0xDF012346, i256, -0x8123458000000000);
254 try test_floateisf(0xDF012345, i256, -0x8123456789ABCDEF);285 try test_f32_floatFromInt(0xDF012345, i256, -0x8123456789ABCDEF);
255 try test_floateisf(0xBF800000, i256, -1);286 try test_f32_floatFromInt(0xBF800000, i256, -1);
256 try test_floateisf(0x00000000, i256, 0);287 try test_f32_floatFromInt(0x00000000, i256, 0);
257 try test_floateisf(0x5F012345, i256, 0x8123456789ABCDEF);288 try test_f32_floatFromInt(0x5F012345, i256, 0x8123456789ABCDEF);
258 try test_floateisf(0x5F012346, i256, 0x8123458000000000);289 try test_f32_floatFromInt(0x5F012346, i256, 0x8123458000000000);
259 try test_floateisf(0x5F012346, i256, 0x8123458000000001);290 try test_f32_floatFromInt(0x5F012346, i256, 0x8123458000000001);
260 try test_floateisf(0x5F012346, i256, 0x8123458100000000);291 try test_f32_floatFromInt(0x5F012346, i256, 0x8123458100000000);
261 try test_floateisf(0x5F012346, i256, 0x8123468000000000);292 try test_f32_floatFromInt(0x5F012346, i256, 0x8123468000000000);
262 try test_floateisf(0x5F012347, i256, 0x8123468000000001);293 try test_f32_floatFromInt(0x5F012347, i256, 0x8123468000000001);
263 try test_floateisf(0x5F012347, i256, 0x8123468100000000);294 try test_f32_floatFromInt(0x5F012347, i256, 0x8123468100000000);
264 try test_floateisf(0x7F000000, i256, math.maxInt(u127));295 try test_f32_floatFromInt(0x7F000000, i256, math.maxInt(u127));
265 try test_floateisf(0x7F000000, i256, 1 << 127);296 try test_f32_floatFromInt(0x7F000000, i256, 1 << 127);
266}297}
267298
268test "floatuneisf" {299test f32_floatFromInt_unsigned {
269 try test_floateisf(0x00000000, u256, 0);300 try test_f32_floatFromInt(0x00000000, u256, 0);
270 try test_floateisf(0x5F012345, u256, 0x8123456789ABCDEF);301 try test_f32_floatFromInt(0x5F012345, u256, 0x8123456789ABCDEF);
271 try test_floateisf(0x5F012346, u256, 0x8123458000000000);302 try test_f32_floatFromInt(0x5F012346, u256, 0x8123458000000000);
272 try test_floateisf(0x5F012346, u256, 0x8123458000000001);303 try test_f32_floatFromInt(0x5F012346, u256, 0x8123458000000001);
273 try test_floateisf(0x5F012346, u256, 0x8123458080000000);304 try test_f32_floatFromInt(0x5F012346, u256, 0x8123458080000000);
274 try test_floateisf(0x5F012346, u256, 0x8123468000000000);305 try test_f32_floatFromInt(0x5F012346, u256, 0x8123468000000000);
275 try test_floateisf(0x5F012347, u256, 0x8123468000000001);306 try test_f32_floatFromInt(0x5F012347, u256, 0x8123468000000001);
276 try test_floateisf(0x5F012347, u256, 0x8123468080000000);307 try test_f32_floatFromInt(0x5F012347, u256, 0x8123468080000000);
277 try test_floateisf(0x7F000000, u256, math.maxInt(u127));308 try test_f32_floatFromInt(0x7F000000, u256, math.maxInt(u127));
278 try test_floateisf(0x7F000000, u256, 1 << 127);309 try test_f32_floatFromInt(0x7F000000, u256, 1 << 127);
279 try test_floateisf(0x7F800000, u256, math.maxInt(u256));310 try test_f32_floatFromInt(0x7F800000, u256, math.maxInt(u256));
280}311}
281312
282fn test_one_floatsidf(a: i32, expected: u64) !void {313fn test_f64_floatFromInt_i32(a: i32, expected: u64) !void {
283 const r = __floatsidf(a);314 const r = f64_floatFromInt_i32(a);
284 try std.testing.expect(@as(u64, @bitCast(r)) == expected);315 try std.testing.expect(@as(u64, @bitCast(r)) == expected);
285}316}
286317
287fn test_one_floatunsidf(a: u32, expected: u64) !void {318fn test_f64_floatFromInt_u32(a: u32, expected: u64) !void {
288 const r = __floatunsidf(a);319 const r = f64_floatFromInt_u32(a);
289 try std.testing.expect(@as(u64, @bitCast(r)) == expected);320 try std.testing.expect(@as(u64, @bitCast(r)) == expected);
290}321}
291322
292test "floatsidf" {323test f64_floatFromInt_i32 {
293 try test_one_floatsidf(0, 0x0000000000000000);324 try test_f64_floatFromInt_i32(0, 0x0000000000000000);
294 try test_one_floatsidf(1, 0x3ff0000000000000);325 try test_f64_floatFromInt_i32(1, 0x3ff0000000000000);
295 try test_one_floatsidf(-1, 0xbff0000000000000);326 try test_f64_floatFromInt_i32(-1, 0xbff0000000000000);
296 try test_one_floatsidf(0x7FFFFFFF, 0x41dfffffffc00000);327 try test_f64_floatFromInt_i32(0x7FFFFFFF, 0x41dfffffffc00000);
297 try test_one_floatsidf(@bitCast(@as(u32, @intCast(0x80000000))), 0xc1e0000000000000);328 try test_f64_floatFromInt_i32(@bitCast(@as(u32, @intCast(0x80000000))), 0xc1e0000000000000);
298}329}
299330
300test "floatunsidf" {331test f64_floatFromInt_u32 {
301 try test_one_floatunsidf(0, 0x0000000000000000);332 try test_f64_floatFromInt_u32(0, 0x0000000000000000);
302 try test_one_floatunsidf(1, 0x3ff0000000000000);333 try test_f64_floatFromInt_u32(1, 0x3ff0000000000000);
303 try test_one_floatunsidf(0x7FFFFFFF, 0x41dfffffffc00000);334 try test_f64_floatFromInt_u32(0x7FFFFFFF, 0x41dfffffffc00000);
304 try test_one_floatunsidf(@intCast(0x80000000), 0x41e0000000000000);335 try test_f64_floatFromInt_u32(@intCast(0x80000000), 0x41e0000000000000);
305 try test_one_floatunsidf(@intCast(0xFFFFFFFF), 0x41efffffffe00000);336 try test_f64_floatFromInt_u32(@intCast(0xFFFFFFFF), 0x41efffffffe00000);
306}337}
307338
308fn test__floatdidf(a: i64, expected: f64) !void {339fn test_f64_floatFromInt_i64(a: i64, expected: f64) !void {
309 const r = __floatdidf(a);340 const r = f64_floatFromInt_i64(a);
310 try testing.expect(r == expected);341 try testing.expect(r == expected);
311}342}
312343
313fn test__floatundidf(a: u64, expected: f64) !void {344fn test_f64_floatFromInt_u64(a: u64, expected: f64) !void {
314 const r = __floatundidf(a);345 const r = f64_floatFromInt_u64(a);
315 try testing.expect(r == expected);346 try testing.expect(r == expected);
316}347}
317348
318test "floatdidf" {349test f64_floatFromInt_i64 {
319 try test__floatdidf(0, 0.0);350 try test_f64_floatFromInt_i64(0, 0.0);
320 try test__floatdidf(1, 1.0);351 try test_f64_floatFromInt_i64(1, 1.0);
321 try test__floatdidf(2, 2.0);352 try test_f64_floatFromInt_i64(2, 2.0);
322 try test__floatdidf(20, 20.0);353 try test_f64_floatFromInt_i64(20, 20.0);
323 try test__floatdidf(-1, -1.0);354 try test_f64_floatFromInt_i64(-1, -1.0);
324 try test__floatdidf(-2, -2.0);355 try test_f64_floatFromInt_i64(-2, -2.0);
325 try test__floatdidf(-20, -20.0);356 try test_f64_floatFromInt_i64(-20, -20.0);
326 try test__floatdidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);357 try test_f64_floatFromInt_i64(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
327 try test__floatdidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);358 try test_f64_floatFromInt_i64(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
328 try test__floatdidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);359 try test_f64_floatFromInt_i64(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
329 try test__floatdidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);360 try test_f64_floatFromInt_i64(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
330 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000008000000000))), -0x1.FFFFFEp+62);361 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000008000000000))), -0x1.FFFFFEp+62);
331 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000800))), -0x1.FFFFFFFFFFFFEp+62);362 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000800))), -0x1.FFFFFFFFFFFFEp+62);
332 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000010000000000))), -0x1.FFFFFCp+62);363 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000010000000000))), -0x1.FFFFFCp+62);
333 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000001000))), -0x1.FFFFFFFFFFFFCp+62);364 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000001000))), -0x1.FFFFFFFFFFFFCp+62);
334 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000000))), -0x1.000000p+63);365 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000000))), -0x1.000000p+63);
335 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000001))), -0x1.000000p+63); // 0x8000000000000001366 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000001))), -0x1.000000p+63); // 0x8000000000000001
336 try test__floatdidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);367 try test_f64_floatFromInt_i64(0x0007FB72E8000000, 0x1.FEDCBAp+50);
337 try test__floatdidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);368 try test_f64_floatFromInt_i64(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
338 try test__floatdidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);369 try test_f64_floatFromInt_i64(0x0007FB72EB000000, 0x1.FEDCBACp+50);
339 try test__floatdidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);370 try test_f64_floatFromInt_i64(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
340 try test__floatdidf(0x0007FB72EC000000, 0x1.FEDCBBp+50);371 try test_f64_floatFromInt_i64(0x0007FB72EC000000, 0x1.FEDCBBp+50);
341 try test__floatdidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);372 try test_f64_floatFromInt_i64(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
342 try test__floatdidf(0x0007FB72E6000000, 0x1.FEDCB98p+50);373 try test_f64_floatFromInt_i64(0x0007FB72E6000000, 0x1.FEDCB98p+50);
343 try test__floatdidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);374 try test_f64_floatFromInt_i64(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
344 try test__floatdidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);375 try test_f64_floatFromInt_i64(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
345 try test__floatdidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);376 try test_f64_floatFromInt_i64(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
346 try test__floatdidf(0x0007FB72E4000000, 0x1.FEDCB9p+50);377 try test_f64_floatFromInt_i64(0x0007FB72E4000000, 0x1.FEDCB9p+50);
347 try test__floatdidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);378 try test_f64_floatFromInt_i64(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
348 try test__floatdidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);379 try test_f64_floatFromInt_i64(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
349 try test__floatdidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);380 try test_f64_floatFromInt_i64(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
350 try test__floatdidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);381 try test_f64_floatFromInt_i64(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
351 try test__floatdidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);382 try test_f64_floatFromInt_i64(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
352 try test__floatdidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);383 try test_f64_floatFromInt_i64(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
353 try test__floatdidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);384 try test_f64_floatFromInt_i64(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
354 try test__floatdidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);385 try test_f64_floatFromInt_i64(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
355 try test__floatdidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);386 try test_f64_floatFromInt_i64(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
356 try test__floatdidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);387 try test_f64_floatFromInt_i64(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
357 try test__floatdidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);388 try test_f64_floatFromInt_i64(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
358 try test__floatdidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);389 try test_f64_floatFromInt_i64(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
359 try test__floatdidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);390 try test_f64_floatFromInt_i64(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
360 try test__floatdidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);391 try test_f64_floatFromInt_i64(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
361 try test__floatdidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);392 try test_f64_floatFromInt_i64(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
362}393}
363394
364test "floatundidf" {395test f64_floatFromInt_u64 {
365 try test__floatundidf(0, 0.0);396 try test_f64_floatFromInt_u64(0, 0.0);
366 try test__floatundidf(1, 1.0);397 try test_f64_floatFromInt_u64(1, 1.0);
367 try test__floatundidf(2, 2.0);398 try test_f64_floatFromInt_u64(2, 2.0);
368 try test__floatundidf(20, 20.0);399 try test_f64_floatFromInt_u64(20, 20.0);
369 try test__floatundidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);400 try test_f64_floatFromInt_u64(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
370 try test__floatundidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);401 try test_f64_floatFromInt_u64(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
371 try test__floatundidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);402 try test_f64_floatFromInt_u64(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
372 try test__floatundidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);403 try test_f64_floatFromInt_u64(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
373 try test__floatundidf(0x8000008000000000, 0x1.000001p+63);404 try test_f64_floatFromInt_u64(0x8000008000000000, 0x1.000001p+63);
374 try test__floatundidf(0x8000000000000800, 0x1.0000000000001p+63);405 try test_f64_floatFromInt_u64(0x8000000000000800, 0x1.0000000000001p+63);
375 try test__floatundidf(0x8000010000000000, 0x1.000002p+63);406 try test_f64_floatFromInt_u64(0x8000010000000000, 0x1.000002p+63);
376 try test__floatundidf(0x8000000000001000, 0x1.0000000000002p+63);407 try test_f64_floatFromInt_u64(0x8000000000001000, 0x1.0000000000002p+63);
377 try test__floatundidf(0x8000000000000000, 0x1p+63);408 try test_f64_floatFromInt_u64(0x8000000000000000, 0x1p+63);
378 try test__floatundidf(0x8000000000000001, 0x1p+63);409 try test_f64_floatFromInt_u64(0x8000000000000001, 0x1p+63);
379 try test__floatundidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);410 try test_f64_floatFromInt_u64(0x0007FB72E8000000, 0x1.FEDCBAp+50);
380 try test__floatundidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);411 try test_f64_floatFromInt_u64(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
381 try test__floatundidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);412 try test_f64_floatFromInt_u64(0x0007FB72EB000000, 0x1.FEDCBACp+50);
382 try test__floatundidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);413 try test_f64_floatFromInt_u64(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
383 try test__floatundidf(0x0007FB72EC000000, 0x1.FEDCBBp+50);414 try test_f64_floatFromInt_u64(0x0007FB72EC000000, 0x1.FEDCBBp+50);
384 try test__floatundidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);415 try test_f64_floatFromInt_u64(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
385 try test__floatundidf(0x0007FB72E6000000, 0x1.FEDCB98p+50);416 try test_f64_floatFromInt_u64(0x0007FB72E6000000, 0x1.FEDCB98p+50);
386 try test__floatundidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);417 try test_f64_floatFromInt_u64(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
387 try test__floatundidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);418 try test_f64_floatFromInt_u64(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
388 try test__floatundidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);419 try test_f64_floatFromInt_u64(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
389 try test__floatundidf(0x0007FB72E4000000, 0x1.FEDCB9p+50);420 try test_f64_floatFromInt_u64(0x0007FB72E4000000, 0x1.FEDCB9p+50);
390 try test__floatundidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);421 try test_f64_floatFromInt_u64(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
391 try test__floatundidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);422 try test_f64_floatFromInt_u64(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
392 try test__floatundidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);423 try test_f64_floatFromInt_u64(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
393 try test__floatundidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);424 try test_f64_floatFromInt_u64(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
394 try test__floatundidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);425 try test_f64_floatFromInt_u64(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
395 try test__floatundidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);426 try test_f64_floatFromInt_u64(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
396 try test__floatundidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);427 try test_f64_floatFromInt_u64(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
397 try test__floatundidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);428 try test_f64_floatFromInt_u64(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
398 try test__floatundidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);429 try test_f64_floatFromInt_u64(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
399 try test__floatundidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);430 try test_f64_floatFromInt_u64(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
400 try test__floatundidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);431 try test_f64_floatFromInt_u64(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
401 try test__floatundidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);432 try test_f64_floatFromInt_u64(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
402 try test__floatundidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);433 try test_f64_floatFromInt_u64(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
403 try test__floatundidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);434 try test_f64_floatFromInt_u64(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
404 try test__floatundidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);435 try test_f64_floatFromInt_u64(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
405}436}
406437
407fn test__floattidf(a: i128, expected: f64) !void {438fn test_f64_floatFromInt_i128(a: i128, expected: f64) !void {
408 const x = __floattidf(a);439 const x = f64_floatFromInt_i128(a);
409 try testing.expect(x == expected);440 try testing.expect(x == expected);
410}441}
411442
412fn test__floatuntidf(a: u128, expected: f64) !void {443fn test_f64_floatFromInt_u128(a: u128, expected: f64) !void {
413 const x = __floatuntidf(a);444 const x = f64_floatFromInt_u128(a);
414 try testing.expect(x == expected);445 try testing.expect(x == expected);
415}446}
416447
417test "floattidf" {448test f64_floatFromInt_i128 {
418 try test__floattidf(0, 0.0);449 try test_f64_floatFromInt_i128(0, 0.0);
419450
420 try test__floattidf(1, 1.0);451 try test_f64_floatFromInt_i128(1, 1.0);
421 try test__floattidf(2, 2.0);452 try test_f64_floatFromInt_i128(2, 2.0);
422 try test__floattidf(20, 20.0);453 try test_f64_floatFromInt_i128(20, 20.0);
423 try test__floattidf(-1, -1.0);454 try test_f64_floatFromInt_i128(-1, -1.0);
424 try test__floattidf(-2, -2.0);455 try test_f64_floatFromInt_i128(-2, -2.0);
425 try test__floattidf(-20, -20.0);456 try test_f64_floatFromInt_i128(-20, -20.0);
426457
427 try test__floattidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);458 try test_f64_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
428 try test__floattidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);459 try test_f64_floatFromInt_i128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
429 try test__floattidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);460 try test_f64_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
430 try test__floattidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);461 try test_f64_floatFromInt_i128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
431462
432 try test__floattidf(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126);463 try test_f64_floatFromInt_i128(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126);
433 try test__floattidf(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126);464 try test_f64_floatFromInt_i128(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126);
434 try test__floattidf(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126);465 try test_f64_floatFromInt_i128(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126);
435 try test__floattidf(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126);466 try test_f64_floatFromInt_i128(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126);
436467
437 try test__floattidf(make_ti(0x8000000000000000, 0), -0x1.000000p+127);468 try test_f64_floatFromInt_i128(make_ti(0x8000000000000000, 0), -0x1.000000p+127);
438 try test__floattidf(make_ti(0x8000000000000001, 0), -0x1.000000p+127);469 try test_f64_floatFromInt_i128(make_ti(0x8000000000000001, 0), -0x1.000000p+127);
439470
440 try test__floattidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);471 try test_f64_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
441472
442 try test__floattidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);473 try test_f64_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
443 try test__floattidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);474 try test_f64_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBACp+50);
444 try test__floattidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);475 try test_f64_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
445 try test__floattidf(0x0007FB72EC000000, 0x1.FEDCBBp+50);476 try test_f64_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBBp+50);
446 try test__floattidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);477 try test_f64_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
447478
448 try test__floattidf(0x0007FB72E6000000, 0x1.FEDCB98p+50);479 try test_f64_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCB98p+50);
449 try test__floattidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);480 try test_f64_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
450 try test__floattidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);481 try test_f64_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
451 try test__floattidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);482 try test_f64_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
452 try test__floattidf(0x0007FB72E4000000, 0x1.FEDCB9p+50);483 try test_f64_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB9p+50);
453484
454 try test__floattidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);485 try test_f64_floatFromInt_i128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
455 try test__floattidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);486 try test_f64_floatFromInt_i128(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
456 try test__floattidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);487 try test_f64_floatFromInt_i128(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
457 try test__floattidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);488 try test_f64_floatFromInt_i128(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
458 try test__floattidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);489 try test_f64_floatFromInt_i128(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
459 try test__floattidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);490 try test_f64_floatFromInt_i128(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
460 try test__floattidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);491 try test_f64_floatFromInt_i128(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
461 try test__floattidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);492 try test_f64_floatFromInt_i128(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
462 try test__floattidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);493 try test_f64_floatFromInt_i128(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
463 try test__floattidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);494 try test_f64_floatFromInt_i128(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
464 try test__floattidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);495 try test_f64_floatFromInt_i128(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
465 try test__floattidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);496 try test_f64_floatFromInt_i128(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
466 try test__floattidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);497 try test_f64_floatFromInt_i128(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
467 try test__floattidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);498 try test_f64_floatFromInt_i128(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
468 try test__floattidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);499 try test_f64_floatFromInt_i128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
469500
470 try test__floattidf(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);501 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
471 try test__floattidf(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121);502 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121);
472 try test__floattidf(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121);503 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121);
473 try test__floattidf(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121);504 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121);
474 try test__floattidf(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121);505 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121);
475 try test__floattidf(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121);506 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121);
476 try test__floattidf(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121);507 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121);
477 try test__floattidf(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121);508 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121);
478 try test__floattidf(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121);509 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121);
479 try test__floattidf(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121);510 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121);
480 try test__floattidf(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121);511 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121);
481 try test__floattidf(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121);512 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121);
482 try test__floattidf(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121);513 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121);
483 try test__floattidf(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121);514 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121);
484 try test__floattidf(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);515 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
485}516}
486517
487test "floatuntidf" {518test f64_floatFromInt_u128 {
488 try test__floatuntidf(0, 0.0);519 try test_f64_floatFromInt_u128(0, 0.0);
489520
490 try test__floatuntidf(1, 1.0);521 try test_f64_floatFromInt_u128(1, 1.0);
491 try test__floatuntidf(2, 2.0);522 try test_f64_floatFromInt_u128(2, 2.0);
492 try test__floatuntidf(20, 20.0);523 try test_f64_floatFromInt_u128(20, 20.0);
493524
494 try test__floatuntidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);525 try test_f64_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
495 try test__floatuntidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);526 try test_f64_floatFromInt_u128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
496 try test__floatuntidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);527 try test_f64_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
497 try test__floatuntidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);528 try test_f64_floatFromInt_u128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
498529
499 try test__floatuntidf(make_uti(0x8000008000000000, 0), 0x1.000001p+127);530 try test_f64_floatFromInt_u128(make_uti(0x8000008000000000, 0), 0x1.000001p+127);
500 try test__floatuntidf(make_uti(0x8000000000000800, 0), 0x1.0000000000001p+127);531 try test_f64_floatFromInt_u128(make_uti(0x8000000000000800, 0), 0x1.0000000000001p+127);
501 try test__floatuntidf(make_uti(0x8000010000000000, 0), 0x1.000002p+127);532 try test_f64_floatFromInt_u128(make_uti(0x8000010000000000, 0), 0x1.000002p+127);
502 try test__floatuntidf(make_uti(0x8000000000001000, 0), 0x1.0000000000002p+127);533 try test_f64_floatFromInt_u128(make_uti(0x8000000000001000, 0), 0x1.0000000000002p+127);
503534
504 try test__floatuntidf(make_uti(0x8000000000000000, 0), 0x1.000000p+127);535 try test_f64_floatFromInt_u128(make_uti(0x8000000000000000, 0), 0x1.000000p+127);
505 try test__floatuntidf(make_uti(0x8000000000000001, 0), 0x1.0000000000000002p+127);536 try test_f64_floatFromInt_u128(make_uti(0x8000000000000001, 0), 0x1.0000000000000002p+127);
506537
507 try test__floatuntidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);538 try test_f64_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
508539
509 try test__floatuntidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);540 try test_f64_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
510 try test__floatuntidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);541 try test_f64_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50);
511 try test__floatuntidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);542 try test_f64_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
512 try test__floatuntidf(0x0007FB72EC000000, 0x1.FEDCBBp+50);543 try test_f64_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50);
513 try test__floatuntidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);544 try test_f64_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
514545
515 try test__floatuntidf(0x0007FB72E6000000, 0x1.FEDCB98p+50);546 try test_f64_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50);
516 try test__floatuntidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);547 try test_f64_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
517 try test__floatuntidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);548 try test_f64_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
518 try test__floatuntidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);549 try test_f64_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
519 try test__floatuntidf(0x0007FB72E4000000, 0x1.FEDCB9p+50);550 try test_f64_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50);
520551
521 try test__floatuntidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);552 try test_f64_floatFromInt_u128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
522 try test__floatuntidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);553 try test_f64_floatFromInt_u128(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
523 try test__floatuntidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);554 try test_f64_floatFromInt_u128(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
524 try test__floatuntidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);555 try test_f64_floatFromInt_u128(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
525 try test__floatuntidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);556 try test_f64_floatFromInt_u128(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
526 try test__floatuntidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);557 try test_f64_floatFromInt_u128(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
527 try test__floatuntidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);558 try test_f64_floatFromInt_u128(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
528 try test__floatuntidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);559 try test_f64_floatFromInt_u128(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
529 try test__floatuntidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);560 try test_f64_floatFromInt_u128(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
530 try test__floatuntidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);561 try test_f64_floatFromInt_u128(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
531 try test__floatuntidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);562 try test_f64_floatFromInt_u128(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
532 try test__floatuntidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);563 try test_f64_floatFromInt_u128(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
533 try test__floatuntidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);564 try test_f64_floatFromInt_u128(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
534 try test__floatuntidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);565 try test_f64_floatFromInt_u128(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
535 try test__floatuntidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);566 try test_f64_floatFromInt_u128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
536567
537 try test__floatuntidf(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);568 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
538 try test__floatuntidf(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121);569 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121);
539 try test__floatuntidf(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121);570 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121);
540 try test__floatuntidf(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121);571 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121);
541 try test__floatuntidf(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121);572 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121);
542 try test__floatuntidf(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121);573 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121);
543 try test__floatuntidf(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121);574 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121);
544 try test__floatuntidf(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121);575 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121);
545 try test__floatuntidf(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121);576 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121);
546 try test__floatuntidf(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121);577 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121);
547 try test__floatuntidf(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121);578 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121);
548 try test__floatuntidf(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121);579 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121);
549 try test__floatuntidf(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121);580 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121);
550 try test__floatuntidf(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121);581 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121);
551 try test__floatuntidf(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);582 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
552}583}
553584
554fn test__floatsitf(a: i32, expected: u128) !void {585fn test_f128_floatFromInt_i32(a: i32, expected: u128) !void {
555 const r = __floatsitf(a);586 const r = f128_floatFromInt_i32(a);
556 try std.testing.expect(@as(u128, @bitCast(r)) == expected);587 try std.testing.expect(@as(u128, @bitCast(r)) == expected);
557}588}
558589
559test "floatsitf" {590fn test_f128_floatFromInt_u32(a: u32, expected_hi: u64, expected_lo: u64) !void {
560 try test__floatsitf(0, 0);591 const x = f128_floatFromInt_u32(a);
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
568fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void {
569 const x = __floatunsitf(a);
570592
571 const x_repr: u128 = @bitCast(x);593 const x_repr: u128 = @bitCast(x);
572 const x_hi: u64 = @intCast(x_repr >> 64);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,24 +603,32 @@ fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void {
581 return;603 return;
582 }604 }
583 }605 }
606 return error.TestFailure;
607}
584608
585 @panic("__floatunsitf test failure");609test 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}
587617
588test "floatunsitf" {618test f128_floatFromInt_u32 {
589 try test__floatunsitf(0x7fffffff, 0x401dfffffffc0000, 0x0);619 try test_f128_floatFromInt_u32(0x7fffffff, 0x401dfffffffc0000, 0x0);
590 try test__floatunsitf(0, 0x0, 0x0);620 try test_f128_floatFromInt_u32(0, 0x0, 0x0);
591 try test__floatunsitf(0xffffffff, 0x401efffffffe0000, 0x0);621 try test_f128_floatFromInt_u32(0xffffffff, 0x401efffffffe0000, 0x0);
592 try test__floatunsitf(0x12345678, 0x401b234567800000, 0x0);622 try test_f128_floatFromInt_u32(0x12345678, 0x401b234567800000, 0x0);
593}623}
594624
595fn test__floatditf(a: i64, expected: f128) !void {625fn test_f128_floatFromInt_i64(a: i64, expected: f128) !void {
596 const x = __floatditf(a);626 const x = f128_floatFromInt_i64(a);
597 try testing.expect(x == expected);627 try testing.expect(x == expected);
598}628}
599629
600fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void {630fn test_f128_floatFromInt_u64(a: u64, expected_hi: u64, expected_lo: u64) !void {
601 const x = __floatunditf(a);631 const x = f128_floatFromInt_u64(a);
602632
603 const x_repr: u128 = @bitCast(x);633 const x_repr: u128 = @bitCast(x);
604 const x_hi: u64 = @intCast(x_repr >> 64);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,208 +643,207 @@ fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void {
613 return;643 return;
614 }644 }
615 }645 }
616646 return error.TestFailure;
617 @panic("__floatunditf test failure");647}
618}648
619649test f128_floatFromInt_i64 {
620test "floatditf" {650 try test_f128_floatFromInt_i64(0x7fffffffffffffff, make_tf(0x403dffffffffffff, 0xfffc000000000000));
621 try test__floatditf(0x7fffffffffffffff, make_tf(0x403dffffffffffff, 0xfffc000000000000));651 try test_f128_floatFromInt_i64(0x123456789abcdef1, make_tf(0x403b23456789abcd, 0xef10000000000000));
622 try test__floatditf(0x123456789abcdef1, make_tf(0x403b23456789abcd, 0xef10000000000000));652 try test_f128_floatFromInt_i64(0x2, make_tf(0x4000000000000000, 0x0));
623 try test__floatditf(0x2, make_tf(0x4000000000000000, 0x0));653 try test_f128_floatFromInt_i64(0x1, make_tf(0x3fff000000000000, 0x0));
624 try test__floatditf(0x1, make_tf(0x3fff000000000000, 0x0));654 try test_f128_floatFromInt_i64(0x0, make_tf(0x0, 0x0));
625 try test__floatditf(0x0, make_tf(0x0, 0x0));655 try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0xffffffffffffffff)), make_tf(0xbfff000000000000, 0x0));
626 try test__floatditf(@bitCast(@as(u64, 0xffffffffffffffff)), make_tf(0xbfff000000000000, 0x0));656 try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0xfffffffffffffffe)), make_tf(0xc000000000000000, 0x0));
627 try test__floatditf(@bitCast(@as(u64, 0xfffffffffffffffe)), make_tf(0xc000000000000000, 0x0));657 try test_f128_floatFromInt_i64(-0x123456789abcdef1, make_tf(0xc03b23456789abcd, 0xef10000000000000));
628 try test__floatditf(-0x123456789abcdef1, make_tf(0xc03b23456789abcd, 0xef10000000000000));658 try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000000)), make_tf(0xc03e000000000000, 0x0));
629 try test__floatditf(@bitCast(@as(u64, 0x8000000000000000)), make_tf(0xc03e000000000000, 0x0));659}
630}660
631661test f128_floatFromInt_u64 {
632test "floatunditf" {662 try test_f128_floatFromInt_u64(0xffffffffffffffff, 0x403effffffffffff, 0xfffe000000000000);
633 try test__floatunditf(0xffffffffffffffff, 0x403effffffffffff, 0xfffe000000000000);663 try test_f128_floatFromInt_u64(0xfffffffffffffffe, 0x403effffffffffff, 0xfffc000000000000);
634 try test__floatunditf(0xfffffffffffffffe, 0x403effffffffffff, 0xfffc000000000000);664 try test_f128_floatFromInt_u64(0x8000000000000000, 0x403e000000000000, 0x0);
635 try test__floatunditf(0x8000000000000000, 0x403e000000000000, 0x0);665 try test_f128_floatFromInt_u64(0x7fffffffffffffff, 0x403dffffffffffff, 0xfffc000000000000);
636 try test__floatunditf(0x7fffffffffffffff, 0x403dffffffffffff, 0xfffc000000000000);666 try test_f128_floatFromInt_u64(0x123456789abcdef1, 0x403b23456789abcd, 0xef10000000000000);
637 try test__floatunditf(0x123456789abcdef1, 0x403b23456789abcd, 0xef10000000000000);667 try test_f128_floatFromInt_u64(0x2, 0x4000000000000000, 0x0);
638 try test__floatunditf(0x2, 0x4000000000000000, 0x0);668 try test_f128_floatFromInt_u64(0x1, 0x3fff000000000000, 0x0);
639 try test__floatunditf(0x1, 0x3fff000000000000, 0x0);669 try test_f128_floatFromInt_u64(0x0, 0x0, 0x0);
640 try test__floatunditf(0x0, 0x0, 0x0);670}
641}671
642672fn test_f128_floatFromInt_i128(a: i128, expected: f128) !void {
643fn test__floattitf(a: i128, expected: f128) !void {673 const x = f128_floatFromInt_i128(a);
644 const x = __floattitf(a);
645 try testing.expect(x == expected);674 try testing.expect(x == expected);
646}675}
647676
648fn test__floatuntitf(a: u128, expected: f128) !void {677fn test_f128_floatFromInt_u128(a: u128, expected: f128) !void {
649 const x = __floatuntitf(a);678 const x = f128_floatFromInt_u128(a);
650 try testing.expect(x == expected);679 try testing.expect(x == expected);
651}680}
652681
653test "floattitf" {682test f128_floatFromInt_i128 {
654 try test__floattitf(0, 0.0);683 try test_f128_floatFromInt_i128(0, 0.0);
655684
656 try test__floattitf(1, 1.0);685 try test_f128_floatFromInt_i128(1, 1.0);
657 try test__floattitf(2, 2.0);686 try test_f128_floatFromInt_i128(2, 2.0);
658 try test__floattitf(20, 20.0);687 try test_f128_floatFromInt_i128(20, 20.0);
659 try test__floattitf(-1, -1.0);688 try test_f128_floatFromInt_i128(-1, -1.0);
660 try test__floattitf(-2, -2.0);689 try test_f128_floatFromInt_i128(-2, -2.0);
661 try test__floattitf(-20, -20.0);690 try test_f128_floatFromInt_i128(-20, -20.0);
662691
663 try test__floattitf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);692 try test_f128_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
664 try test__floattitf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);693 try test_f128_floatFromInt_i128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
665 try test__floattitf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);694 try test_f128_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
666 try test__floattitf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);695 try test_f128_floatFromInt_i128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
667696
668 try test__floattitf(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126);697 try test_f128_floatFromInt_i128(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126);
669 try test__floattitf(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126);698 try test_f128_floatFromInt_i128(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126);
670 try test__floattitf(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126);699 try test_f128_floatFromInt_i128(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126);
671 try test__floattitf(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126);700 try test_f128_floatFromInt_i128(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126);
672701
673 try test__floattitf(make_ti(0x8000000000000000, 0), -0x1.000000p+127);702 try test_f128_floatFromInt_i128(make_ti(0x8000000000000000, 0), -0x1.000000p+127);
674 try test__floattitf(make_ti(0x8000000000000001, 0), -0x1.FFFFFFFFFFFFFFFCp+126);703 try test_f128_floatFromInt_i128(make_ti(0x8000000000000001, 0), -0x1.FFFFFFFFFFFFFFFCp+126);
675704
676 try test__floattitf(0x0007FB72E8000000, 0x1.FEDCBAp+50);705 try test_f128_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
677706
678 try test__floattitf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);707 try test_f128_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
679 try test__floattitf(0x0007FB72EB000000, 0x1.FEDCBACp+50);708 try test_f128_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBACp+50);
680 try test__floattitf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);709 try test_f128_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
681 try test__floattitf(0x0007FB72EC000000, 0x1.FEDCBBp+50);710 try test_f128_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBBp+50);
682 try test__floattitf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);711 try test_f128_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
683712
684 try test__floattitf(0x0007FB72E6000000, 0x1.FEDCB98p+50);713 try test_f128_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCB98p+50);
685 try test__floattitf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);714 try test_f128_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
686 try test__floattitf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);715 try test_f128_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
687 try test__floattitf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);716 try test_f128_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
688 try test__floattitf(0x0007FB72E4000000, 0x1.FEDCB9p+50);717 try test_f128_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB9p+50);
689718
690 try test__floattitf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);719 try test_f128_floatFromInt_i128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
691 try test__floattitf(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57);720 try test_f128_floatFromInt_i128(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57);
692 try test__floattitf(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57);721 try test_f128_floatFromInt_i128(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57);
693 try test__floattitf(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57);722 try test_f128_floatFromInt_i128(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57);
694 try test__floattitf(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57);723 try test_f128_floatFromInt_i128(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57);
695 try test__floattitf(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57);724 try test_f128_floatFromInt_i128(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57);
696 try test__floattitf(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57);725 try test_f128_floatFromInt_i128(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57);
697 try test__floattitf(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57);726 try test_f128_floatFromInt_i128(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57);
698 try test__floattitf(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57);727 try test_f128_floatFromInt_i128(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57);
699 try test__floattitf(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57);728 try test_f128_floatFromInt_i128(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57);
700 try test__floattitf(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57);729 try test_f128_floatFromInt_i128(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57);
701 try test__floattitf(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57);730 try test_f128_floatFromInt_i128(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57);
702 try test__floattitf(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57);731 try test_f128_floatFromInt_i128(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57);
703 try test__floattitf(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57);732 try test_f128_floatFromInt_i128(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57);
704 try test__floattitf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);733 try test_f128_floatFromInt_i128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
705734
706 try test__floattitf(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);735 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
707 try test__floattitf(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121);736 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121);
708 try test__floattitf(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121);737 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121);
709 try test__floattitf(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121);738 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121);
710 try test__floattitf(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121);739 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121);
711 try test__floattitf(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121);740 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121);
712 try test__floattitf(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121);741 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121);
713 try test__floattitf(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121);742 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121);
714 try test__floattitf(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121);743 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121);
715 try test__floattitf(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121);744 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121);
716 try test__floattitf(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121);745 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121);
717 try test__floattitf(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121);746 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121);
718 try test__floattitf(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121);747 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121);
719 try test__floattitf(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121);748 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121);
720 try test__floattitf(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);749 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
721750
722 try test__floattitf(make_ti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63);751 try test_f128_floatFromInt_i128(make_ti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63);
723752
724 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124);753 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124);
725 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124);754 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124);
726 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124);755 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124);
727 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124);756 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124);
728 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124);757 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124);
729 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124);758 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124);
730 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124);759 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124);
731 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124);760 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124);
732 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124);761 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124);
733}762}
734763
735test "floatuntitf" {764test f128_floatFromInt_u128 {
736 try test__floatuntitf(0, 0.0);765 try test_f128_floatFromInt_u128(0, 0.0);
737766
738 try test__floatuntitf(1, 1.0);767 try test_f128_floatFromInt_u128(1, 1.0);
739 try test__floatuntitf(2, 2.0);768 try test_f128_floatFromInt_u128(2, 2.0);
740 try test__floatuntitf(20, 20.0);769 try test_f128_floatFromInt_u128(20, 20.0);
741770
742 try test__floatuntitf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);771 try test_f128_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
743 try test__floatuntitf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);772 try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
744 try test__floatuntitf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);773 try test_f128_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
745 try test__floatuntitf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);774 try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
746 try test__floatuntitf(0x7FFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFEp+59);775 try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFEp+59);
747 try test__floatuntitf(0xFFFFFFFFFFFFFFFE, 0xF.FFFFFFFFFFFFFFEp+60);776 try test_f128_floatFromInt_u128(0xFFFFFFFFFFFFFFFE, 0xF.FFFFFFFFFFFFFFEp+60);
748 try test__floatuntitf(0xFFFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFFp+60);777 try test_f128_floatFromInt_u128(0xFFFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFFp+60);
749778
750 try test__floatuntitf(0x8000008000000000, 0x8.000008p+60);779 try test_f128_floatFromInt_u128(0x8000008000000000, 0x8.000008p+60);
751 try test__floatuntitf(0x8000000000000800, 0x8.0000000000008p+60);780 try test_f128_floatFromInt_u128(0x8000000000000800, 0x8.0000000000008p+60);
752 try test__floatuntitf(0x8000010000000000, 0x8.00001p+60);781 try test_f128_floatFromInt_u128(0x8000010000000000, 0x8.00001p+60);
753 try test__floatuntitf(0x8000000000001000, 0x8.000000000001p+60);782 try test_f128_floatFromInt_u128(0x8000000000001000, 0x8.000000000001p+60);
754783
755 try test__floatuntitf(0x8000000000000000, 0x8p+60);784 try test_f128_floatFromInt_u128(0x8000000000000000, 0x8p+60);
756 try test__floatuntitf(0x8000000000000001, 0x8.000000000000001p+60);785 try test_f128_floatFromInt_u128(0x8000000000000001, 0x8.000000000000001p+60);
757786
758 try test__floatuntitf(0x0007FB72E8000000, 0x1.FEDCBAp+50);787 try test_f128_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
759788
760 try test__floatuntitf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);789 try test_f128_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
761 try test__floatuntitf(0x0007FB72EB000000, 0x1.FEDCBACp+50);790 try test_f128_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50);
762 try test__floatuntitf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);791 try test_f128_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
763 try test__floatuntitf(0x0007FB72EC000000, 0x1.FEDCBBp+50);792 try test_f128_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50);
764 try test__floatuntitf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);793 try test_f128_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
765794
766 try test__floatuntitf(0x0007FB72E6000000, 0x1.FEDCB98p+50);795 try test_f128_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50);
767 try test__floatuntitf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);796 try test_f128_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
768 try test__floatuntitf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);797 try test_f128_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
769 try test__floatuntitf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);798 try test_f128_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
770 try test__floatuntitf(0x0007FB72E4000000, 0x1.FEDCB9p+50);799 try test_f128_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50);
771800
772 try test__floatuntitf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);801 try test_f128_floatFromInt_u128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
773 try test__floatuntitf(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57);802 try test_f128_floatFromInt_u128(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57);
774 try test__floatuntitf(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57);803 try test_f128_floatFromInt_u128(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57);
775 try test__floatuntitf(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57);804 try test_f128_floatFromInt_u128(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57);
776 try test__floatuntitf(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57);805 try test_f128_floatFromInt_u128(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57);
777 try test__floatuntitf(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57);806 try test_f128_floatFromInt_u128(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57);
778 try test__floatuntitf(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57);807 try test_f128_floatFromInt_u128(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57);
779 try test__floatuntitf(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57);808 try test_f128_floatFromInt_u128(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57);
780 try test__floatuntitf(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57);809 try test_f128_floatFromInt_u128(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57);
781 try test__floatuntitf(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57);810 try test_f128_floatFromInt_u128(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57);
782 try test__floatuntitf(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57);811 try test_f128_floatFromInt_u128(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57);
783 try test__floatuntitf(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57);812 try test_f128_floatFromInt_u128(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57);
784 try test__floatuntitf(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57);813 try test_f128_floatFromInt_u128(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57);
785 try test__floatuntitf(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57);814 try test_f128_floatFromInt_u128(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57);
786 try test__floatuntitf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);815 try test_f128_floatFromInt_u128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
787816
788 try test__floatuntitf(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);817 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
789 try test__floatuntitf(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121);818 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121);
790 try test__floatuntitf(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121);819 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121);
791 try test__floatuntitf(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121);820 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121);
792 try test__floatuntitf(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121);821 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121);
793 try test__floatuntitf(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121);822 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121);
794 try test__floatuntitf(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121);823 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121);
795 try test__floatuntitf(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121);824 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121);
796 try test__floatuntitf(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121);825 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121);
797 try test__floatuntitf(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121);826 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121);
798 try test__floatuntitf(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121);827 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121);
799 try test__floatuntitf(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121);828 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121);
800 try test__floatuntitf(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121);829 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121);
801 try test__floatuntitf(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121);830 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121);
802 try test__floatuntitf(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);831 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
803832
804 try test__floatuntitf(make_uti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63);833 try test_f128_floatFromInt_u128(make_uti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63);
805834
806 try test__floatuntitf(make_uti(0xFFFFFFFFFFFFFFFF, 0x0000000000000000), 0x1.FFFFFFFFFFFFFFFEp+127);835 try test_f128_floatFromInt_u128(make_uti(0xFFFFFFFFFFFFFFFF, 0x0000000000000000), 0x1.FFFFFFFFFFFFFFFEp+127);
807 try test__floatuntitf(make_uti(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0x1.0000000000000000p+128);836 try test_f128_floatFromInt_u128(make_uti(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0x1.0000000000000000p+128);
808837
809 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124);838 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124);
810 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124);839 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124);
811 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124);840 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124);
812 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124);841 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124);
813 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124);842 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124);
814 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124);843 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124);
815 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124);844 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124);
816 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124);845 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124);
817 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124);846 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124);
818}847}
819848
820fn make_ti(high: u64, low: u64) i128 {849fn make_ti(high: u64, low: u64) i128 {
...@@ -838,45 +867,40 @@ fn make_tf(high: u64, low: u64) f128 {...@@ -838,45 +867,40 @@ fn make_tf(high: u64, low: u64) f128 {
838 return @bitCast(result);867 return @bitCast(result);
839}868}
840869
841test "conversion to f16" {870test f16_floatFromInt_u32 {
842 try testing.expect(__floatunsihf(@as(u32, 0)) == 0.0);871 try testing.expect(f16_floatFromInt_u32(0) == 0.0);
843 try testing.expect(__floatunsihf(@as(u32, 1)) == 1.0);872 try testing.expect(f16_floatFromInt_u32(1) == 1.0);
844 try testing.expect(__floatunsihf(@as(u32, 65504)) == 65504);873 try testing.expect(f16_floatFromInt_u32(65504) == 65504);
845 try testing.expect(__floatunsihf(@as(u32, 65504 + (1 << 4))) == math.inf(f16));874 try testing.expect(f16_floatFromInt_u32(65504 + (1 << 4)) == math.inf(f16));
846}875}
847876
848test "conversion to f32" {877test f80_floatFromInt_u32 {
849 try testing.expect(__floatunsisf(@as(u32, 0)) == 0.0);878 try testing.expect(f80_floatFromInt_u32(0) == 0.0);
850 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u32))) != 1.0);879 try testing.expect(f80_floatFromInt_u32(1) == 1.0);
851 try testing.expect(__floatsisf(@as(i32, math.minInt(i32))) != 1.0);880 try testing.expect(f80_floatFromInt_u32(math.maxInt(u24) + 0) == math.maxInt(u24));
852 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24))) == math.maxInt(u24));881}
853 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 1) == math.maxInt(u24) + 1); // 0x100_0000 - Exact882
854 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 2) == math.maxInt(u24) + 1); // 0x100_0001 - Tie: Rounds down to even883test f80_floatFromInt_u64 {
855 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 3) == math.maxInt(u24) + 3); // 0x100_0002 - Exact884 try testing.expect(f80_floatFromInt_u64(math.maxInt(u64) + 0) == math.maxInt(u64) + 0);
856 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 4) == math.maxInt(u24) + 5); // 0x100_0003 - Tie: Rounds up to even885}
857 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 5) == math.maxInt(u24) + 5); // 0x100_0004 - Exact886
858}887test f80_floatFromInt_i128 {
859888 try testing.expect(f80_floatFromInt_i128(-12) == -12);
860test "conversion to f80" {889}
861 const floatFromInt = @import("./float_from_int.zig").floatFromInt;890
862891test f80_floatFromInt_u128 {
863 try testing.expect(floatFromInt(f80, @as(i80, -12)) == -12);892 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 1) == math.maxInt(u64) + 1);
864 try testing.expect(@as(u80, @intFromFloat(floatFromInt(f80, @as(u64, math.maxInt(u64)) + 0))) == math.maxInt(u64) + 0);893
865 try testing.expect(@as(u80, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1))) == math.maxInt(u64) + 1);894 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 0) == math.maxInt(u64));
866895 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 1) == math.maxInt(u64) + 1); // Exact
867 try testing.expect(floatFromInt(f80, @as(u32, 0)) == 0.0);896 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 2) == math.maxInt(u64) + 1); // Rounds down
868 try testing.expect(floatFromInt(f80, @as(u32, 1)) == 1.0);897 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 3) == math.maxInt(u64) + 3); // Tie - Exact
869 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u32, math.maxInt(u24)) + 0))) == math.maxInt(u24));898 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 4) == math.maxInt(u64) + 5); // Rounds up
870 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 0))) == math.maxInt(u64));899
871 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1))) == math.maxInt(u64) + 1); // Exact900 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 0) == math.maxInt(u65) + 1); // Rounds up
872 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 2))) == math.maxInt(u64) + 1); // Rounds down901 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 1) == math.maxInt(u65) + 1); // Exact
873 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 3))) == math.maxInt(u64) + 3); // Tie - Exact902 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 2) == math.maxInt(u65) + 1); // Rounds down
874 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 4))) == math.maxInt(u64) + 5); // Rounds up903 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 3) == math.maxInt(u65) + 1); // Tie - Rounds down
875904 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 4) == math.maxInt(u65) + 5); // Rounds up
876 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 0))) == math.maxInt(u65) + 1); // Rounds up905 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 5) == math.maxInt(u65) + 5); // Exact
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
882}906}
lib/compiler_rt/floatdidf.zig deleted-23
...@@ -1,23 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const floatFromInt = @import("./float_from_int.zig").floatFromInt;
5
6comptime {
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
17pub fn __floatdidf(a: i64) callconv(.c) f64 {
18 return floatFromInt(f64, a);
19}
20
21fn __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 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3
4comptime {
5 symbol(&__floatdihf, "__floatdihf");
6}
7
8fn __floatdihf(a: i64) callconv(.c) f16 {
9 return floatFromInt(f16, a);
10}
lib/compiler_rt/floatdisf.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
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
16pub fn __floatdisf(a: i64) callconv(.c) f32 {
17 return floatFromInt(f32, a);
18}
19
20fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
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
16pub fn __floatditf(a: i64) callconv(.c) f128 {
17 return floatFromInt(f128, a);
18}
19
20fn _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 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3
4comptime {
5 symbol(&__floatdixf, "__floatdixf");
6}
7
8fn __floatdixf(a: i64) callconv(.c) f80 {
9 return floatFromInt(f80, a);
10}
lib/compiler_rt/floateidf.zig deleted-15
...@@ -1,15 +0,0 @@
1const builtin = @import("builtin");
2
3const std = @import("std");
4
5const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
6const symbol = @import("../compiler_rt.zig").symbol;
7
8comptime {
9 symbol(&__floateidf, "__floateidf");
10}
11
12pub 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 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
6
7comptime {
8 symbol(&__floateihf, "__floateihf");
9}
10
11pub 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 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
6
7comptime {
8 symbol(&__floateisf, "__floateisf");
9}
10
11pub 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 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
6
7comptime {
8 symbol(&__floateitf, "__floateitf");
9}
10
11pub 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 @@
1const builtin = @import("builtin");
2
3const std = @import("std");
4
5const symbol = @import("../compiler_rt.zig").symbol;
6const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
7
8comptime {
9 symbol(&__floateixf, "__floateixf");
10}
11
12pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_i2d, "__aeabi_i2d");
8 } else {
9 symbol(&__floatsidf, "__floatsidf");
10 }
11}
12
13pub fn __floatsidf(a: i32) callconv(.c) f64 {
14 return floatFromInt(f64, a);
15}
16
17fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 symbol(&__floatsihf, "__floatsihf");
7}
8
9fn __floatsihf(a: i32) callconv(.c) f16 {
10 return floatFromInt(f16, a);
11}
lib/compiler_rt/floatsisf.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_i2f, "__aeabi_i2f");
8 } else {
9 symbol(&__floatsisf, "__floatsisf");
10 }
11}
12
13pub fn __floatsisf(a: i32) callconv(.c) f32 {
14 return floatFromInt(f32, a);
15}
16
17fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
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
16pub fn __floatsitf(a: i32) callconv(.c) f128 {
17 return floatFromInt(f128, a);
18}
19
20fn _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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 symbol(&__floatsixf, "__floatsixf");
7}
8
9fn __floatsixf(a: i32) callconv(.c) f80 {
10 return floatFromInt(f80, a);
11}
lib/compiler_rt/floattidf.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 symbol(&__floattidf, "__floattidf");
7}
8
9pub fn __floattidf(a: i128) callconv(.c) f64 {
10 return floatFromInt(f64, a);
11}
lib/compiler_rt/floattihf.zig deleted-12
...@@ -1,12 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const floatFromInt = @import("./float_from_int.zig").floatFromInt;
5
6comptime {
7 symbol(&__floattihf, "__floattihf");
8}
9
10pub fn __floattihf(a: i128) callconv(.c) f16 {
11 return floatFromInt(f16, a);
12}
lib/compiler_rt/floattisf.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 symbol(&__floattisf, "__floattisf");
7}
8
9pub fn __floattisf(a: i128) callconv(.c) f32 {
10 return floatFromInt(f32, a);
11}
lib/compiler_rt/floattitf.zig deleted-13
...@@ -1,13 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 if (compiler_rt.want_ppc_abi)
7 symbol(&__floattitf, "__floattikf");
8 symbol(&__floattitf, "__floattitf");
9}
10
11pub fn __floattitf(a: i128) callconv(.c) f128 {
12 return floatFromInt(f128, a);
13}
lib/compiler_rt/floattixf.zig deleted-12
...@@ -1,12 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const floatFromInt = @import("./float_from_int.zig").floatFromInt;
5
6comptime {
7 symbol(&__floattixf, "__floattixf");
8}
9
10pub fn __floattixf(a: i128) callconv(.c) f80 {
11 return floatFromInt(f80, a);
12}
lib/compiler_rt/floatundidf.zig deleted-22
...@@ -1,22 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
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
16pub fn __floatundidf(a: u64) callconv(.c) f64 {
17 return floatFromInt(f64, a);
18}
19
20fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 symbol(&__floatundihf, "__floatundihf");
7}
8
9fn __floatundihf(a: u64) callconv(.c) f16 {
10 return floatFromInt(f16, a);
11}
lib/compiler_rt/floatundisf.zig deleted-23
...@@ -1,23 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const floatFromInt = @import("./float_from_int.zig").floatFromInt;
5
6comptime {
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
17pub fn __floatundisf(a: u64) callconv(.c) f32 {
18 return floatFromInt(f32, a);
19}
20
21fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
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
16pub fn __floatunditf(a: u64) callconv(.c) f128 {
17 return floatFromInt(f128, a);
18}
19
20fn _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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 symbol(&__floatundixf, "__floatundixf");
7}
8
9fn __floatundixf(a: u64) callconv(.c) f80 {
10 return floatFromInt(f80, a);
11}
lib/compiler_rt/floatuneidf.zig deleted-14
...@@ -1,14 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
6
7comptime {
8 symbol(&__floatuneidf, "__floatuneidf");
9}
10
11pub 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 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
6
7comptime {
8 symbol(&__floatuneihf, "__floatuneihf");
9}
10
11pub 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 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
6
7comptime {
8 symbol(&__floatuneisf, "__floatuneisf");
9}
10
11pub 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 @@
1const builtin = @import("builtin");
2
3const std = @import("std");
4
5const symbol = @import("../compiler_rt.zig").symbol;
6const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
7
8comptime {
9 symbol(&__floatuneitf, "__floatuneitf");
10}
11
12pub 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 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt;
6
7comptime {
8 symbol(&__floatuneixf, "__floatuneixf");
9}
10
11pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_ui2d, "__aeabi_ui2d");
8 } else {
9 symbol(&__floatunsidf, "__floatunsidf");
10 }
11}
12
13pub fn __floatunsidf(a: u32) callconv(.c) f64 {
14 return floatFromInt(f64, a);
15}
16
17fn __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 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3
4comptime {
5 symbol(&__floatunsihf, "__floatunsihf");
6}
7
8pub fn __floatunsihf(a: u32) callconv(.c) f16 {
9 return floatFromInt(f16, a);
10}
lib/compiler_rt/floatunsisf.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_ui2f, "__aeabi_ui2f");
8 } else {
9 symbol(&__floatunsisf, "__floatunsisf");
10 }
11}
12
13pub fn __floatunsisf(a: u32) callconv(.c) f32 {
14 return floatFromInt(f32, a);
15}
16
17fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
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
16pub fn __floatunsitf(a: u32) callconv(.c) f128 {
17 return floatFromInt(f128, a);
18}
19
20fn _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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 symbol(&__floatunsixf, "__floatunsixf");
7}
8
9fn __floatunsixf(a: u32) callconv(.c) f80 {
10 return floatFromInt(f80, a);
11}
lib/compiler_rt/floatuntidf.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 symbol(&__floatuntidf, "__floatuntidf");
7}
8
9pub fn __floatuntidf(a: u128) callconv(.c) f64 {
10 return floatFromInt(f64, a);
11}
lib/compiler_rt/floatuntihf.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const floatFromInt = @import("./float_from_int.zig").floatFromInt;
4
5comptime {
6 symbol(&__floatuntihf, "__floatuntihf");
7}
8
9pub fn __floatuntihf(a: u128) callconv(.c) f16 {
10 return floatFromInt(f16, a);
11}
lib/compiler_rt/floatuntisf.zig deleted-12
...@@ -1,12 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const floatFromInt = @import("./float_from_int.zig").floatFromInt;
5
6comptime {
7 symbol(&__floatuntisf, "__floatuntisf");
8}
9
10pub fn __floatuntisf(a: u128) callconv(.c) f32 {
11 return floatFromInt(f32, a);
12}
lib/compiler_rt/floatuntitf.zig deleted-13
...@@ -1,13 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const floatFromInt = @import("./float_from_int.zig").floatFromInt;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_ppc_abi)
7 symbol(&__floatuntitf, "__floatuntikf");
8 symbol(&__floatuntitf, "__floatuntitf");
9}
10
11pub fn __floatuntitf(a: u128) callconv(.c) f128 {
12 return floatFromInt(f128, a);
13}
lib/compiler_rt/floatuntixf.zig deleted-12
...@@ -1,12 +0,0 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const floatFromInt = @import("./float_from_int.zig").floatFromInt;
5
6comptime {
7 symbol(&__floatuntixf, "__floatuntixf");
8}
9
10pub 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,7 +15,7 @@ const mem = std.mem;
15const expect = std.testing.expect;15const expect = std.testing.expect;
1616
17const compiler_rt = @import("../compiler_rt.zig");17const compiler_rt = @import("../compiler_rt.zig");
18const symbol = @import("../compiler_rt.zig").symbol;18const symbol = compiler_rt.symbol;
1919
20comptime {20comptime {
21 // floor21 // floor
...@@ -41,52 +41,92 @@ comptime {...@@ -41,52 +41,92 @@ comptime {
41 symbol(&ceill, "ceill");41 symbol(&ceill, "ceill");
42}42}
4343
44pub fn __floorh(x: f16) callconv(.c) f16 {44fn __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}
47pub fn floor_f16(x: f16) f16 {
45 return impl(f16, .floor, x);48 return impl(f16, .floor, x);
46}49}
4750
48pub fn floorf(x: f32) callconv(.c) f32 {51fn 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}
54pub fn floor_f32(x: f32) f32 {
49 return impl(f32, .floor, x);55 return impl(f32, .floor, x);
50}56}
5157
52pub fn floor(x: f64) callconv(.c) f64 {58fn 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}
61pub fn floor_f64(x: f64) f64 {
53 return impl(f64, .floor, x);62 return impl(f64, .floor, x);
54}63}
5564
56pub fn __floorx(x: f80) callconv(.c) f80 {65fn __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}
68pub fn floor_f80(x: f80) f80 {
57 return impl(f80, .floor, x);69 return impl(f80, .floor, x);
58}70}
5971
60pub fn floorq(x: f128) callconv(.c) f128 {72fn 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}
75pub fn floor_f128(x: f128) f128 {
61 return impl(f128, .floor, x);76 return impl(f128, .floor, x);
62}77}
6378
64pub fn floorl(x: c_longdouble) callconv(.c) c_longdouble {79pub 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}
6787
68pub fn __ceilh(x: f16) callconv(.c) f16 {88fn __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}
91pub fn ceil_f16(x: f16) f16 {
69 return impl(f16, .ceil, x);92 return impl(f16, .ceil, x);
70}93}
7194
72pub fn ceilf(x: f32) callconv(.c) f32 {95fn 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}
98pub fn ceil_f32(x: f32) f32 {
73 return impl(f32, .ceil, x);99 return impl(f32, .ceil, x);
74}100}
75101
76pub fn ceil(x: f64) callconv(.c) f64 {102fn 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}
105pub fn ceil_f64(x: f64) f64 {
77 return impl(f64, .ceil, x);106 return impl(f64, .ceil, x);
78}107}
79108
80pub fn __ceilx(x: f80) callconv(.c) f80 {109fn __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}
112pub fn ceil_f80(x: f80) f80 {
81 return impl(f80, .ceil, x);113 return impl(f80, .ceil, x);
82}114}
83115
84pub fn ceilq(x: f128) callconv(.c) f128 {116fn 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}
119pub fn ceil_f128(x: f128) f128 {
85 return impl(f128, .ceil, x);120 return impl(f128, .ceil, x);
86}121}
87122
88pub fn ceill(x: c_longdouble) callconv(.c) c_longdouble {123pub 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}
91131
92inline fn impl(comptime T: type, comptime op: enum { floor, ceil }, x: T) T {132inline 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,142 +184,122 @@ inline fn impl(comptime T: type, comptime op: enum { floor, ceil }, x: T) T {
144 }184 }
145}185}
146186
147test "floor16" {187test floor_f16 {
148 try expect(__floorh(1.3) == 1.0);188 try expect(floor_f16(1.3) == 1.0);
149 try expect(__floorh(-1.3) == -2.0);189 try expect(floor_f16(-1.3) == -2.0);
150 try expect(__floorh(0.2) == 0.0);190 try expect(floor_f16(-0.2) == -1.0);
151}191 try expect(math.isPositiveZero(floor_f16(0.2)));
152192 try expect(math.isPositiveZero(floor_f16(0.0)));
153test "floor32" {193 try expect(math.isNegativeZero(floor_f16(-0.0)));
154 try expect(floorf(1.3) == 1.0);194 try expect(math.isPositiveInf(floor_f16(math.inf(f16))));
155 try expect(floorf(-1.3) == -2.0);195 try expect(math.isNegativeInf(floor_f16(-math.inf(f16))));
156 try expect(floorf(0.2) == 0.0);196 try expect(math.isNan(floor_f16(math.nan(f16))));
157}197}
158198
159test "floor64" {199test floor_f32 {
160 try expect(floor(1.3) == 1.0);200 try expect(floor_f32(1.3) == 1.0);
161 try expect(floor(-1.3) == -2.0);201 try expect(floor_f32(-1.3) == -2.0);
162 try expect(floor(0.2) == 0.0);202 try expect(floor_f32(-0.2) == -1.0);
163}203 try expect(math.isPositiveZero(floor_f32(0.2)));
164204 try expect(math.isPositiveZero(floor_f32(0.0)));
165test "floor80" {205 try expect(math.isNegativeZero(floor_f32(-0.0)));
166 try expect(__floorx(1.3) == 1.0);206 try expect(math.isPositiveInf(floor_f32(math.inf(f32))));
167 try expect(__floorx(-1.3) == -2.0);207 try expect(math.isNegativeInf(floor_f32(-math.inf(f32))));
168 try expect(__floorx(0.2) == 0.0);208 try expect(math.isNan(floor_f32(math.nan(f32))));
169}209}
170210
171test "floor128" {211test floor_f64 {
172 try expect(floorq(1.3) == 1.0);212 try expect(floor_f64(1.3) == 1.0);
173 try expect(floorq(-1.3) == -2.0);213 try expect(floor_f64(-1.3) == -2.0);
174 try expect(floorq(0.2) == 0.0);214 try expect(floor_f64(-0.2) == -1.0);
175}215 try expect(math.isPositiveZero(floor_f64(0.2)));
176216 try expect(math.isPositiveZero(floor_f64(0.0)));
177test "floor16.special" {217 try expect(math.isNegativeZero(floor_f64(-0.0)));
178 try expect(__floorh(0.0) == 0.0);218 try expect(math.isPositiveInf(floor_f64(math.inf(f64))));
179 try expect(__floorh(-0.0) == -0.0);219 try expect(math.isNegativeInf(floor_f64(-math.inf(f64))));
180 try expect(math.isPositiveInf(__floorh(math.inf(f16))));220 try expect(math.isNan(floor_f64(math.nan(f64))));
181 try expect(math.isNegativeInf(__floorh(-math.inf(f16))));221}
182 try expect(math.isNan(__floorh(math.nan(f16))));222
183}223test floor_f80 {
184224 try expect(floor_f80(1.3) == 1.0);
185test "floor32.special" {225 try expect(floor_f80(-1.3) == -2.0);
186 try expect(floorf(0.0) == 0.0);226 try expect(floor_f80(-0.2) == -1.0);
187 try expect(floorf(-0.0) == -0.0);227 try expect(math.isPositiveZero(floor_f80(0.2)));
188 try expect(math.isPositiveInf(floorf(math.inf(f32))));228 try expect(math.isPositiveZero(floor_f80(0.0)));
189 try expect(math.isNegativeInf(floorf(-math.inf(f32))));229 try expect(math.isNegativeZero(floor_f80(-0.0)));
190 try expect(math.isNan(floorf(math.nan(f32))));230 try expect(math.isPositiveInf(floor_f80(math.inf(f80))));
191}231 try expect(math.isNegativeInf(floor_f80(-math.inf(f80))));
192232 try expect(math.isNan(floor_f80(math.nan(f80))));
193test "floor64.special" {233}
194 try expect(floor(0.0) == 0.0);234
195 try expect(floor(-0.0) == -0.0);235test floor_f128 {
196 try expect(math.isPositiveInf(floor(math.inf(f64))));236 try expect(floor_f128(1.3) == 1.0);
197 try expect(math.isNegativeInf(floor(-math.inf(f64))));237 try expect(floor_f128(-1.3) == -2.0);
198 try expect(math.isNan(floor(math.nan(f64))));238 try expect(floor_f128(-0.2) == -1.0);
199}239 try expect(math.isPositiveZero(floor_f128(0.2)));
200240 try expect(math.isPositiveZero(floor_f128(0.0)));
201test "floor80.special" {241 try expect(math.isNegativeZero(floor_f128(-0.0)));
202 try expect(__floorx(0.0) == 0.0);242 try expect(math.isPositiveInf(floor_f128(math.inf(f128))));
203 try expect(__floorx(-0.0) == -0.0);243 try expect(math.isNegativeInf(floor_f128(-math.inf(f128))));
204 try expect(math.isPositiveInf(__floorx(math.inf(f80))));244 try expect(math.isNan(floor_f128(math.nan(f128))));
205 try expect(math.isNegativeInf(__floorx(-math.inf(f80))));245}
206 try expect(math.isNan(__floorx(math.nan(f80))));246
207}247test ceil_f16 {
208248 try expect(ceil_f16(1.3) == 2.0);
209test "floor128.special" {249 try expect(ceil_f16(-1.3) == -1.0);
210 try expect(floorq(0.0) == 0.0);250 try expect(ceil_f16(0.2) == 1.0);
211 try expect(floorq(-0.0) == -0.0);251 try expect(math.isNegativeZero(ceil_f16(-0.2)));
212 try expect(math.isPositiveInf(floorq(math.inf(f128))));252 try expect(math.isPositiveZero(ceil_f16(0.0)));
213 try expect(math.isNegativeInf(floorq(-math.inf(f128))));253 try expect(math.isNegativeZero(ceil_f16(-0.0)));
214 try expect(math.isNan(floorq(math.nan(f128))));254 try expect(math.isPositiveInf(ceil_f16(math.inf(f16))));
215}255 try expect(math.isNegativeInf(ceil_f16(-math.inf(f16))));
216256 try expect(math.isNan(ceil_f16(math.nan(f16))));
217test "ceil16" {257}
218 try expect(__ceilh(1.3) == 2.0);258
219 try expect(__ceilh(-1.3) == -1.0);259test ceil_f32 {
220 try expect(__ceilh(0.2) == 1.0);260 try expect(ceil_f32(1.3) == 2.0);
221}261 try expect(ceil_f32(-1.3) == -1.0);
222262 try expect(ceil_f32(0.2) == 1.0);
223test "ceil32" {263 try expect(math.isNegativeZero(ceil_f32(-0.2)));
224 try expect(ceilf(1.3) == 2.0);264 try expect(math.isPositiveZero(ceil_f32(0.0)));
225 try expect(ceilf(-1.3) == -1.0);265 try expect(math.isNegativeZero(ceil_f32(-0.0)));
226 try expect(ceilf(0.2) == 1.0);266 try expect(math.isPositiveInf(ceil_f32(math.inf(f32))));
227}267 try expect(math.isNegativeInf(ceil_f32(-math.inf(f32))));
228268 try expect(math.isNan(ceil_f32(math.nan(f32))));
229test "ceil64" {269}
230 try expect(ceil(1.3) == 2.0);270
231 try expect(ceil(-1.3) == -1.0);271test ceil_f64 {
232 try expect(ceil(0.2) == 1.0);272 try expect(ceil_f64(1.3) == 2.0);
233}273 try expect(ceil_f64(-1.3) == -1.0);
234274 try expect(ceil_f64(0.2) == 1.0);
235test "ceil80" {275 try expect(math.isNegativeZero(ceil_f64(-0.2)));
236 try expect(__ceilx(1.3) == 2.0);276 try expect(math.isPositiveZero(ceil_f64(0.0)));
237 try expect(__ceilx(-1.3) == -1.0);277 try expect(math.isNegativeZero(ceil_f64(-0.0)));
238 try expect(__ceilx(0.2) == 1.0);278 try expect(math.isPositiveInf(ceil_f64(math.inf(f64))));
239}279 try expect(math.isNegativeInf(ceil_f64(-math.inf(f64))));
240280 try expect(math.isNan(ceil_f64(math.nan(f64))));
241test "ceil128" {281}
242 try expect(ceilq(1.3) == 2.0);282
243 try expect(ceilq(-1.3) == -1.0);283test ceil_f80 {
244 try expect(ceilq(0.2) == 1.0);284 try expect(ceil_f80(1.3) == 2.0);
245}285 try expect(ceil_f80(-1.3) == -1.0);
246286 try expect(ceil_f80(0.2) == 1.0);
247test "ceil16.special" {287 try expect(math.isNegativeZero(ceil_f80(-0.2)));
248 try expect(__ceilh(0.0) == 0.0);288 try expect(math.isPositiveZero(ceil_f80(0.0)));
249 try expect(__ceilh(-0.0) == -0.0);289 try expect(math.isNegativeZero(ceil_f80(-0.0)));
250 try expect(math.isPositiveInf(__ceilh(math.inf(f16))));290 try expect(math.isPositiveInf(ceil_f80(math.inf(f80))));
251 try expect(math.isNegativeInf(__ceilh(-math.inf(f16))));291 try expect(math.isNegativeInf(ceil_f80(-math.inf(f80))));
252 try expect(math.isNan(__ceilh(math.nan(f16))));292 try expect(math.isNan(ceil_f80(math.nan(f80))));
253}293}
254294
255test "ceil32.special" {295test ceil_f128 {
256 try expect(ceilf(0.0) == 0.0);296 try expect(ceil_f128(1.3) == 2.0);
257 try expect(ceilf(-0.0) == -0.0);297 try expect(ceil_f128(-1.3) == -1.0);
258 try expect(math.isPositiveInf(ceilf(math.inf(f32))));298 try expect(ceil_f128(0.2) == 1.0);
259 try expect(math.isNegativeInf(ceilf(-math.inf(f32))));299 try expect(math.isNegativeZero(ceil_f128(-0.2)));
260 try expect(math.isNan(ceilf(math.nan(f32))));300 try expect(math.isPositiveZero(ceil_f128(0.0)));
261}301 try expect(math.isNegativeZero(ceil_f128(-0.0)));
262302 try expect(math.isPositiveInf(ceil_f128(math.inf(f128))));
263test "ceil64.special" {303 try expect(math.isNegativeInf(ceil_f128(-math.inf(f128))));
264 try expect(ceil(0.0) == 0.0);304 try expect(math.isNan(ceil_f128(math.nan(f128))));
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
271test "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
279test "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))));
285}305}
lib/compiler_rt/fma.zig+47-32
...@@ -23,12 +23,18 @@ comptime {...@@ -23,12 +23,18 @@ comptime {
23 symbol(&fmal, "fmal");23 symbol(&fmal, "fmal");
24}24}
2525
26pub fn __fmah(x: f16, y: f16, z: f16) callconv(.c) f16 {26fn __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}
29pub fn fma_f16(x: f16, y: f16, z: f16) f16 {
27 // TODO: more efficient implementation30 // TODO: more efficient implementation
28 return @floatCast(fmaf(x, y, z));31 return @floatCast(fma_f32(x, y, z));
29}32}
3033
31pub fn fmaf(x: f32, y: f32, z: f32) callconv(.c) f32 {34fn 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}
37pub fn fma_f32(x: f32, y: f32, z: f32) f32 {
32 const xy = @as(f64, x) * y;38 const xy = @as(f64, x) * y;
33 const xy_z = xy + z;39 const xy_z = xy + z;
34 const u = @as(u64, @bitCast(xy_z));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,8 +48,11 @@ pub fn fmaf(x: f32, y: f32, z: f32) callconv(.c) f32 {
42 }48 }
43}49}
4450
51fn 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/// NOTE: Upstream fma.c has been rewritten completely to raise fp exceptions more accurately.54/// NOTE: Upstream fma.c has been rewritten completely to raise fp exceptions more accurately.
46pub fn fma(x: f64, y: f64, z: f64) callconv(.c) f64 {55pub fn fma_f64(x: f64, y: f64, z: f64) f64 {
47 if (!math.isFinite(x) or !math.isFinite(y)) {56 if (!math.isFinite(x) or !math.isFinite(y)) {
48 return x * y + z;57 return x * y + z;
49 }58 }
...@@ -90,11 +99,17 @@ pub fn fma(x: f64, y: f64, z: f64) callconv(.c) f64 {...@@ -90,11 +99,17 @@ pub fn fma(x: f64, y: f64, z: f64) callconv(.c) f64 {
90 }99 }
91}100}
92101
93pub fn __fmax(a: f80, b: f80, c: f80) callconv(.c) f80 {102fn __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}
105pub fn fma_f80(a: f80, b: f80, c: f80) f80 {
94 // TODO: more efficient implementation106 // TODO: more efficient implementation
95 return @floatCast(fmaq(a, b, c));107 return @floatCast(fma_f128(a, b, c));
96}108}
97109
110fn 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/// Fused multiply-add: Compute x * y + z with a single rounding error.113/// Fused multiply-add: Compute x * y + z with a single rounding error.
99///114///
100/// We use scaling to avoid overflow/underflow, along with the115/// 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,7 +117,7 @@ pub fn __fmax(a: f80, b: f80, c: f80) callconv(.c) f80 {
102///117///
103/// Dekker, T. A Floating-Point Technique for Extending the118/// Dekker, T. A Floating-Point Technique for Extending the
104/// Available Precision. Numer. Math. 18, 224-242 (1971).119/// Available Precision. Numer. Math. 18, 224-242 (1971).
105pub fn fmaq(x: f128, y: f128, z: f128) callconv(.c) f128 {120pub fn fma_f128(x: f128, y: f128, z: f128) f128 {
106 if (!math.isFinite(x) or !math.isFinite(y)) {121 if (!math.isFinite(x) or !math.isFinite(y)) {
107 return x * y + z;122 return x * y + z;
108 }123 }
...@@ -151,10 +166,10 @@ pub fn fmaq(x: f128, y: f128, z: f128) callconv(.c) f128 {...@@ -151,10 +166,10 @@ pub fn fmaq(x: f128, y: f128, z: f128) callconv(.c) f128 {
151166
152pub fn fmal(x: c_longdouble, y: c_longdouble, z: c_longdouble) callconv(.c) c_longdouble {167pub fn fmal(x: c_longdouble, y: c_longdouble, z: c_longdouble) callconv(.c) c_longdouble {
153 switch (@typeInfo(c_longdouble).float.bits) {168 switch (@typeInfo(c_longdouble).float.bits) {
154 64 => return fma(x, y, z),169 64 => return fma_f64(x, y, z),
155 80 => return __fmax(x, y, z),170 80 => return fma_f80(x, y, z),
156 128 => return fmaq(x, y, z),171 128 => return fma_f128(x, y, z),
157 else => @compileError("unreachable"),172 else => comptime unreachable,
158 }173 }
159}174}
160175
...@@ -316,35 +331,35 @@ fn dd_mul128(a: f128, b: f128) dd128 {...@@ -316,35 +331,35 @@ fn dd_mul128(a: f128, b: f128) dd128 {
316test "32" {331test "32" {
317 const epsilon = 0.000001;332 const epsilon = 0.000001;
318333
319 try expect(math.approxEqAbs(f32, fmaf(0.0, 5.0, 9.124), 9.124, epsilon));334 try expect(math.approxEqAbs(f32, fma_f32(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));335 try expect(math.approxEqAbs(f32, fma_f32(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));336 try expect(math.approxEqAbs(f32, fma_f32(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));337 try expect(math.approxEqAbs(f32, fma_f32(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));338 try expect(math.approxEqAbs(f32, fma_f32(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));339 try expect(math.approxEqAbs(f32, fma_f32(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));340 try expect(math.approxEqAbs(f32, fma_f32(123123.234375, 5.0, 9.124), 615625.295875, epsilon));
326}341}
327342
328test "64" {343test "64" {
329 const epsilon = 0.000001;344 const epsilon = 0.000001;
330345
331 try expect(math.approxEqAbs(f64, fma(0.0, 5.0, 9.124), 9.124, epsilon));346 try expect(math.approxEqAbs(f64, fma_f64(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));347 try expect(math.approxEqAbs(f64, fma_f64(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));348 try expect(math.approxEqAbs(f64, fma_f64(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));349 try expect(math.approxEqAbs(f64, fma_f64(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));350 try expect(math.approxEqAbs(f64, fma_f64(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));351 try expect(math.approxEqAbs(f64, fma_f64(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));352 try expect(math.approxEqAbs(f64, fma_f64(123123.234375, 5.0, 9.124), 615625.295875, epsilon));
338}353}
339354
340test "128" {355test "128" {
341 const epsilon = 0.000001;356 const epsilon = 0.000001;
342357
343 try expect(math.approxEqAbs(f128, fmaq(0.0, 5.0, 9.124), 9.124, epsilon));358 try expect(math.approxEqAbs(f128, fma_f128(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));359 try expect(math.approxEqAbs(f128, fma_f128(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));360 try expect(math.approxEqAbs(f128, fma_f128(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));361 try expect(math.approxEqAbs(f128, fma_f128(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));362 try expect(math.approxEqAbs(f128, fma_f128(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));363 try expect(math.approxEqAbs(f128, fma_f128(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));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,32 +17,47 @@ comptime {
17 symbol(&fmaxl, "fmaxl");17 symbol(&fmaxl, "fmaxl");
18}18}
1919
20pub fn __fmaxh(x: f16, y: f16) callconv(.c) f16 {20fn __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}
23pub fn fmax_f16(x: f16, y: f16) f16 {
21 return generic_fmax(f16, x, y);24 return generic_fmax(f16, x, y);
22}25}
2326
24pub fn fmaxf(x: f32, y: f32) callconv(.c) f32 {27fn 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}
30pub fn fmax_f32(x: f32, y: f32) f32 {
25 return generic_fmax(f32, x, y);31 return generic_fmax(f32, x, y);
26}32}
2733
28pub fn fmax(x: f64, y: f64) callconv(.c) f64 {34fn 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}
37pub fn fmax_f64(x: f64, y: f64) f64 {
29 return generic_fmax(f64, x, y);38 return generic_fmax(f64, x, y);
30}39}
3140
32pub fn __fmaxx(x: f80, y: f80) callconv(.c) f80 {41fn __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}
44pub fn fmax_f80(x: f80, y: f80) f80 {
33 return generic_fmax(f80, x, y);45 return generic_fmax(f80, x, y);
34}46}
3547
36pub fn fmaxq(x: f128, y: f128) callconv(.c) f128 {48fn 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}
51pub fn fmax_f128(x: f128, y: f128) f128 {
37 return generic_fmax(f128, x, y);52 return generic_fmax(f128, x, y);
38}53}
3954
40pub fn fmaxl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble {55pub fn fmaxl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble {
41 switch (@typeInfo(c_longdouble).float.bits) {56 switch (@typeInfo(c_longdouble).float.bits) {
42 64 => return fmax(x, y),57 64 => return fmax_f64(x, y),
43 80 => return __fmaxx(x, y),58 80 => return fmax_f80(x, y),
44 128 => return fmaxq(x, y),59 128 => return fmax_f128(x, y),
45 else => @compileError("unreachable"),60 else => comptime unreachable,
46 }61 }
47}62}
4863
lib/compiler_rt/fmin.zig+24-9
...@@ -17,32 +17,47 @@ comptime {...@@ -17,32 +17,47 @@ comptime {
17 symbol(&fminl, "fminl");17 symbol(&fminl, "fminl");
18}18}
1919
20pub fn __fminh(x: f16, y: f16) callconv(.c) f16 {20fn __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}
23pub fn fmin_f16(x: f16, y: f16) f16 {
21 return generic_fmin(f16, x, y);24 return generic_fmin(f16, x, y);
22}25}
2326
24pub fn fminf(x: f32, y: f32) callconv(.c) f32 {27fn 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}
30pub fn fmin_f32(x: f32, y: f32) f32 {
25 return generic_fmin(f32, x, y);31 return generic_fmin(f32, x, y);
26}32}
2733
28pub fn fmin(x: f64, y: f64) callconv(.c) f64 {34fn 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}
37pub fn fmin_f64(x: f64, y: f64) f64 {
29 return generic_fmin(f64, x, y);38 return generic_fmin(f64, x, y);
30}39}
3140
32pub fn __fminx(x: f80, y: f80) callconv(.c) f80 {41fn __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}
44pub fn fmin_f80(x: f80, y: f80) f80 {
33 return generic_fmin(f80, x, y);45 return generic_fmin(f80, x, y);
34}46}
3547
36pub fn fminq(x: f128, y: f128) callconv(.c) f128 {48fn 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}
51pub fn fmin_f128(x: f128, y: f128) f128 {
37 return generic_fmin(f128, x, y);52 return generic_fmin(f128, x, y);
38}53}
3954
40pub fn fminl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble {55pub fn fminl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble {
41 switch (@typeInfo(c_longdouble).float.bits) {56 switch (@typeInfo(c_longdouble).float.bits) {
42 64 => return fmin(x, y),57 64 => return fmin_f64(x, y),
43 80 => return __fminx(x, y),58 80 => return fmin_f80(x, y),
44 128 => return fminq(x, y),59 128 => return fmin_f128(x, y),
45 else => @compileError("unreachable"),60 else => comptime unreachable,
46 }61 }
47}62}
4863
lib/compiler_rt/fmod.zig+49-34
...@@ -19,22 +19,34 @@ comptime {...@@ -19,22 +19,34 @@ comptime {
19 symbol(&fmodl, "fmodl");19 symbol(&fmodl, "fmodl");
20}20}
2121
22pub fn __fmodh(x: f16, y: f16) callconv(.c) f16 {22fn __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}
25pub fn fmod_f16(x: f16, y: f16) f16 {
23 // TODO: more efficient implementation26 // TODO: more efficient implementation
24 return @floatCast(fmodf(x, y));27 return @floatCast(fmod_f32(x, y));
25}28}
2629
27pub fn fmodf(x: f32, y: f32) callconv(.c) f32 {30fn 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}
33pub fn fmod_f32(x: f32, y: f32) f32 {
28 return generic_fmod(f32, x, y);34 return generic_fmod(f32, x, y);
29}35}
3036
31pub fn fmod(x: f64, y: f64) callconv(.c) f64 {37fn 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}
40pub fn fmod_f64(x: f64, y: f64) f64 {
32 return generic_fmod(f64, x, y);41 return generic_fmod(f64, x, y);
33}42}
3443
44fn __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/// fmodx - floating modulo large, returns the remainder of division for f80 types47/// fmodx - floating modulo large, returns the remainder of division for f80 types
36/// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits48/// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits
37pub fn __fmodx(a: f80, b: f80) callconv(.c) f80 {49pub fn fmod_f80(a: f80, b: f80) f80 {
38 const T = f80;50 const T = f80;
39 const Z = @Int(.unsigned, @bitSizeOf(T));51 const Z = @Int(.unsigned, @bitSizeOf(T));
4052
...@@ -130,9 +142,12 @@ pub fn __fmodx(a: f80, b: f80) callconv(.c) f80 {...@@ -130,9 +142,12 @@ pub fn __fmodx(a: f80, b: f80) callconv(.c) f80 {
130 }142 }
131}143}
132144
145fn 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/// fmodq - floating modulo large, returns the remainder of division for f128 types148/// fmodq - floating modulo large, returns the remainder of division for f128 types
134/// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits149/// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits
135pub fn fmodq(a: f128, b: f128) callconv(.c) f128 {150pub fn fmod_f128(a: f128, b: f128) f128 {
136 var amod = a;151 var amod = a;
137 var bmod = b;152 var bmod = b;
138 const aPtr_u64: [*]u64 = @ptrCast(&amod);153 const aPtr_u64: [*]u64 = @ptrCast(&amod);
...@@ -251,10 +266,10 @@ pub fn fmodq(a: f128, b: f128) callconv(.c) f128 {...@@ -251,10 +266,10 @@ pub fn fmodq(a: f128, b: f128) callconv(.c) f128 {
251266
252pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.c) c_longdouble {267pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.c) c_longdouble {
253 switch (@typeInfo(c_longdouble).float.bits) {268 switch (@typeInfo(c_longdouble).float.bits) {
254 64 => return fmod(a, b),269 64 => return fmod_f64(a, b),
255 80 => return __fmodx(a, b),270 80 => return fmod_f80(a, b),
256 128 => return fmodq(a, b),271 128 => return fmod_f128(a, b),
257 else => @compileError("unreachable"),272 else => comptime unreachable,
258 }273 }
259}274}
260275
...@@ -342,42 +357,42 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T {...@@ -342,42 +357,42 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T {
342 return @bitCast(ux);357 return @bitCast(ux);
343}358}
344359
345test "fmodf" {360test fmod_f32 {
346 const nan_val = math.nan(f32);361 const nan_val = math.nan(f32);
347 const inf_val = math.inf(f32);362 const inf_val = math.inf(f32);
348363
349 try std.testing.expect(math.isNan(fmodf(nan_val, 1.0)));364 try std.testing.expect(math.isNan(fmod_f32(nan_val, 1.0)));
350 try std.testing.expect(math.isNan(fmodf(1.0, nan_val)));365 try std.testing.expect(math.isNan(fmod_f32(1.0, nan_val)));
351 try std.testing.expect(math.isNan(fmodf(inf_val, 1.0)));366 try std.testing.expect(math.isNan(fmod_f32(inf_val, 1.0)));
352 try std.testing.expect(math.isNan(fmodf(0.0, 0.0)));367 try std.testing.expect(math.isNan(fmod_f32(0.0, 0.0)));
353 try std.testing.expect(math.isNan(fmodf(1.0, 0.0)));368 try std.testing.expect(math.isNan(fmod_f32(1.0, 0.0)));
354369
355 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));
356 try std.testing.expectEqual(@as(f32, -0.0), fmodf(-0.0, 2.0));371 try std.testing.expectEqual(@as(f32, -0.0), fmod_f32(-0.0, 2.0));
357372
358 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));
359 try std.testing.expectEqual(@as(f32, -2.0), fmodf(-32.0, -10.0));374 try std.testing.expectEqual(@as(f32, -2.0), fmod_f32(-32.0, -10.0));
360 try std.testing.expectEqual(@as(f32, 2.0), fmodf(32.0, 10.0));375 try std.testing.expectEqual(@as(f32, 2.0), fmod_f32(32.0, 10.0));
361 try std.testing.expectEqual(@as(f32, 2.0), fmodf(32.0, -10.0));376 try std.testing.expectEqual(@as(f32, 2.0), fmod_f32(32.0, -10.0));
362}377}
363378
364test "fmod" {379test fmod_f64 {
365 const nan_val = math.nan(f64);380 const nan_val = math.nan(f64);
366 const inf_val = math.inf(f64);381 const inf_val = math.inf(f64);
367382
368 try std.testing.expect(math.isNan(fmod(nan_val, 1.0)));383 try std.testing.expect(math.isNan(fmod_f64(nan_val, 1.0)));
369 try std.testing.expect(math.isNan(fmod(1.0, nan_val)));384 try std.testing.expect(math.isNan(fmod_f64(1.0, nan_val)));
370 try std.testing.expect(math.isNan(fmod(inf_val, 1.0)));385 try std.testing.expect(math.isNan(fmod_f64(inf_val, 1.0)));
371 try std.testing.expect(math.isNan(fmod(0.0, 0.0)));386 try std.testing.expect(math.isNan(fmod_f64(0.0, 0.0)));
372 try std.testing.expect(math.isNan(fmod(1.0, 0.0)));387 try std.testing.expect(math.isNan(fmod_f64(1.0, 0.0)));
373388
374 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));
375 try std.testing.expectEqual(@as(f64, -0.0), fmod(-0.0, 2.0));390 try std.testing.expectEqual(@as(f64, -0.0), fmod_f64(-0.0, 2.0));
376391
377 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));
378 try std.testing.expectEqual(@as(f64, -2.0), fmod(-32.0, -10.0));393 try std.testing.expectEqual(@as(f64, -2.0), fmod_f64(-32.0, -10.0));
379 try std.testing.expectEqual(@as(f64, 2.0), fmod(32.0, 10.0));394 try std.testing.expectEqual(@as(f64, 2.0), fmod_f64(32.0, 10.0));
380 try std.testing.expectEqual(@as(f64, 2.0), fmod(32.0, -10.0));395 try std.testing.expectEqual(@as(f64, 2.0), fmod_f64(32.0, -10.0));
381}396}
382397
383test {398test {
lib/compiler_rt/fmodq_test.zig+32-32
...@@ -1,52 +1,52 @@...@@ -1,52 +1,52 @@
1const std = @import("std");1const std = @import("std");
2const fmod = @import("fmod.zig");2const fmod_f128 = @import("fmod.zig").fmod_f128;
3const testing = std.testing;3const testing = std.testing;
44
5fn test_fmodq(a: f128, b: f128, exp: f128) !void {5fn test_fmod_f128(a: f128, b: f128, exp: f128) !void {
6 const res = fmod.fmodq(a, b);6 const res = fmod_f128(a, b);
7 try testing.expect(exp == res);7 try testing.expect(exp == res);
8}8}
99
10fn test_fmodq_nans() !void {10fn test_fmod_f128_nans() !void {
11 try testing.expect(std.math.isNan(fmod.fmodq(1.0, std.math.nan(f128))));11 try testing.expect(std.math.isNan(fmod_f128(1.0, std.math.nan(f128))));
12 try testing.expect(std.math.isNan(fmod.fmodq(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.fmodq(std.math.nan(f128), 1.0)));13 try testing.expect(std.math.isNan(fmod_f128(std.math.nan(f128), 1.0)));
14 try testing.expect(std.math.isNan(fmod.fmodq(-std.math.nan(f128), 1.0)));14 try testing.expect(std.math.isNan(fmod_f128(-std.math.nan(f128), 1.0)));
15}15}
1616
17fn test_fmodq_infs() !void {17fn test_fmod_f128_infs() !void {
18 try testing.expect(fmod.fmodq(1.0, std.math.inf(f128)) == 1.0);18 try testing.expect(fmod_f128(1.0, std.math.inf(f128)) == 1.0);
19 try testing.expect(fmod.fmodq(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.fmodq(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.fmodq(-std.math.inf(f128), 1.0)));21 try testing.expect(std.math.isNan(fmod_f128(-std.math.inf(f128), 1.0)));
22}22}
2323
24test "fmodq" {24test fmod_f128 {
25 try test_fmodq(6.8, 4.0, 2.8);25 try test_fmod_f128(6.8, 4.0, 2.8);
26 try test_fmodq(6.8, -4.0, 2.8);26 try test_fmod_f128(6.8, -4.0, 2.8);
27 try test_fmodq(-6.8, 4.0, -2.8);27 try test_fmod_f128(-6.8, 4.0, -2.8);
28 try test_fmodq(-6.8, -4.0, -2.8);28 try test_fmod_f128(-6.8, -4.0, -2.8);
29 try test_fmodq(3.0, 2.0, 1.0);29 try test_fmod_f128(3.0, 2.0, 1.0);
30 try test_fmodq(-5.0, 3.0, -2.0);30 try test_fmod_f128(-5.0, 3.0, -2.0);
31 try test_fmodq(3.0, 2.0, 1.0);31 try test_fmod_f128(3.0, 2.0, 1.0);
32 try test_fmodq(1.0, 2.0, 1.0);32 try test_fmod_f128(1.0, 2.0, 1.0);
33 try test_fmodq(0.0, 1.0, 0.0);33 try test_fmod_f128(0.0, 1.0, 0.0);
34 try test_fmodq(-0.0, 1.0, -0.0);34 try test_fmod_f128(-0.0, 1.0, -0.0);
35 try test_fmodq(7046119.0, 5558362.0, 1487757.0);35 try test_fmod_f128(7046119.0, 5558362.0, 1487757.0);
36 try test_fmodq(9010357.0, 1957236.0, 1181413.0);36 try test_fmod_f128(9010357.0, 1957236.0, 1181413.0);
37 try test_fmodq(5192296858534827628530496329220095, 10.0, 5.0);37 try test_fmod_f128(5192296858534827628530496329220095, 10.0, 5.0);
38 try test_fmodq(5192296858534827628530496329220095, 922337203681230954775807, 220474884073715748246157);38 try test_fmod_f128(5192296858534827628530496329220095, 922337203681230954775807, 220474884073715748246157);
3939
40 // Denormals40 // Denormals
41 const a1: f128 = 0xedcb34a235253948765432134674p-16494;41 const a1: f128 = 0xedcb34a235253948765432134674p-16494;
42 const b1: f128 = 0x5d2e38791cfbc0737402da5a9518p-16494;42 const b1: f128 = 0x5d2e38791cfbc0737402da5a9518p-16494;
43 const exp1: f128 = 0x336ec3affb2db8618e4e7d5e1c44p-16494;43 const exp1: f128 = 0x336ec3affb2db8618e4e7d5e1c44p-16494;
44 try test_fmodq(a1, b1, exp1);44 try test_fmod_f128(a1, b1, exp1);
45 const a2: f128 = 0x0.7654_3210_fdec_ba98_7654_3210_fdecp-16382;45 const a2: f128 = 0x0.7654_3210_fdec_ba98_7654_3210_fdecp-16382;
46 const b2: f128 = 0x0.0012_fdac_bdef_1234_fdec_3222_1111p-16382;46 const b2: f128 = 0x0.0012_fdac_bdef_1234_fdec_3222_1111p-16382;
47 const exp2: f128 = 0x0.0001_aecd_9d66_4a6e_67b7_d7d0_a901p-16382;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);
4949
50 try test_fmodq_nans();50 try test_fmod_f128_nans();
51 try test_fmodq_infs();51 try test_fmod_f128_infs();
52}52}
lib/compiler_rt/fmodx_test.zig+31-31
...@@ -1,52 +1,52 @@...@@ -1,52 +1,52 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const fmod = @import("fmod.zig");3const fmod_f80 = @import("fmod.zig").fmod_f80;
4const testing = std.testing;4const testing = std.testing;
55
6fn test_fmodx(a: f80, b: f80, exp: f80) !void {6fn test_fmod_f80(a: f80, b: f80, exp: f80) !void {
7 const res = fmod.__fmodx(a, b);7 const res = fmod_f80(a, b);
8 try testing.expect(exp == res);8 try testing.expect(exp == res);
9}9}
1010
11fn test_fmodx_nans() !void {11fn test_fmod_f80_nans() !void {
12 try testing.expect(std.math.isNan(fmod.__fmodx(1.0, std.math.nan(f80))));12 try testing.expect(std.math.isNan(fmod_f80(1.0, std.math.nan(f80))));
13 try testing.expect(std.math.isNan(fmod.__fmodx(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.__fmodx(std.math.nan(f80), 1.0)));14 try testing.expect(std.math.isNan(fmod_f80(std.math.nan(f80), 1.0)));
15 try testing.expect(std.math.isNan(fmod.__fmodx(-std.math.nan(f80), 1.0)));15 try testing.expect(std.math.isNan(fmod_f80(-std.math.nan(f80), 1.0)));
16}16}
1717
18fn test_fmodx_infs() !void {18fn test_fmod_f80_infs() !void {
19 try testing.expect(fmod.__fmodx(1.0, std.math.inf(f80)) == 1.0);19 try testing.expect(fmod_f80(1.0, std.math.inf(f80)) == 1.0);
20 try testing.expect(fmod.__fmodx(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.__fmodx(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.__fmodx(-std.math.inf(f80), 1.0)));22 try testing.expect(std.math.isNan(fmod_f80(-std.math.inf(f80), 1.0)));
23}23}
2424
25test "fmodx" {25test fmod_f80 {
26 try test_fmodx(6.4, 4.0, 2.4);26 try test_fmod_f80(6.4, 4.0, 2.4);
27 try test_fmodx(6.4, -4.0, 2.4);27 try test_fmod_f80(6.4, -4.0, 2.4);
28 try test_fmodx(-6.4, 4.0, -2.4);28 try test_fmod_f80(-6.4, 4.0, -2.4);
29 try test_fmodx(-6.4, -4.0, -2.4);29 try test_fmod_f80(-6.4, -4.0, -2.4);
30 try test_fmodx(3.0, 2.0, 1.0);30 try test_fmod_f80(3.0, 2.0, 1.0);
31 try test_fmodx(-5.0, 3.0, -2.0);31 try test_fmod_f80(-5.0, 3.0, -2.0);
32 try test_fmodx(3.0, 2.0, 1.0);32 try test_fmod_f80(3.0, 2.0, 1.0);
33 try test_fmodx(1.0, 2.0, 1.0);33 try test_fmod_f80(1.0, 2.0, 1.0);
34 try test_fmodx(0.0, 1.0, 0.0);34 try test_fmod_f80(0.0, 1.0, 0.0);
35 try test_fmodx(-0.0, 1.0, -0.0);35 try test_fmod_f80(-0.0, 1.0, -0.0);
36 try test_fmodx(7046119.0, 5558362.0, 1487757.0);36 try test_fmod_f80(7046119.0, 5558362.0, 1487757.0);
37 try test_fmodx(9010357.0, 1957236.0, 1181413.0);37 try test_fmod_f80(9010357.0, 1957236.0, 1181413.0);
38 try test_fmodx(9223372036854775807, 10.0, 7.0);38 try test_fmod_f80(9223372036854775807, 10.0, 7.0);
3939
40 // Denormals40 // Denormals
41 const a1: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381;41 const a1: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381;
42 const b1: f80 = 0x0.2e97_1c3c_8e7d_e03ap-16381;42 const b1: f80 = 0x0.2e97_1c3c_8e7d_e03ap-16381;
43 const exp1: f80 = 0x0.19b7_61d7_fd96_dc30p-16381;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 const a2: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381;45 const a2: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381;
46 const b2: f80 = 0x0.0e97_1c3c_8e7d_e03ap-16381;46 const b2: f80 = 0x0.0e97_1c3c_8e7d_e03ap-16381;
47 const exp2: f80 = 0x0.022c_b86c_a6a3_9ad4p-16381;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);
4949
50 try test_fmodx_nans();50 try test_fmod_f80_nans();
51 try test_fmodx_infs();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
3const compiler_rt = @import("../compiler_rt.zig");
4const comparef = @import("./comparef.zig");
5const symbol = @import("../compiler_rt.zig").symbol;
6
7comptime {
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."
19pub 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."
25pub fn __gtdf2(a: f64, b: f64) callconv(.c) i32 {
26 return __gedf2(a, b);
27}
28
29fn __aeabi_dcmpge(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
30 return @intFromBool(comparef.cmpf2(f64, comparef.GE, a, b) != .Less);
31}
32
33fn __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
3const symbol = @import("../compiler_rt.zig").symbol;
4const comparef = @import("./comparef.zig");
5
6comptime {
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."
13pub 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."
19pub 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
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const comparef = @import("./comparef.zig");
6
7comptime {
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."
19pub 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."
25pub fn __gtsf2(a: f32, b: f32) callconv(.c) i32 {
26 return __gesf2(a, b);
27}
28
29fn __aeabi_fcmpge(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
30 return @intFromBool(comparef.cmpf2(f32, comparef.GE, a, b) != .Less);
31}
32
33fn __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
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5const comparef = @import("./comparef.zig");
6
7comptime {
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."
18fn __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."
24fn __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 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const comparef = @import("./comparef.zig");
3
4comptime {
5 symbol(&__gexf2, "__gexf2");
6 symbol(&__gtxf2, "__gtxf2");
7}
8
9fn __gexf2(a: f80, b: f80) callconv(.c) i32 {
10 return @backingInt(comparef.cmp_f80(comparef.GE, a, b));
11}
12
13fn __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,7 +36,7 @@ comptime {
3636
37pub fn __divmodti4(a: i128, b: i128, rem: *i128) callconv(.c) i128 {37pub fn __divmodti4(a: i128, b: i128, rem: *i128) callconv(.c) i128 {
38 const d = __divti3(a, b);38 const d = __divti3(a, b);
39 rem.* = a -% (d * b);39 rem.* = a - d *% b;
40 return d;40 return d;
41}41}
4242
...@@ -69,7 +69,7 @@ fn test_one_divmodti4(a: i128, b: i128, expected_q: i128, expected_r: i128) !voi...@@ -69,7 +69,7 @@ fn test_one_divmodti4(a: i128, b: i128, expected_q: i128, expected_r: i128) !voi
6969
70pub fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.c) i64 {70pub fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.c) i64 {
71 const d = __divdi3(a, b);71 const d = __divdi3(a, b);
72 rem.* = a -% (d * b);72 rem.* = a - d *% b;
73 return d;73 return d;
74}74}
7575
...@@ -79,21 +79,20 @@ fn test_one_divmoddi4(a: i64, b: i64, expected_q: i64, expected_r: i64) !void {...@@ -79,21 +79,20 @@ fn test_one_divmoddi4(a: i64, b: i64, expected_q: i64, expected_r: i64) !void {
79 try testing.expect(q == expected_q and r == expected_r);79 try testing.expect(q == expected_q and r == expected_r);
80}80}
8181
82const cases__divmoddi4 =82const cases__divmoddi4 = [_][4]i64{
83 [_][4]i64{83 [_]i64{ 0, 1, 0, 0 },
84 [_]i64{ 0, 1, 0, 0 },84 [_]i64{ 0, -1, 0, 0 },
85 [_]i64{ 0, -1, 0, 0 },85 [_]i64{ 2, 1, 2, 0 },
86 [_]i64{ 2, 1, 2, 0 },86 [_]i64{ 2, -1, -2, 0 },
87 [_]i64{ 2, -1, -2, 0 },87 [_]i64{ -2, 1, -2, 0 },
88 [_]i64{ -2, 1, -2, 0 },88 [_]i64{ -2, -1, 2, 0 },
89 [_]i64{ -2, -1, 2, 0 },89 [_]i64{ 7, 5, 1, 2 },
90 [_]i64{ 7, 5, 1, 2 },90 [_]i64{ -7, 5, -1, -2 },
91 [_]i64{ -7, 5, -1, -2 },91 [_]i64{ 19, 5, 3, 4 },
92 [_]i64{ 19, 5, 3, 4 },92 [_]i64{ 19, -5, -3, 4 },
93 [_]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, 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 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 },95};
96 };
9796
98test "test_divmoddi4" {97test "test_divmoddi4" {
99 for (cases__divmoddi4) |case| {98 for (cases__divmoddi4) |case| {
...@@ -105,10 +104,6 @@ pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.c) u64 {...@@ -105,10 +104,6 @@ pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.c) u64 {
105 return udivmod(u64, a, b, maybe_rem);104 return udivmod(u64, a, b, maybe_rem);
106}105}
107106
108test "test_udivmoddi4" {
109 _ = @import("udivmoddi4_test.zig");
110}
111
112pub fn __divdi3(a: i64, b: i64) callconv(.c) i64 {107pub fn __divdi3(a: i64, b: i64) callconv(.c) i64 {
113 // Set aside the sign of the quotient.108 // Set aside the sign of the quotient.
114 const sign: u64 = @bitCast((a ^ b) >> 63);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,25 +204,24 @@ fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) !void {
209204
210pub fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.c) i32 {205pub fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.c) i32 {
211 const d = __divsi3(a, b);206 const d = __divsi3(a, b);
212 rem.* = a -% (d * b);207 rem.* = a - d *% b;
213 return d;208 return d;
214}209}
215210
216const cases__divmodsi4 =211const cases__divmodsi4 = [_][4]i32{
217 [_][4]i32{212 [_]i32{ 0, 1, 0, 0 },
218 [_]i32{ 0, 1, 0, 0 },213 [_]i32{ 0, -1, 0, 0 },
219 [_]i32{ 0, -1, 0, 0 },214 [_]i32{ 2, 1, 2, 0 },
220 [_]i32{ 2, 1, 2, 0 },215 [_]i32{ 2, -1, -2, 0 },
221 [_]i32{ 2, -1, -2, 0 },216 [_]i32{ -2, 1, -2, 0 },
222 [_]i32{ -2, 1, -2, 0 },217 [_]i32{ -2, -1, 2, 0 },
223 [_]i32{ -2, -1, 2, 0 },218 [_]i32{ 7, 5, 1, 2 },
224 [_]i32{ 7, 5, 1, 2 },219 [_]i32{ -7, 5, -1, -2 },
225 [_]i32{ -7, 5, -1, -2 },220 [_]i32{ 19, 5, 3, 4 },
226 [_]i32{ 19, 5, 3, 4 },221 [_]i32{ 19, -5, -3, 4 },
227 [_]i32{ 19, -5, -3, 4 },222 [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 },
228 [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 },223 [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 },
229 [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 },224};
230 };
231225
232fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) !void {226fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) !void {
233 var r: i32 = undefined;227 var r: i32 = undefined;
...@@ -243,7 +237,7 @@ test "test_divmodsi4" {...@@ -243,7 +237,7 @@ test "test_divmodsi4" {
243237
244pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.c) u32 {238pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.c) u32 {
245 const d = __udivsi3(a, b);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 return d;241 return d;
248}242}
249243
...@@ -486,7 +480,7 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) !void {...@@ -486,7 +480,7 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) !void {
486}480}
487481
488pub fn __modsi3(n: i32, d: i32) callconv(.c) i32 {482pub 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}
491485
492test "test_modsi3" {486test "test_modsi3" {
...@@ -515,7 +509,7 @@ fn test_one_modsi3(a: i32, b: i32, expected_r: i32) !void {...@@ -515,7 +509,7 @@ fn test_one_modsi3(a: i32, b: i32, expected_r: i32) !void {
515}509}
516510
517pub fn __umodsi3(n: u32, d: u32) callconv(.c) u32 {511pub 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}
520514
521test "test_umodsi3" {515test "test_umodsi3" {
...@@ -663,3 +657,8 @@ fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) !void {...@@ -663,3 +657,8 @@ fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) !void {
663 const r: u32 = __umodsi3(a, b);657 const r: u32 = __umodsi3(a, b);
664 try testing.expect(r == expected_r);658 try testing.expect(r == expected_r);
665}659}
660
661test {
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,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const math = std.math;3const math = std.math;
3const Log2Int = std.math.Log2Int;4const Log2Int = std.math.Log2Int;
...@@ -6,29 +7,532 @@ const compiler_rt = @import("../compiler_rt.zig");...@@ -6,29 +7,532 @@ const compiler_rt = @import("../compiler_rt.zig");
6const symbol = compiler_rt.symbol;7const symbol = compiler_rt.symbol;
78
8comptime {9comptime {
9 symbol(&__fixxfti, "__fixxfti");
10 symbol(&__fixhfsi, "__fixhfsi");10 symbol(&__fixhfsi, "__fixhfsi");
11 symbol(&__fixhfdi, "__fixhfdi");11 symbol(&__fixhfdi, "__fixhfdi");
12 symbol(&__fixhfti, "__fixhfti");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
66fn __fixhfsi(a: compiler_rt.f16.Abi) callconv(.c) i32 {
67 return i32_intFromFloat_f16(compiler_rt.f16.fromAbi(a));
68}
69pub fn i32_intFromFloat_f16(a: f16) i32 {
70 return intFromFloat(i32, a);
71}
72
73fn __fixhfdi(a: compiler_rt.f16.Abi) callconv(.c) i64 {
74 return i64_intFromFloat_f16(compiler_rt.f16.fromAbi(a));
75}
76pub fn i64_intFromFloat_f16(a: f16) i64 {
77 return intFromFloat(i64, a);
78}
79
80fn __fixhfti(a: compiler_rt.f16.Abi) callconv(.c) i128 {
81 return i128_intFromFloat_f16(compiler_rt.f16.fromAbi(a));
82}
83pub fn i128_intFromFloat_f16(a: f16) i128 {
84 return intFromFloat(i128, a);
85}
86
87fn __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}
91pub fn signed_intFromFloat_f16(result: []u8, a: f16) void {
92 bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a);
93}
94
95fn __fixsfsi(a: compiler_rt.f32.Abi) callconv(.c) i32 {
96 return i32_intFromFloat_f32(compiler_rt.f32.fromAbi(a));
97}
98fn __aeabi_f2iz(a: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
99 return i32_intFromFloat_f32(a);
100}
101pub fn i32_intFromFloat_f32(a: f32) i32 {
102 return intFromFloat(i32, a);
103}
104
105fn __fixsfdi(a: compiler_rt.f32.Abi) callconv(.c) i64 {
106 return i64_intFromFloat_f32(compiler_rt.f32.fromAbi(a));
107}
108fn __aeabi_f2lz(a: f32) callconv(.{ .arm_aapcs = .{} }) i64 {
109 return i64_intFromFloat_f32(a);
110}
111pub fn i64_intFromFloat_f32(a: f32) i64 {
112 return intFromFloat(i64, a);
113}
114
115fn __fixsfti(a: compiler_rt.f32.Abi) callconv(.c) i128 {
116 return i128_intFromFloat_f32(compiler_rt.f32.fromAbi(a));
117}
118fn __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}
139pub fn i128_intFromFloat_f32(a: f32) i128 {
140 return intFromFloat(i128, a);
141}
142
143fn __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}
147pub fn signed_intFromFloat_f32(result: []u8, a: f32) void {
148 bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a);
149}
150
151fn __fixdfsi(a: compiler_rt.f64.Abi) callconv(.c) i32 {
152 return i32_intFromFloat_f64(compiler_rt.f64.fromAbi(a));
153}
154fn __aeabi_d2iz(a: f64) callconv(.{ .arm_aapcs = .{} }) i32 {
155 return i32_intFromFloat_f64(a);
156}
157pub fn i32_intFromFloat_f64(a: f64) i32 {
158 return intFromFloat(i32, a);
159}
160
161fn __fixdfdi(a: compiler_rt.f64.Abi) callconv(.c) i64 {
162 return i64_intFromFloat_f64(compiler_rt.f64.fromAbi(a));
163}
164fn __aeabi_d2lz(a: f64) callconv(.{ .arm_aapcs = .{} }) i64 {
165 return i64_intFromFloat_f64(a);
166}
167pub fn i64_intFromFloat_f64(a: f64) i64 {
168 return intFromFloat(i64, a);
13}169}
14170
15pub fn __fixhfti(a: f16) callconv(.c) i128 {171fn __fixdfti(a: compiler_rt.f64.Abi) callconv(.c) i128 {
172 return i128_intFromFloat_f64(compiler_rt.f64.fromAbi(a));
173}
174fn __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}
196pub fn i128_intFromFloat_f64(a: f64) i128 {
16 return intFromFloat(i128, a);197 return intFromFloat(i128, a);
17}198}
18199
19fn __fixhfdi(a: f16) callconv(.c) i64 {200fn __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}
204pub fn signed_intFromFloat_f64(result: []u8, a: f64) void {
205 bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a);
206}
207
208fn __fixxfsi(a: compiler_rt.f80.Abi) callconv(.c) i32 {
209 return i32_intFromFloat_f80(compiler_rt.f80.fromAbi(a));
210}
211pub fn i32_intFromFloat_f80(a: f80) i32 {
212 return intFromFloat(i32, a);
213}
214
215fn __fixxfdi(a: compiler_rt.f80.Abi) callconv(.c) i64 {
216 return i64_intFromFloat_f80(compiler_rt.f80.fromAbi(a));
217}
218pub fn i64_intFromFloat_f80(a: f80) i64 {
20 return intFromFloat(i64, a);219 return intFromFloat(i64, a);
21}220}
22221
23fn __fixhfsi(a: f16) callconv(.c) i32 {222fn __fixxfti(a: compiler_rt.f80.Abi) callconv(.c) i128 {
223 return i128_intFromFloat_f80(compiler_rt.f80.fromAbi(a));
224}
225pub fn i128_intFromFloat_f80(a: f80) i128 {
226 return intFromFloat(i128, a);
227}
228
229fn __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}
233pub fn signed_intFromFloat_f80(result: []u8, a: f80) void {
234 bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a);
235}
236
237fn __fixtfsi(a: compiler_rt.f128.Abi) callconv(.c) i32 {
238 return i32_intFromFloat_f128(compiler_rt.f128.fromAbi(a));
239}
240fn _Qp_qtoi(a: *const f128) callconv(.c) i32 {
241 return i32_intFromFloat_f128(a.*);
242}
243pub fn i32_intFromFloat_f128(a: f128) i32 {
24 return intFromFloat(i32, a);244 return intFromFloat(i32, a);
25}245}
26246
27pub fn __fixxfti(a: f80) callconv(.c) i128 {247fn __fixtfdi(a: compiler_rt.f128.Abi) callconv(.c) i64 {
248 return i64_intFromFloat_f128(compiler_rt.f128.fromAbi(a));
249}
250fn _Qp_qtox(a: *const f128) callconv(.c) i64 {
251 return i64_intFromFloat_f128(a.*);
252}
253pub fn i64_intFromFloat_f128(a: f128) i64 {
254 return intFromFloat(i64, a);
255}
256
257fn __fixtfti(a: compiler_rt.f128.Abi) callconv(.c) i128 {
258 return i128_intFromFloat_f128(compiler_rt.f128.fromAbi(a));
259}
260pub fn i128_intFromFloat_f128(a: f128) i128 {
28 return intFromFloat(i128, a);261 return intFromFloat(i128, a);
29}262}
30263
31pub inline fn intFromFloat(comptime I: type, a: anytype) I {264fn __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}
268pub fn signed_intFromFloat_f128(result: []u8, a: f128) void {
269 bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a);
270}
271
272comptime {
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
329fn __fixunshfsi(a: compiler_rt.f16.Abi) callconv(.c) u32 {
330 return u32_intFromFloat_f16(compiler_rt.f16.fromAbi(a));
331}
332pub fn u32_intFromFloat_f16(a: f16) u32 {
333 return intFromFloat(u32, a);
334}
335
336fn __fixunshfdi(a: compiler_rt.f16.Abi) callconv(.c) u64 {
337 return u64_intFromFloat_f16(compiler_rt.f16.fromAbi(a));
338}
339pub fn u64_intFromFloat_f16(a: f16) u64 {
340 return intFromFloat(u64, a);
341}
342
343fn __fixunshfti(a: compiler_rt.f16.Abi) callconv(.c) u128 {
344 return u128_intFromFloat_f16(compiler_rt.f16.fromAbi(a));
345}
346pub fn u128_intFromFloat_f16(a: f16) u128 {
347 return intFromFloat(u128, a);
348}
349
350fn __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}
354pub fn unsigned_intFromFloat_f16(result: []u8, a: f16) void {
355 bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a);
356}
357
358fn __fixunssfsi(a: compiler_rt.f32.Abi) callconv(.c) u32 {
359 return u32_intFromFloat_f32(compiler_rt.f32.fromAbi(a));
360}
361fn __aeabi_f2uiz(a: f32) callconv(.{ .arm_aapcs = .{} }) u32 {
362 return u32_intFromFloat_f32(a);
363}
364pub fn u32_intFromFloat_f32(a: f32) u32 {
365 return intFromFloat(u32, a);
366}
367
368fn __fixunssfdi(a: compiler_rt.f32.Abi) callconv(.c) u64 {
369 return u64_intFromFloat_f32(compiler_rt.f32.fromAbi(a));
370}
371fn __aeabi_f2ulz(a: f32) callconv(.{ .arm_aapcs = .{} }) u64 {
372 return u64_intFromFloat_f32(a);
373}
374pub fn u64_intFromFloat_f32(a: f32) u64 {
375 return intFromFloat(u64, a);
376}
377
378fn __fixunssfti(a: compiler_rt.f32.Abi) callconv(.c) u128 {
379 return u128_intFromFloat_f32(compiler_rt.f32.fromAbi(a));
380}
381fn __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}
402pub fn u128_intFromFloat_f32(a: f32) u128 {
403 return intFromFloat(u128, a);
404}
405
406fn __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}
410pub fn unsigned_intFromFloat_f32(result: []u8, a: f32) void {
411 bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a);
412}
413
414fn __fixunsdfsi(a: compiler_rt.f64.Abi) callconv(.c) u32 {
415 return u32_intFromFloat_f64(compiler_rt.f64.fromAbi(a));
416}
417fn __aeabi_d2uiz(a: f64) callconv(.{ .arm_aapcs = .{} }) u32 {
418 return u32_intFromFloat_f64(a);
419}
420pub fn u32_intFromFloat_f64(a: f64) u32 {
421 return intFromFloat(u32, a);
422}
423
424fn __fixunsdfdi(a: compiler_rt.f64.Abi) callconv(.c) u64 {
425 return u64_intFromFloat_f64(compiler_rt.f64.fromAbi(a));
426}
427fn __aeabi_d2ulz(a: f64) callconv(.{ .arm_aapcs = .{} }) u64 {
428 return u64_intFromFloat_f64(a);
429}
430pub fn u64_intFromFloat_f64(a: f64) u64 {
431 return intFromFloat(u64, a);
432}
433
434fn __fixunsdfti(a: compiler_rt.f64.Abi) callconv(.c) u128 {
435 return u128_intFromFloat_f64(compiler_rt.f64.fromAbi(a));
436}
437fn __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}
459pub fn u128_intFromFloat_f64(a: f64) u128 {
460 return intFromFloat(u128, a);
461}
462
463fn __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}
467pub fn unsigned_intFromFloat_f64(result: []u8, a: f64) void {
468 bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a);
469}
470
471fn __fixunsxfsi(a: compiler_rt.f80.Abi) callconv(.c) u32 {
472 return u32_intFromFloat_f80(compiler_rt.f80.fromAbi(a));
473}
474pub fn u32_intFromFloat_f80(a: f80) u32 {
475 return intFromFloat(u32, a);
476}
477
478fn __fixunsxfdi(a: compiler_rt.f80.Abi) callconv(.c) u64 {
479 return u64_intFromFloat_f80(compiler_rt.f80.fromAbi(a));
480}
481pub fn u64_intFromFloat_f80(a: f80) u64 {
482 return intFromFloat(u64, a);
483}
484
485fn __fixunsxfti(a: compiler_rt.f80.Abi) callconv(.c) u128 {
486 return u128_intFromFloat_f80(compiler_rt.f80.fromAbi(a));
487}
488pub fn u128_intFromFloat_f80(a: f80) u128 {
489 return intFromFloat(u128, a);
490}
491
492fn __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}
496pub fn unsigned_intFromFloat_f80(result: []u8, a: f80) void {
497 bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a);
498}
499
500fn __fixunstfsi(a: compiler_rt.f128.Abi) callconv(.c) u32 {
501 return u32_intFromFloat_f128(compiler_rt.f128.fromAbi(a));
502}
503fn _Qp_qtoui(a: *const f128) callconv(.c) u32 {
504 return u32_intFromFloat_f128(a.*);
505}
506pub fn u32_intFromFloat_f128(a: f128) u32 {
507 return intFromFloat(u32, a);
508}
509
510fn __fixunstfdi(a: compiler_rt.f128.Abi) callconv(.c) u64 {
511 return u64_intFromFloat_f128(compiler_rt.f128.fromAbi(a));
512}
513fn _Qp_qtoux(a: *const f128) callconv(.c) u64 {
514 return u64_intFromFloat_f128(a.*);
515}
516pub fn u64_intFromFloat_f128(a: f128) u64 {
517 return intFromFloat(u64, a);
518}
519
520fn __fixunstfti(a: compiler_rt.f128.Abi) callconv(.c) u128 {
521 return u128_intFromFloat_f128(compiler_rt.f128.fromAbi(a));
522}
523pub fn u128_intFromFloat_f128(a: f128) u128 {
524 return intFromFloat(u128, a);
525}
526
527fn __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}
531pub fn unsigned_intFromFloat_f128(result: []u8, a: f128) void {
532 bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a);
533}
534
535inline fn intFromFloat(comptime I: type, a: anytype) I {
32 const F = @TypeOf(a);536 const F = @TypeOf(a);
33 const float_bits = @typeInfo(F).float.bits;537 const float_bits = @typeInfo(F).float.bits;
34 const int_bits = @typeInfo(I).int.bits;538 const int_bits = @typeInfo(I).int.bits;
...@@ -76,13 +580,14 @@ pub inline fn intFromFloat(comptime I: type, a: anytype) I {...@@ -76,13 +580,14 @@ pub inline fn intFromFloat(comptime I: type, a: anytype) I {
76 return result;580 return result;
77}581}
78582
79pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, result: []u32, a: anytype) void {583inline fn bigIntFromFloat(comptime signedness: std.lang.Signedness, result: []u32, a: anytype) void {
584 const endian = builtin.cpu.arch.endian();
80 switch (result.len) {585 switch (result.len) {
81 0 => return,586 0 => return,
82 inline 1...4 => |limbs_len| {587 inline 1...4 => |limbs_len| {
83 const I = @Int(signedness, 32 * limbs_len);588 const I = @Int(signedness, 32 * limbs_len);
84 const low_to_high: [limbs_len]u32 = @bitCast(@as(I, @intFromFloat(a)));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 .little => low_to_high,591 .little => low_to_high,
87 .big => switch (limbs_len) {592 .big => switch (limbs_len) {
88 1 => .{low_to_high[0]},593 1 => .{low_to_high[0]},
...@@ -111,7 +616,6 @@ pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, resul...@@ -111,7 +616,6 @@ pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, resul
111 });616 });
112 switch (signedness) {617 switch (signedness) {
113 .signed => {618 .signed => {
114 const endian = @import("builtin").cpu.arch.endian();
115 const exponent_limb = switch (endian) {619 const exponent_limb = switch (endian) {
116 .little => exponent / 32,620 .little => exponent / 32,
117 .big => result.len - 1 - exponent / 32,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,1023 +2,1039 @@ const std = @import("std");
2const testing = std.testing;2const testing = std.testing;
3const math = std.math;3const math = std.math;
44
5const __fixunshfti = @import("fixunshfti.zig").__fixunshfti;5const impl = @import("int_from_float.zig");
6const __fixunsxfti = @import("fixunsxfti.zig").__fixunsxfti;6
77const i32_intFromFloat_f16 = impl.i32_intFromFloat_f16;
8// Conversion from f328const u32_intFromFloat_f16 = impl.u32_intFromFloat_f16;
9const __fixsfsi = @import("fixsfsi.zig").__fixsfsi;9const i64_intFromFloat_f16 = impl.i64_intFromFloat_f16;
10const __fixunssfsi = @import("fixunssfsi.zig").__fixunssfsi;10const u64_intFromFloat_f16 = impl.u64_intFromFloat_f16;
11const __fixsfdi = @import("fixsfdi.zig").__fixsfdi;11const i128_intFromFloat_f16 = impl.i128_intFromFloat_f16;
12const __fixunssfdi = @import("fixunssfdi.zig").__fixunssfdi;12const u128_intFromFloat_f16 = impl.u128_intFromFloat_f16;
13const __fixsfti = @import("fixsfti.zig").__fixsfti;13const signed_intFromFloat_f16 = impl.signed_intFromFloat_f16;
14const __fixunssfti = @import("fixunssfti.zig").__fixunssfti;14const unsigned_intFromFloat_f16 = impl.unsigned_intFromFloat_f16;
15const __fixsfei = @import("fixsfei.zig").__fixsfei;15
16const __fixunssfei = @import("fixunssfei.zig").__fixunssfei;16const i32_intFromFloat_f32 = impl.i32_intFromFloat_f32;
1717const u32_intFromFloat_f32 = impl.u32_intFromFloat_f32;
18// Conversion from f6418const i64_intFromFloat_f32 = impl.i64_intFromFloat_f32;
19const __fixdfsi = @import("fixdfsi.zig").__fixdfsi;19const u64_intFromFloat_f32 = impl.u64_intFromFloat_f32;
20const __fixunsdfsi = @import("fixunsdfsi.zig").__fixunsdfsi;20const i128_intFromFloat_f32 = impl.i128_intFromFloat_f32;
21const __fixdfdi = @import("fixdfdi.zig").__fixdfdi;21const u128_intFromFloat_f32 = impl.u128_intFromFloat_f32;
22const __fixunsdfdi = @import("fixunsdfdi.zig").__fixunsdfdi;22const signed_intFromFloat_f32 = impl.signed_intFromFloat_f32;
23const __fixdfti = @import("fixdfti.zig").__fixdfti;23const unsigned_intFromFloat_f32 = impl.unsigned_intFromFloat_f32;
24const __fixunsdfti = @import("fixunsdfti.zig").__fixunsdfti;24
25const __fixdfei = @import("fixdfei.zig").__fixdfei;25const i32_intFromFloat_f64 = impl.i32_intFromFloat_f64;
26const __fixunsdfei = @import("fixunsdfei.zig").__fixunsdfei;26const u32_intFromFloat_f64 = impl.u32_intFromFloat_f64;
2727const i64_intFromFloat_f64 = impl.i64_intFromFloat_f64;
28// Conversion from f12828const u64_intFromFloat_f64 = impl.u64_intFromFloat_f64;
29const __fixtfsi = @import("fixtfsi.zig").__fixtfsi;29const i128_intFromFloat_f64 = impl.i128_intFromFloat_f64;
30const __fixunstfsi = @import("fixunstfsi.zig").__fixunstfsi;30const u128_intFromFloat_f64 = impl.u128_intFromFloat_f64;
31const __fixtfdi = @import("fixtfdi.zig").__fixtfdi;31const signed_intFromFloat_f64 = impl.signed_intFromFloat_f64;
32const __fixunstfdi = @import("fixunstfdi.zig").__fixunstfdi;32const unsigned_intFromFloat_f64 = impl.unsigned_intFromFloat_f64;
33const __fixtfti = @import("fixtfti.zig").__fixtfti;33
34const __fixunstfti = @import("fixunstfti.zig").__fixunstfti;34const i32_intFromFloat_f80 = impl.i32_intFromFloat_f80;
3535const u32_intFromFloat_f80 = impl.u32_intFromFloat_f80;
36fn test__fixsfsi(a: f32, expected: i32) !void {36const i64_intFromFloat_f80 = impl.i64_intFromFloat_f80;
37 const x = __fixsfsi(a);37const u64_intFromFloat_f80 = impl.u64_intFromFloat_f80;
38const i128_intFromFloat_f80 = impl.i128_intFromFloat_f80;
39const u128_intFromFloat_f80 = impl.u128_intFromFloat_f80;
40const signed_intFromFloat_f80 = impl.signed_intFromFloat_f80;
41const unsigned_intFromFloat_f80 = impl.unsigned_intFromFloat_f80;
42
43const i32_intFromFloat_f128 = impl.i32_intFromFloat_f128;
44const u32_intFromFloat_f128 = impl.u32_intFromFloat_f128;
45const i64_intFromFloat_f128 = impl.i64_intFromFloat_f128;
46const u64_intFromFloat_f128 = impl.u64_intFromFloat_f128;
47const i128_intFromFloat_f128 = impl.i128_intFromFloat_f128;
48const u128_intFromFloat_f128 = impl.u128_intFromFloat_f128;
49const signed_intFromFloat_f128 = impl.signed_intFromFloat_f128;
50const unsigned_intFromFloat_f128 = impl.unsigned_intFromFloat_f128;
51
52fn test_i32_intFromFloat_f32(a: f32, expected: i32) !void {
53 const x = i32_intFromFloat_f32(a);
38 try testing.expect(x == expected);54 try testing.expect(x == expected);
39}55}
4056
41fn test__fixunssfsi(a: f32, expected: u32) !void {57fn test_u32_intFromFloat_f32(a: f32, expected: u32) !void {
42 const x = __fixunssfsi(a);58 const x = u32_intFromFloat_f32(a);
43 try testing.expect(x == expected);59 try testing.expect(x == expected);
44}60}
4561
46test "fixsfsi" {62test i32_intFromFloat_f32 {
47 try test__fixsfsi(-math.floatMax(f32), math.minInt(i32));63 try test_i32_intFromFloat_f32(-math.floatMax(f32), math.minInt(i32));
4864
49 try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));65 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
50 try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);66 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
5167
52 try test__fixsfsi(-0x1.0000000000000p+127, -0x80000000);68 try test_i32_intFromFloat_f32(-0x1.0000000000000p+127, -0x80000000);
53 try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);69 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
54 try test__fixsfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);70 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
5571
56 try test__fixsfsi(-0x1.0000000000001p+63, -0x80000000);72 try test_i32_intFromFloat_f32(-0x1.0000000000001p+63, -0x80000000);
57 try test__fixsfsi(-0x1.0000000000000p+63, -0x80000000);73 try test_i32_intFromFloat_f32(-0x1.0000000000000p+63, -0x80000000);
58 try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);74 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);
59 try test__fixsfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);75 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);
6076
61 try test__fixsfsi(-0x1.FFFFFEp+62, -0x80000000);77 try test_i32_intFromFloat_f32(-0x1.FFFFFEp+62, -0x80000000);
62 try test__fixsfsi(-0x1.FFFFFCp+62, -0x80000000);78 try test_i32_intFromFloat_f32(-0x1.FFFFFCp+62, -0x80000000);
6379
64 try test__fixsfsi(-0x1.000000p+31, -0x80000000);80 try test_i32_intFromFloat_f32(-0x1.000000p+31, -0x80000000);
65 try test__fixsfsi(-0x1.FFFFFFp+30, -0x80000000);81 try test_i32_intFromFloat_f32(-0x1.FFFFFFp+30, -0x80000000);
66 try test__fixsfsi(-0x1.FFFFFEp+30, -0x7FFFFF80);82 try test_i32_intFromFloat_f32(-0x1.FFFFFEp+30, -0x7FFFFF80);
67 try test__fixsfsi(-0x1.FFFFFCp+30, -0x7FFFFF00);83 try test_i32_intFromFloat_f32(-0x1.FFFFFCp+30, -0x7FFFFF00);
6884
69 try test__fixsfsi(-2.01, -2);85 try test_i32_intFromFloat_f32(-2.01, -2);
70 try test__fixsfsi(-2.0, -2);86 try test_i32_intFromFloat_f32(-2.0, -2);
71 try test__fixsfsi(-1.99, -1);87 try test_i32_intFromFloat_f32(-1.99, -1);
72 try test__fixsfsi(-1.0, -1);88 try test_i32_intFromFloat_f32(-1.0, -1);
73 try test__fixsfsi(-0.99, 0);89 try test_i32_intFromFloat_f32(-0.99, 0);
74 try test__fixsfsi(-0.5, 0);90 try test_i32_intFromFloat_f32(-0.5, 0);
7591
76 try test__fixsfsi(-math.floatMin(f32), 0);92 try test_i32_intFromFloat_f32(-math.floatMin(f32), 0);
77 try test__fixsfsi(0.0, 0);93 try test_i32_intFromFloat_f32(0.0, 0);
78 try test__fixsfsi(math.floatMin(f32), 0);94 try test_i32_intFromFloat_f32(math.floatMin(f32), 0);
79 try test__fixsfsi(0.5, 0);95 try test_i32_intFromFloat_f32(0.5, 0);
80 try test__fixsfsi(0.99, 0);96 try test_i32_intFromFloat_f32(0.99, 0);
81 try test__fixsfsi(1.0, 1);97 try test_i32_intFromFloat_f32(1.0, 1);
82 try test__fixsfsi(1.5, 1);98 try test_i32_intFromFloat_f32(1.5, 1);
83 try test__fixsfsi(1.99, 1);99 try test_i32_intFromFloat_f32(1.99, 1);
84 try test__fixsfsi(2.0, 2);100 try test_i32_intFromFloat_f32(2.0, 2);
85 try test__fixsfsi(2.01, 2);101 try test_i32_intFromFloat_f32(2.01, 2);
86102
87 try test__fixsfsi(0x1.FFFFFCp+30, 0x7FFFFF00);103 try test_i32_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00);
88 try test__fixsfsi(0x1.FFFFFEp+30, 0x7FFFFF80);104 try test_i32_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80);
89 try test__fixsfsi(0x1.FFFFFFp+30, 0x7FFFFFFF);105 try test_i32_intFromFloat_f32(0x1.FFFFFFp+30, 0x7FFFFFFF);
90 try test__fixsfsi(0x1.000000p+31, 0x7FFFFFFF);106 try test_i32_intFromFloat_f32(0x1.000000p+31, 0x7FFFFFFF);
91107
92 try test__fixsfsi(0x1.FFFFFCp+62, 0x7FFFFFFF);108 try test_i32_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFFFF);
93 try test__fixsfsi(0x1.FFFFFEp+62, 0x7FFFFFFF);109 try test_i32_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFFFF);
94110
95 try test__fixsfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);111 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
96 try test__fixsfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);112 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
97 try test__fixsfsi(0x1.0000000000000p+63, 0x7FFFFFFF);113 try test_i32_intFromFloat_f32(0x1.0000000000000p+63, 0x7FFFFFFF);
98 try test__fixsfsi(0x1.0000000000001p+63, 0x7FFFFFFF);114 try test_i32_intFromFloat_f32(0x1.0000000000001p+63, 0x7FFFFFFF);
99115
100 try test__fixsfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);116 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
101 try test__fixsfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);117 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
102 try test__fixsfsi(0x1.0000000000000p+127, 0x7FFFFFFF);118 try test_i32_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFF);
103119
104 try test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);120 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
105 try test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));121 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
106122
107 try test__fixsfsi(math.floatMax(f32), math.maxInt(i32));123 try test_i32_intFromFloat_f32(math.floatMax(f32), math.maxInt(i32));
108}124}
109125
110test "fixunssfsi" {126test u32_intFromFloat_f32 {
111 try test__fixunssfsi(0.0, 0);127 try test_u32_intFromFloat_f32(0.0, 0);
112128
113 try test__fixunssfsi(0.5, 0);129 try test_u32_intFromFloat_f32(0.5, 0);
114 try test__fixunssfsi(0.99, 0);130 try test_u32_intFromFloat_f32(0.99, 0);
115 try test__fixunssfsi(1.0, 1);131 try test_u32_intFromFloat_f32(1.0, 1);
116 try test__fixunssfsi(1.5, 1);132 try test_u32_intFromFloat_f32(1.5, 1);
117 try test__fixunssfsi(1.99, 1);133 try test_u32_intFromFloat_f32(1.99, 1);
118 try test__fixunssfsi(2.0, 2);134 try test_u32_intFromFloat_f32(2.0, 2);
119 try test__fixunssfsi(2.01, 2);135 try test_u32_intFromFloat_f32(2.01, 2);
120 try test__fixunssfsi(-0.5, 0);136 try test_u32_intFromFloat_f32(-0.5, 0);
121 try test__fixunssfsi(-0.99, 0);137 try test_u32_intFromFloat_f32(-0.99, 0);
122138
123 try test__fixunssfsi(-1.0, 0);139 try test_u32_intFromFloat_f32(-1.0, 0);
124 try test__fixunssfsi(-1.5, 0);140 try test_u32_intFromFloat_f32(-1.5, 0);
125 try test__fixunssfsi(-1.99, 0);141 try test_u32_intFromFloat_f32(-1.99, 0);
126 try test__fixunssfsi(-2.0, 0);142 try test_u32_intFromFloat_f32(-2.0, 0);
127 try test__fixunssfsi(-2.01, 0);143 try test_u32_intFromFloat_f32(-2.01, 0);
128144
129 try test__fixunssfsi(0x1.000000p+31, 0x80000000);145 try test_u32_intFromFloat_f32(0x1.000000p+31, 0x80000000);
130 try test__fixunssfsi(0x1.000000p+32, 0xFFFFFFFF);146 try test_u32_intFromFloat_f32(0x1.000000p+32, 0xFFFFFFFF);
131 try test__fixunssfsi(0x1.FFFFFEp+31, 0xFFFFFF00);147 try test_u32_intFromFloat_f32(0x1.FFFFFEp+31, 0xFFFFFF00);
132 try test__fixunssfsi(0x1.FFFFFEp+30, 0x7FFFFF80);148 try test_u32_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80);
133 try test__fixunssfsi(0x1.FFFFFCp+30, 0x7FFFFF00);149 try test_u32_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00);
134150
135 try test__fixunssfsi(-0x1.FFFFFEp+30, 0);151 try test_u32_intFromFloat_f32(-0x1.FFFFFEp+30, 0);
136 try test__fixunssfsi(-0x1.FFFFFCp+30, 0);152 try test_u32_intFromFloat_f32(-0x1.FFFFFCp+30, 0);
137}153}
138154
139fn test__fixsfdi(a: f32, expected: i64) !void {155fn test_i64_intFromFloat_f32(a: f32, expected: i64) !void {
140 const x = __fixsfdi(a);156 const x = i64_intFromFloat_f32(a);
141 try testing.expect(x == expected);157 try testing.expect(x == expected);
142}158}
143159
144fn test__fixunssfdi(a: f32, expected: u64) !void {160fn test_u64_intFromFloat_f32(a: f32, expected: u64) !void {
145 const x = __fixunssfdi(a);161 const x = u64_intFromFloat_f32(a);
146 try testing.expect(x == expected);162 try testing.expect(x == expected);
147}163}
148164
149test "fixsfdi" {165test i64_intFromFloat_f32 {
150 try test__fixsfdi(-math.floatMax(f32), math.minInt(i64));166 try test_i64_intFromFloat_f32(-math.floatMax(f32), math.minInt(i64));
151167
152 try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));168 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
153 try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);169 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
154170
155 try test__fixsfdi(-0x1.0000000000000p+127, -0x8000000000000000);171 try test_i64_intFromFloat_f32(-0x1.0000000000000p+127, -0x8000000000000000);
156 try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);172 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
157 try test__fixsfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);173 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
158174
159 try test__fixsfdi(-0x1.0000000000001p+63, -0x8000000000000000);175 try test_i64_intFromFloat_f32(-0x1.0000000000001p+63, -0x8000000000000000);
160 try test__fixsfdi(-0x1.0000000000000p+63, -0x8000000000000000);176 try test_i64_intFromFloat_f32(-0x1.0000000000000p+63, -0x8000000000000000);
161 try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000);177 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000);
162 try test__fixsfdi(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000);178 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000);
163179
164 try test__fixsfdi(-0x1.FFFFFFp+62, -0x8000000000000000);180 try test_i64_intFromFloat_f32(-0x1.FFFFFFp+62, -0x8000000000000000);
165 try test__fixsfdi(-0x1.FFFFFEp+62, -0x7fffff8000000000);181 try test_i64_intFromFloat_f32(-0x1.FFFFFEp+62, -0x7fffff8000000000);
166 try test__fixsfdi(-0x1.FFFFFCp+62, -0x7fffff0000000000);182 try test_i64_intFromFloat_f32(-0x1.FFFFFCp+62, -0x7fffff0000000000);
167183
168 try test__fixsfdi(-2.01, -2);184 try test_i64_intFromFloat_f32(-2.01, -2);
169 try test__fixsfdi(-2.0, -2);185 try test_i64_intFromFloat_f32(-2.0, -2);
170 try test__fixsfdi(-1.99, -1);186 try test_i64_intFromFloat_f32(-1.99, -1);
171 try test__fixsfdi(-1.0, -1);187 try test_i64_intFromFloat_f32(-1.0, -1);
172 try test__fixsfdi(-0.99, 0);188 try test_i64_intFromFloat_f32(-0.99, 0);
173 try test__fixsfdi(-0.5, 0);189 try test_i64_intFromFloat_f32(-0.5, 0);
174 try test__fixsfdi(-math.floatMin(f32), 0);190 try test_i64_intFromFloat_f32(-math.floatMin(f32), 0);
175 try test__fixsfdi(0.0, 0);191 try test_i64_intFromFloat_f32(0.0, 0);
176 try test__fixsfdi(math.floatMin(f32), 0);192 try test_i64_intFromFloat_f32(math.floatMin(f32), 0);
177 try test__fixsfdi(0.5, 0);193 try test_i64_intFromFloat_f32(0.5, 0);
178 try test__fixsfdi(0.99, 0);194 try test_i64_intFromFloat_f32(0.99, 0);
179 try test__fixsfdi(1.0, 1);195 try test_i64_intFromFloat_f32(1.0, 1);
180 try test__fixsfdi(1.5, 1);196 try test_i64_intFromFloat_f32(1.5, 1);
181 try test__fixsfdi(1.99, 1);197 try test_i64_intFromFloat_f32(1.99, 1);
182 try test__fixsfdi(2.0, 2);198 try test_i64_intFromFloat_f32(2.0, 2);
183 try test__fixsfdi(2.01, 2);199 try test_i64_intFromFloat_f32(2.01, 2);
184200
185 try test__fixsfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);201 try test_i64_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
186 try test__fixsfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);202 try test_i64_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
187 try test__fixsfdi(0x1.FFFFFFp+62, 0x7FFFFFFFFFFFFFFF);203 try test_i64_intFromFloat_f32(0x1.FFFFFFp+62, 0x7FFFFFFFFFFFFFFF);
188204
189 try test__fixsfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFFFFF);205 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFFFFF);
190 try test__fixsfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFFFF);206 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFFFF);
191 try test__fixsfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);207 try test_i64_intFromFloat_f32(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
192 try test__fixsfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);208 try test_i64_intFromFloat_f32(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
193209
194 try test__fixsfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);210 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
195 try test__fixsfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);211 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
196 try test__fixsfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);212 try test_i64_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
197213
198 try test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);214 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
199 try test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));215 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
200216
201 try test__fixsfdi(math.floatMax(f32), math.maxInt(i64));217 try test_i64_intFromFloat_f32(math.floatMax(f32), math.maxInt(i64));
202}218}
203219
204test "fixunssfdi" {220test u64_intFromFloat_f32 {
205 try test__fixunssfdi(0.0, 0);221 try test_u64_intFromFloat_f32(0.0, 0);
206222
207 try test__fixunssfdi(0.5, 0);223 try test_u64_intFromFloat_f32(0.5, 0);
208 try test__fixunssfdi(0.99, 0);224 try test_u64_intFromFloat_f32(0.99, 0);
209 try test__fixunssfdi(1.0, 1);225 try test_u64_intFromFloat_f32(1.0, 1);
210 try test__fixunssfdi(1.5, 1);226 try test_u64_intFromFloat_f32(1.5, 1);
211 try test__fixunssfdi(1.99, 1);227 try test_u64_intFromFloat_f32(1.99, 1);
212 try test__fixunssfdi(2.0, 2);228 try test_u64_intFromFloat_f32(2.0, 2);
213 try test__fixunssfdi(2.01, 2);229 try test_u64_intFromFloat_f32(2.01, 2);
214 try test__fixunssfdi(-0.5, 0);230 try test_u64_intFromFloat_f32(-0.5, 0);
215 try test__fixunssfdi(-0.99, 0);231 try test_u64_intFromFloat_f32(-0.99, 0);
216232
217 try test__fixunssfdi(-1.0, 0);233 try test_u64_intFromFloat_f32(-1.0, 0);
218 try test__fixunssfdi(-1.5, 0);234 try test_u64_intFromFloat_f32(-1.5, 0);
219 try test__fixunssfdi(-1.99, 0);235 try test_u64_intFromFloat_f32(-1.99, 0);
220 try test__fixunssfdi(-2.0, 0);236 try test_u64_intFromFloat_f32(-2.0, 0);
221 try test__fixunssfdi(-2.01, 0);237 try test_u64_intFromFloat_f32(-2.01, 0);
222238
223 try test__fixunssfdi(0x1.FFFFFEp+63, 0xFFFFFF0000000000);239 try test_u64_intFromFloat_f32(0x1.FFFFFEp+63, 0xFFFFFF0000000000);
224 try test__fixunssfdi(0x1.000000p+63, 0x8000000000000000);240 try test_u64_intFromFloat_f32(0x1.000000p+63, 0x8000000000000000);
225 try test__fixunssfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);241 try test_u64_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
226 try test__fixunssfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);242 try test_u64_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
227243
228 try test__fixunssfdi(-0x1.FFFFFEp+62, 0x0000000000000000);244 try test_u64_intFromFloat_f32(-0x1.FFFFFEp+62, 0x0000000000000000);
229 try test__fixunssfdi(-0x1.FFFFFCp+62, 0x0000000000000000);245 try test_u64_intFromFloat_f32(-0x1.FFFFFCp+62, 0x0000000000000000);
230}246}
231247
232fn test__fixsfti(a: f32, expected: i128) !void {248fn test_i128_intFromFloat_f32(a: f32, expected: i128) !void {
233 const x = __fixsfti(a);249 const x = i128_intFromFloat_f32(a);
234 try testing.expect(x == expected);250 try testing.expect(x == expected);
235}251}
236252
237fn test__fixunssfti(a: f32, expected: u128) !void {253fn test_u128_intFromFloat_f32(a: f32, expected: u128) !void {
238 const x = __fixunssfti(a);254 const x = u128_intFromFloat_f32(a);
239 try testing.expect(x == expected);255 try testing.expect(x == expected);
240}256}
241257
242test "fixsfti" {258test i128_intFromFloat_f32 {
243 try test__fixsfti(-math.floatMax(f32), math.minInt(i128));259 try test_i128_intFromFloat_f32(-math.floatMax(f32), math.minInt(i128));
244260
245 try test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));261 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
246 try test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);262 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
247263
248 try test__fixsfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);264 try test_i128_intFromFloat_f32(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
249 try test__fixsfti(-0x1.FFFFFFFFFFFFFp+126, -0x80000000000000000000000000000000);265 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x80000000000000000000000000000000);
250 try test__fixsfti(-0x1.FFFFFFFFFFFFEp+126, -0x80000000000000000000000000000000);266 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x80000000000000000000000000000000);
251 try test__fixsfti(-0x1.FFFFFF0000000p+126, -0x80000000000000000000000000000000);267 try test_i128_intFromFloat_f32(-0x1.FFFFFF0000000p+126, -0x80000000000000000000000000000000);
252 try test__fixsfti(-0x1.FFFFFE0000000p+126, -0x7FFFFF80000000000000000000000000);268 try test_i128_intFromFloat_f32(-0x1.FFFFFE0000000p+126, -0x7FFFFF80000000000000000000000000);
253 try test__fixsfti(-0x1.FFFFFC0000000p+126, -0x7FFFFF00000000000000000000000000);269 try test_i128_intFromFloat_f32(-0x1.FFFFFC0000000p+126, -0x7FFFFF00000000000000000000000000);
254270
255 try test__fixsfti(-0x1.0000000000001p+63, -0x8000000000000000);271 try test_i128_intFromFloat_f32(-0x1.0000000000001p+63, -0x8000000000000000);
256 try test__fixsfti(-0x1.0000000000000p+63, -0x8000000000000000);272 try test_i128_intFromFloat_f32(-0x1.0000000000000p+63, -0x8000000000000000);
257 try test__fixsfti(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000);273 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000);
258 try test__fixsfti(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000);274 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000);
259275
260 try test__fixsfti(-0x1.FFFFFFp+62, -0x8000000000000000);276 try test_i128_intFromFloat_f32(-0x1.FFFFFFp+62, -0x8000000000000000);
261 try test__fixsfti(-0x1.FFFFFEp+62, -0x7fffff8000000000);277 try test_i128_intFromFloat_f32(-0x1.FFFFFEp+62, -0x7fffff8000000000);
262 try test__fixsfti(-0x1.FFFFFCp+62, -0x7fffff0000000000);278 try test_i128_intFromFloat_f32(-0x1.FFFFFCp+62, -0x7fffff0000000000);
263279
264 try test__fixsfti(-0x1.000000p+31, -0x80000000);280 try test_i128_intFromFloat_f32(-0x1.000000p+31, -0x80000000);
265 try test__fixsfti(-0x1.FFFFFFp+30, -0x80000000);281 try test_i128_intFromFloat_f32(-0x1.FFFFFFp+30, -0x80000000);
266 try test__fixsfti(-0x1.FFFFFEp+30, -0x7FFFFF80);282 try test_i128_intFromFloat_f32(-0x1.FFFFFEp+30, -0x7FFFFF80);
267 try test__fixsfti(-0x1.FFFFFCp+30, -0x7FFFFF00);283 try test_i128_intFromFloat_f32(-0x1.FFFFFCp+30, -0x7FFFFF00);
268284
269 try test__fixsfti(-2.01, -2);285 try test_i128_intFromFloat_f32(-2.01, -2);
270 try test__fixsfti(-2.0, -2);286 try test_i128_intFromFloat_f32(-2.0, -2);
271 try test__fixsfti(-1.99, -1);287 try test_i128_intFromFloat_f32(-1.99, -1);
272 try test__fixsfti(-1.0, -1);288 try test_i128_intFromFloat_f32(-1.0, -1);
273 try test__fixsfti(-0.99, 0);289 try test_i128_intFromFloat_f32(-0.99, 0);
274 try test__fixsfti(-0.5, 0);290 try test_i128_intFromFloat_f32(-0.5, 0);
275 try test__fixsfti(-math.floatMin(f32), 0);291 try test_i128_intFromFloat_f32(-math.floatMin(f32), 0);
276 try test__fixsfti(0.0, 0);292 try test_i128_intFromFloat_f32(0.0, 0);
277 try test__fixsfti(math.floatMin(f32), 0);293 try test_i128_intFromFloat_f32(math.floatMin(f32), 0);
278 try test__fixsfti(0.5, 0);294 try test_i128_intFromFloat_f32(0.5, 0);
279 try test__fixsfti(0.99, 0);295 try test_i128_intFromFloat_f32(0.99, 0);
280 try test__fixsfti(1.0, 1);296 try test_i128_intFromFloat_f32(1.0, 1);
281 try test__fixsfti(1.5, 1);297 try test_i128_intFromFloat_f32(1.5, 1);
282 try test__fixsfti(1.99, 1);298 try test_i128_intFromFloat_f32(1.99, 1);
283 try test__fixsfti(2.0, 2);299 try test_i128_intFromFloat_f32(2.0, 2);
284 try test__fixsfti(2.01, 2);300 try test_i128_intFromFloat_f32(2.01, 2);
285301
286 try test__fixsfti(0x1.FFFFFCp+30, 0x7FFFFF00);302 try test_i128_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00);
287 try test__fixsfti(0x1.FFFFFEp+30, 0x7FFFFF80);303 try test_i128_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80);
288 try test__fixsfti(0x1.FFFFFFp+30, 0x80000000);304 try test_i128_intFromFloat_f32(0x1.FFFFFFp+30, 0x80000000);
289 try test__fixsfti(0x1.000000p+31, 0x80000000);305 try test_i128_intFromFloat_f32(0x1.000000p+31, 0x80000000);
290306
291 try test__fixsfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);307 try test_i128_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
292 try test__fixsfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);308 try test_i128_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
293 try test__fixsfti(0x1.FFFFFFp+62, 0x8000000000000000);309 try test_i128_intFromFloat_f32(0x1.FFFFFFp+62, 0x8000000000000000);
294310
295 try test__fixsfti(0x1.FFFFFFFFFFFFEp+62, 0x8000000000000000);311 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x8000000000000000);
296 try test__fixsfti(0x1.FFFFFFFFFFFFFp+62, 0x8000000000000000);312 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x8000000000000000);
297 try test__fixsfti(0x1.0000000000000p+63, 0x8000000000000000);313 try test_i128_intFromFloat_f32(0x1.0000000000000p+63, 0x8000000000000000);
298 try test__fixsfti(0x1.0000000000001p+63, 0x8000000000000000);314 try test_i128_intFromFloat_f32(0x1.0000000000001p+63, 0x8000000000000000);
299315
300 try test__fixsfti(0x1.FFFFFC0000000p+126, 0x7FFFFF00000000000000000000000000);316 try test_i128_intFromFloat_f32(0x1.FFFFFC0000000p+126, 0x7FFFFF00000000000000000000000000);
301 try test__fixsfti(0x1.FFFFFE0000000p+126, 0x7FFFFF80000000000000000000000000);317 try test_i128_intFromFloat_f32(0x1.FFFFFE0000000p+126, 0x7FFFFF80000000000000000000000000);
302 try test__fixsfti(0x1.FFFFFF0000000p+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);318 try test_i128_intFromFloat_f32(0x1.FFFFFF0000000p+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
303 try test__fixsfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);319 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
304 try test__fixsfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);320 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
305 try test__fixsfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);321 try test_i128_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
306322
307 try test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);323 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
308 try test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));324 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
309325
310 try test__fixsfti(math.floatMax(f32), math.maxInt(i128));326 try test_i128_intFromFloat_f32(math.floatMax(f32), math.maxInt(i128));
311}327}
312328
313test "fixunssfti" {329test u128_intFromFloat_f32 {
314 try test__fixunssfti(0.0, 0);330 try test_u128_intFromFloat_f32(0.0, 0);
315331
316 try test__fixunssfti(0.5, 0);332 try test_u128_intFromFloat_f32(0.5, 0);
317 try test__fixunssfti(0.99, 0);333 try test_u128_intFromFloat_f32(0.99, 0);
318 try test__fixunssfti(1.0, 1);334 try test_u128_intFromFloat_f32(1.0, 1);
319 try test__fixunssfti(1.5, 1);335 try test_u128_intFromFloat_f32(1.5, 1);
320 try test__fixunssfti(1.99, 1);336 try test_u128_intFromFloat_f32(1.99, 1);
321 try test__fixunssfti(2.0, 2);337 try test_u128_intFromFloat_f32(2.0, 2);
322 try test__fixunssfti(2.01, 2);338 try test_u128_intFromFloat_f32(2.01, 2);
323 try test__fixunssfti(-0.5, 0);339 try test_u128_intFromFloat_f32(-0.5, 0);
324 try test__fixunssfti(-0.99, 0);340 try test_u128_intFromFloat_f32(-0.99, 0);
325341
326 try test__fixunssfti(-1.0, 0);342 try test_u128_intFromFloat_f32(-1.0, 0);
327 try test__fixunssfti(-1.5, 0);343 try test_u128_intFromFloat_f32(-1.5, 0);
328 try test__fixunssfti(-1.99, 0);344 try test_u128_intFromFloat_f32(-1.99, 0);
329 try test__fixunssfti(-2.0, 0);345 try test_u128_intFromFloat_f32(-2.0, 0);
330 try test__fixunssfti(-2.01, 0);346 try test_u128_intFromFloat_f32(-2.01, 0);
331347
332 try test__fixunssfti(0x1.FFFFFEp+63, 0xFFFFFF0000000000);348 try test_u128_intFromFloat_f32(0x1.FFFFFEp+63, 0xFFFFFF0000000000);
333 try test__fixunssfti(0x1.000000p+63, 0x8000000000000000);349 try test_u128_intFromFloat_f32(0x1.000000p+63, 0x8000000000000000);
334 try test__fixunssfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);350 try test_u128_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
335 try test__fixunssfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);351 try test_u128_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
336 try test__fixunssfti(0x1.FFFFFEp+127, 0xFFFFFF00000000000000000000000000);352 try test_u128_intFromFloat_f32(0x1.FFFFFEp+127, 0xFFFFFF00000000000000000000000000);
337 try test__fixunssfti(0x1.000000p+127, 0x80000000000000000000000000000000);353 try test_u128_intFromFloat_f32(0x1.000000p+127, 0x80000000000000000000000000000000);
338 try test__fixunssfti(0x1.FFFFFEp+126, 0x7FFFFF80000000000000000000000000);354 try test_u128_intFromFloat_f32(0x1.FFFFFEp+126, 0x7FFFFF80000000000000000000000000);
339 try test__fixunssfti(0x1.FFFFFCp+126, 0x7FFFFF00000000000000000000000000);355 try test_u128_intFromFloat_f32(0x1.FFFFFCp+126, 0x7FFFFF00000000000000000000000000);
340356
341 try test__fixunssfti(-0x1.FFFFFEp+62, 0x0000000000000000);357 try test_u128_intFromFloat_f32(-0x1.FFFFFEp+62, 0x0000000000000000);
342 try test__fixunssfti(-0x1.FFFFFCp+62, 0x0000000000000000);358 try test_u128_intFromFloat_f32(-0x1.FFFFFCp+62, 0x0000000000000000);
343 try test__fixunssfti(-0x1.FFFFFEp+126, 0x0000000000000000);359 try test_u128_intFromFloat_f32(-0x1.FFFFFEp+126, 0x0000000000000000);
344 try test__fixunssfti(-0x1.FFFFFCp+126, 0x0000000000000000);360 try test_u128_intFromFloat_f32(-0x1.FFFFFCp+126, 0x0000000000000000);
345 try test__fixunssfti(math.floatMax(f32), 0xffffff00000000000000000000000000);361 try test_u128_intFromFloat_f32(math.floatMax(f32), 0xffffff00000000000000000000000000);
346 try test__fixunssfti(math.inf(f32), math.maxInt(u128));362 try test_u128_intFromFloat_f32(math.inf(f32), math.maxInt(u128));
347}363}
348364
349fn test_fixsfei(comptime T: type, expected: T, a: f32) !void {365fn test_intFromFloat_f32(comptime T: type, expected: T, a: f32) !void {
350 const int = @typeInfo(T).int;366 const int = @typeInfo(T).int;
351 var actual: T = undefined;367 var actual: T = undefined;
352 _ = switch (int.signedness) {368 _ = switch (int.signedness) {
353 .signed => __fixsfei,369 .signed => signed_intFromFloat_f32,
354 .unsigned => __fixunssfei,370 .unsigned => unsigned_intFromFloat_f32,
355 }(@ptrCast(&actual), int.bits, a);371 }(@ptrCast(&actual), a);
356 try testing.expect(expected == actual);372 try testing.expect(expected == actual);
357}373}
358374
359test "fixsfei" {375test signed_intFromFloat_f32 {
360 try test_fixsfei(i256, -1 << 127, -0x1p127);376 try test_intFromFloat_f32(i256, -1 << 127, -0x1p127);
361 try test_fixsfei(i256, -1 << 100, -0x1p100);377 try test_intFromFloat_f32(i256, -1 << 100, -0x1p100);
362 try test_fixsfei(i256, -1 << 50, -0x1p50);378 try test_intFromFloat_f32(i256, -1 << 50, -0x1p50);
363 try test_fixsfei(i256, -1 << 1, -0x1p1);379 try test_intFromFloat_f32(i256, -1 << 1, -0x1p1);
364 try test_fixsfei(i256, -1 << 0, -0x1p0);380 try test_intFromFloat_f32(i256, -1 << 0, -0x1p0);
365 try test_fixsfei(i256, 0, 0);381 try test_intFromFloat_f32(i256, 0, 0);
366 try test_fixsfei(i256, 1 << 0, 0x1p0);382 try test_intFromFloat_f32(i256, 1 << 0, 0x1p0);
367 try test_fixsfei(i256, 1 << 1, 0x1p1);383 try test_intFromFloat_f32(i256, 1 << 1, 0x1p1);
368 try test_fixsfei(i256, 1 << 50, 0x1p50);384 try test_intFromFloat_f32(i256, 1 << 50, 0x1p50);
369 try test_fixsfei(i256, 1 << 100, 0x1p100);385 try test_intFromFloat_f32(i256, 1 << 100, 0x1p100);
370 try test_fixsfei(i256, 1 << 127, 0x1p127);386 try test_intFromFloat_f32(i256, 1 << 127, 0x1p127);
371}387}
372388
373test "fixunsfei" {389test unsigned_intFromFloat_f32 {
374 try test_fixsfei(u256, 0, 0);390 try test_intFromFloat_f32(u256, 0, 0);
375 try test_fixsfei(u256, 1 << 0, 0x1p0);391 try test_intFromFloat_f32(u256, 1 << 0, 0x1p0);
376 try test_fixsfei(u256, 1 << 1, 0x1p1);392 try test_intFromFloat_f32(u256, 1 << 1, 0x1p1);
377 try test_fixsfei(u256, 1 << 50, 0x1p50);393 try test_intFromFloat_f32(u256, 1 << 50, 0x1p50);
378 try test_fixsfei(u256, 1 << 100, 0x1p100);394 try test_intFromFloat_f32(u256, 1 << 100, 0x1p100);
379 try test_fixsfei(u256, 1 << 127, 0x1p127);395 try test_intFromFloat_f32(u256, 1 << 127, 0x1p127);
380}396}
381397
382fn test__fixdfsi(a: f64, expected: i32) !void {398fn test_i32_intFromFloat_f64(a: f64, expected: i32) !void {
383 const x = __fixdfsi(a);399 const x = i32_intFromFloat_f64(a);
384 try testing.expect(x == expected);400 try testing.expect(x == expected);
385}401}
386402
387fn test__fixunsdfsi(a: f64, expected: u32) !void {403fn test_u32_intFromFloat_f64(a: f64, expected: u32) !void {
388 const x = __fixunsdfsi(a);404 const x = u32_intFromFloat_f64(a);
389 try testing.expect(x == expected);405 try testing.expect(x == expected);
390}406}
391407
392test "fixdfsi" {408test i32_intFromFloat_f64 {
393 try test__fixdfsi(-math.floatMax(f64), math.minInt(i32));409 try test_i32_intFromFloat_f64(-math.floatMax(f64), math.minInt(i32));
394410
395 try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));411 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
396 try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);412 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
397413
398 try test__fixdfsi(-0x1.0000000000000p+127, -0x80000000);414 try test_i32_intFromFloat_f64(-0x1.0000000000000p+127, -0x80000000);
399 try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);415 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
400 try test__fixdfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);416 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
401417
402 try test__fixdfsi(-0x1.0000000000001p+63, -0x80000000);418 try test_i32_intFromFloat_f64(-0x1.0000000000001p+63, -0x80000000);
403 try test__fixdfsi(-0x1.0000000000000p+63, -0x80000000);419 try test_i32_intFromFloat_f64(-0x1.0000000000000p+63, -0x80000000);
404 try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);420 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);
405 try test__fixdfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);421 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);
406422
407 try test__fixdfsi(-0x1.FFFFFEp+62, -0x80000000);423 try test_i32_intFromFloat_f64(-0x1.FFFFFEp+62, -0x80000000);
408 try test__fixdfsi(-0x1.FFFFFCp+62, -0x80000000);424 try test_i32_intFromFloat_f64(-0x1.FFFFFCp+62, -0x80000000);
409425
410 try test__fixdfsi(-0x1.000000p+31, -0x80000000);426 try test_i32_intFromFloat_f64(-0x1.000000p+31, -0x80000000);
411 try test__fixdfsi(-0x1.FFFFFFp+30, -0x7FFFFFC0);427 try test_i32_intFromFloat_f64(-0x1.FFFFFFp+30, -0x7FFFFFC0);
412 try test__fixdfsi(-0x1.FFFFFEp+30, -0x7FFFFF80);428 try test_i32_intFromFloat_f64(-0x1.FFFFFEp+30, -0x7FFFFF80);
413429
414 try test__fixdfsi(-2.01, -2);430 try test_i32_intFromFloat_f64(-2.01, -2);
415 try test__fixdfsi(-2.0, -2);431 try test_i32_intFromFloat_f64(-2.0, -2);
416 try test__fixdfsi(-1.99, -1);432 try test_i32_intFromFloat_f64(-1.99, -1);
417 try test__fixdfsi(-1.0, -1);433 try test_i32_intFromFloat_f64(-1.0, -1);
418 try test__fixdfsi(-0.99, 0);434 try test_i32_intFromFloat_f64(-0.99, 0);
419 try test__fixdfsi(-0.5, 0);435 try test_i32_intFromFloat_f64(-0.5, 0);
420 try test__fixdfsi(-math.floatMin(f64), 0);436 try test_i32_intFromFloat_f64(-math.floatMin(f64), 0);
421 try test__fixdfsi(0.0, 0);437 try test_i32_intFromFloat_f64(0.0, 0);
422 try test__fixdfsi(math.floatMin(f64), 0);438 try test_i32_intFromFloat_f64(math.floatMin(f64), 0);
423 try test__fixdfsi(0.5, 0);439 try test_i32_intFromFloat_f64(0.5, 0);
424 try test__fixdfsi(0.99, 0);440 try test_i32_intFromFloat_f64(0.99, 0);
425 try test__fixdfsi(1.0, 1);441 try test_i32_intFromFloat_f64(1.0, 1);
426 try test__fixdfsi(1.5, 1);442 try test_i32_intFromFloat_f64(1.5, 1);
427 try test__fixdfsi(1.99, 1);443 try test_i32_intFromFloat_f64(1.99, 1);
428 try test__fixdfsi(2.0, 2);444 try test_i32_intFromFloat_f64(2.0, 2);
429 try test__fixdfsi(2.01, 2);445 try test_i32_intFromFloat_f64(2.01, 2);
430446
431 try test__fixdfsi(0x1.FFFFFEp+30, 0x7FFFFF80);447 try test_i32_intFromFloat_f64(0x1.FFFFFEp+30, 0x7FFFFF80);
432 try test__fixdfsi(0x1.FFFFFFp+30, 0x7FFFFFC0);448 try test_i32_intFromFloat_f64(0x1.FFFFFFp+30, 0x7FFFFFC0);
433 try test__fixdfsi(0x1.000000p+31, 0x7FFFFFFF);449 try test_i32_intFromFloat_f64(0x1.000000p+31, 0x7FFFFFFF);
434450
435 try test__fixdfsi(0x1.FFFFFCp+62, 0x7FFFFFFF);451 try test_i32_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFFFF);
436 try test__fixdfsi(0x1.FFFFFEp+62, 0x7FFFFFFF);452 try test_i32_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFFFF);
437453
438 try test__fixdfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);454 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
439 try test__fixdfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);455 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
440 try test__fixdfsi(0x1.0000000000000p+63, 0x7FFFFFFF);456 try test_i32_intFromFloat_f64(0x1.0000000000000p+63, 0x7FFFFFFF);
441 try test__fixdfsi(0x1.0000000000001p+63, 0x7FFFFFFF);457 try test_i32_intFromFloat_f64(0x1.0000000000001p+63, 0x7FFFFFFF);
442458
443 try test__fixdfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);459 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
444 try test__fixdfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);460 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
445 try test__fixdfsi(0x1.0000000000000p+127, 0x7FFFFFFF);461 try test_i32_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFF);
446462
447 try test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);463 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
448 try test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));464 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
449465
450 try test__fixdfsi(math.floatMax(f64), math.maxInt(i32));466 try test_i32_intFromFloat_f64(math.floatMax(f64), math.maxInt(i32));
451}467}
452468
453test "fixunsdfsi" {469test u32_intFromFloat_f64 {
454 try test__fixunsdfsi(0.0, 0);470 try test_u32_intFromFloat_f64(0.0, 0);
455471
456 try test__fixunsdfsi(0.5, 0);472 try test_u32_intFromFloat_f64(0.5, 0);
457 try test__fixunsdfsi(0.99, 0);473 try test_u32_intFromFloat_f64(0.99, 0);
458 try test__fixunsdfsi(1.0, 1);474 try test_u32_intFromFloat_f64(1.0, 1);
459 try test__fixunsdfsi(1.5, 1);475 try test_u32_intFromFloat_f64(1.5, 1);
460 try test__fixunsdfsi(1.99, 1);476 try test_u32_intFromFloat_f64(1.99, 1);
461 try test__fixunsdfsi(2.0, 2);477 try test_u32_intFromFloat_f64(2.0, 2);
462 try test__fixunsdfsi(2.01, 2);478 try test_u32_intFromFloat_f64(2.01, 2);
463 try test__fixunsdfsi(-0.5, 0);479 try test_u32_intFromFloat_f64(-0.5, 0);
464 try test__fixunsdfsi(-0.99, 0);480 try test_u32_intFromFloat_f64(-0.99, 0);
465 try test__fixunsdfsi(-1.0, 0);481 try test_u32_intFromFloat_f64(-1.0, 0);
466 try test__fixunsdfsi(-1.5, 0);482 try test_u32_intFromFloat_f64(-1.5, 0);
467 try test__fixunsdfsi(-1.99, 0);483 try test_u32_intFromFloat_f64(-1.99, 0);
468 try test__fixunsdfsi(-2.0, 0);484 try test_u32_intFromFloat_f64(-2.0, 0);
469 try test__fixunsdfsi(-2.01, 0);485 try test_u32_intFromFloat_f64(-2.01, 0);
470486
471 try test__fixunsdfsi(0x1.000000p+31, 0x80000000);487 try test_u32_intFromFloat_f64(0x1.000000p+31, 0x80000000);
472 try test__fixunsdfsi(0x1.000000p+32, 0xFFFFFFFF);488 try test_u32_intFromFloat_f64(0x1.000000p+32, 0xFFFFFFFF);
473 try test__fixunsdfsi(0x1.FFFFFEp+31, 0xFFFFFF00);489 try test_u32_intFromFloat_f64(0x1.FFFFFEp+31, 0xFFFFFF00);
474 try test__fixunsdfsi(0x1.FFFFFEp+30, 0x7FFFFF80);490 try test_u32_intFromFloat_f64(0x1.FFFFFEp+30, 0x7FFFFF80);
475 try test__fixunsdfsi(0x1.FFFFFCp+30, 0x7FFFFF00);491 try test_u32_intFromFloat_f64(0x1.FFFFFCp+30, 0x7FFFFF00);
476492
477 try test__fixunsdfsi(-0x1.FFFFFEp+30, 0);493 try test_u32_intFromFloat_f64(-0x1.FFFFFEp+30, 0);
478 try test__fixunsdfsi(-0x1.FFFFFCp+30, 0);494 try test_u32_intFromFloat_f64(-0x1.FFFFFCp+30, 0);
479495
480 try test__fixunsdfsi(0x1.FFFFFFFEp+31, 0xFFFFFFFF);496 try test_u32_intFromFloat_f64(0x1.FFFFFFFEp+31, 0xFFFFFFFF);
481 try test__fixunsdfsi(0x1.FFFFFFFC00000p+30, 0x7FFFFFFF);497 try test_u32_intFromFloat_f64(0x1.FFFFFFFC00000p+30, 0x7FFFFFFF);
482 try test__fixunsdfsi(0x1.FFFFFFF800000p+30, 0x7FFFFFFE);498 try test_u32_intFromFloat_f64(0x1.FFFFFFF800000p+30, 0x7FFFFFFE);
483}499}
484500
485fn test__fixdfdi(a: f64, expected: i64) !void {501fn test_i64_intFromFloat_f64(a: f64, expected: i64) !void {
486 const x = __fixdfdi(a);502 const x = i64_intFromFloat_f64(a);
487 try testing.expect(x == expected);503 try testing.expect(x == expected);
488}504}
489505
490fn test__fixunsdfdi(a: f64, expected: u64) !void {506fn test_u64_intFromFloat_f64(a: f64, expected: u64) !void {
491 const x = __fixunsdfdi(a);507 const x = u64_intFromFloat_f64(a);
492 try testing.expect(x == expected);508 try testing.expect(x == expected);
493}509}
494510
495test "fixdfdi" {511test i64_intFromFloat_f64 {
496 try test__fixdfdi(-math.floatMax(f64), math.minInt(i64));512 try test_i64_intFromFloat_f64(-math.floatMax(f64), math.minInt(i64));
497513
498 try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));514 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
499 try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);515 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
500516
501 try test__fixdfdi(-0x1.0000000000000p+127, -0x8000000000000000);517 try test_i64_intFromFloat_f64(-0x1.0000000000000p+127, -0x8000000000000000);
502 try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);518 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
503 try test__fixdfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);519 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
504520
505 try test__fixdfdi(-0x1.0000000000001p+63, -0x8000000000000000);521 try test_i64_intFromFloat_f64(-0x1.0000000000001p+63, -0x8000000000000000);
506 try test__fixdfdi(-0x1.0000000000000p+63, -0x8000000000000000);522 try test_i64_intFromFloat_f64(-0x1.0000000000000p+63, -0x8000000000000000);
507 try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);523 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
508 try test__fixdfdi(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);524 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
509525
510 try test__fixdfdi(-0x1.FFFFFEp+62, -0x7fffff8000000000);526 try test_i64_intFromFloat_f64(-0x1.FFFFFEp+62, -0x7fffff8000000000);
511 try test__fixdfdi(-0x1.FFFFFCp+62, -0x7fffff0000000000);527 try test_i64_intFromFloat_f64(-0x1.FFFFFCp+62, -0x7fffff0000000000);
512528
513 try test__fixdfdi(-2.01, -2);529 try test_i64_intFromFloat_f64(-2.01, -2);
514 try test__fixdfdi(-2.0, -2);530 try test_i64_intFromFloat_f64(-2.0, -2);
515 try test__fixdfdi(-1.99, -1);531 try test_i64_intFromFloat_f64(-1.99, -1);
516 try test__fixdfdi(-1.0, -1);532 try test_i64_intFromFloat_f64(-1.0, -1);
517 try test__fixdfdi(-0.99, 0);533 try test_i64_intFromFloat_f64(-0.99, 0);
518 try test__fixdfdi(-0.5, 0);534 try test_i64_intFromFloat_f64(-0.5, 0);
519 try test__fixdfdi(-math.floatMin(f64), 0);535 try test_i64_intFromFloat_f64(-math.floatMin(f64), 0);
520 try test__fixdfdi(0.0, 0);536 try test_i64_intFromFloat_f64(0.0, 0);
521 try test__fixdfdi(math.floatMin(f64), 0);537 try test_i64_intFromFloat_f64(math.floatMin(f64), 0);
522 try test__fixdfdi(0.5, 0);538 try test_i64_intFromFloat_f64(0.5, 0);
523 try test__fixdfdi(0.99, 0);539 try test_i64_intFromFloat_f64(0.99, 0);
524 try test__fixdfdi(1.0, 1);540 try test_i64_intFromFloat_f64(1.0, 1);
525 try test__fixdfdi(1.5, 1);541 try test_i64_intFromFloat_f64(1.5, 1);
526 try test__fixdfdi(1.99, 1);542 try test_i64_intFromFloat_f64(1.99, 1);
527 try test__fixdfdi(2.0, 2);543 try test_i64_intFromFloat_f64(2.0, 2);
528 try test__fixdfdi(2.01, 2);544 try test_i64_intFromFloat_f64(2.01, 2);
529545
530 try test__fixdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);546 try test_i64_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
531 try test__fixdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);547 try test_i64_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
532548
533 try test__fixdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);549 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
534 try test__fixdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);550 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
535 try test__fixdfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);551 try test_i64_intFromFloat_f64(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
536 try test__fixdfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);552 try test_i64_intFromFloat_f64(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
537553
538 try test__fixdfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);554 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
539 try test__fixdfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);555 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
540 try test__fixdfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);556 try test_i64_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
541557
542 try test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);558 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
543 try test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));559 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
544560
545 try test__fixdfdi(math.floatMax(f64), math.maxInt(i64));561 try test_i64_intFromFloat_f64(math.floatMax(f64), math.maxInt(i64));
546}562}
547563
548test "fixunsdfdi" {564test u64_intFromFloat_f64 {
549 try test__fixunsdfdi(0.0, 0);565 try test_u64_intFromFloat_f64(0.0, 0);
550 try test__fixunsdfdi(0.5, 0);566 try test_u64_intFromFloat_f64(0.5, 0);
551 try test__fixunsdfdi(0.99, 0);567 try test_u64_intFromFloat_f64(0.99, 0);
552 try test__fixunsdfdi(1.0, 1);568 try test_u64_intFromFloat_f64(1.0, 1);
553 try test__fixunsdfdi(1.5, 1);569 try test_u64_intFromFloat_f64(1.5, 1);
554 try test__fixunsdfdi(1.99, 1);570 try test_u64_intFromFloat_f64(1.99, 1);
555 try test__fixunsdfdi(2.0, 2);571 try test_u64_intFromFloat_f64(2.0, 2);
556 try test__fixunsdfdi(2.01, 2);572 try test_u64_intFromFloat_f64(2.01, 2);
557 try test__fixunsdfdi(-0.5, 0);573 try test_u64_intFromFloat_f64(-0.5, 0);
558 try test__fixunsdfdi(-0.99, 0);574 try test_u64_intFromFloat_f64(-0.99, 0);
559 try test__fixunsdfdi(-1.0, 0);575 try test_u64_intFromFloat_f64(-1.0, 0);
560 try test__fixunsdfdi(-1.5, 0);576 try test_u64_intFromFloat_f64(-1.5, 0);
561 try test__fixunsdfdi(-1.99, 0);577 try test_u64_intFromFloat_f64(-1.99, 0);
562 try test__fixunsdfdi(-2.0, 0);578 try test_u64_intFromFloat_f64(-2.0, 0);
563 try test__fixunsdfdi(-2.01, 0);579 try test_u64_intFromFloat_f64(-2.01, 0);
564580
565 try test__fixunsdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);581 try test_u64_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
566 try test__fixunsdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);582 try test_u64_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
567583
568 try test__fixunsdfdi(-0x1.FFFFFEp+62, 0);584 try test_u64_intFromFloat_f64(-0x1.FFFFFEp+62, 0);
569 try test__fixunsdfdi(-0x1.FFFFFCp+62, 0);585 try test_u64_intFromFloat_f64(-0x1.FFFFFCp+62, 0);
570586
571 try test__fixunsdfdi(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800);587 try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800);
572 try test__fixunsdfdi(0x1.0000000000000p+63, 0x8000000000000000);588 try test_u64_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000);
573 try test__fixunsdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);589 try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
574 try test__fixunsdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);590 try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
575591
576 try test__fixunsdfdi(-0x1.FFFFFFFFFFFFFp+62, 0);592 try test_u64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, 0);
577 try test__fixunsdfdi(-0x1.FFFFFFFFFFFFEp+62, 0);593 try test_u64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, 0);
578}594}
579595
580fn test__fixdfti(a: f64, expected: i128) !void {596fn test_i128_intFromFloat_f64(a: f64, expected: i128) !void {
581 const x = __fixdfti(a);597 const x = i128_intFromFloat_f64(a);
582 try testing.expect(x == expected);598 try testing.expect(x == expected);
583}599}
584600
585fn test__fixunsdfti(a: f64, expected: u128) !void {601fn test_u128_intFromFloat_f64(a: f64, expected: u128) !void {
586 const x = __fixunsdfti(a);602 const x = u128_intFromFloat_f64(a);
587 try testing.expect(x == expected);603 try testing.expect(x == expected);
588}604}
589605
590test "fixdfti" {606test i128_intFromFloat_f64 {
591 try test__fixdfti(-math.floatMax(f64), math.minInt(i128));607 try test_i128_intFromFloat_f64(-math.floatMax(f64), math.minInt(i128));
592608
593 try test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));609 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
594 try test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);610 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
595611
596 try test__fixdfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);612 try test_i128_intFromFloat_f64(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
597 try test__fixdfti(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000);613 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000);
598 try test__fixdfti(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000);614 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000);
599615
600 try test__fixdfti(-0x1.0000000000001p+63, -0x8000000000000800);616 try test_i128_intFromFloat_f64(-0x1.0000000000001p+63, -0x8000000000000800);
601 try test__fixdfti(-0x1.0000000000000p+63, -0x8000000000000000);617 try test_i128_intFromFloat_f64(-0x1.0000000000000p+63, -0x8000000000000000);
602 try test__fixdfti(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);618 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
603 try test__fixdfti(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);619 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
604620
605 try test__fixdfti(-0x1.FFFFFEp+62, -0x7fffff8000000000);621 try test_i128_intFromFloat_f64(-0x1.FFFFFEp+62, -0x7fffff8000000000);
606 try test__fixdfti(-0x1.FFFFFCp+62, -0x7fffff0000000000);622 try test_i128_intFromFloat_f64(-0x1.FFFFFCp+62, -0x7fffff0000000000);
607623
608 try test__fixdfti(-2.01, -2);624 try test_i128_intFromFloat_f64(-2.01, -2);
609 try test__fixdfti(-2.0, -2);625 try test_i128_intFromFloat_f64(-2.0, -2);
610 try test__fixdfti(-1.99, -1);626 try test_i128_intFromFloat_f64(-1.99, -1);
611 try test__fixdfti(-1.0, -1);627 try test_i128_intFromFloat_f64(-1.0, -1);
612 try test__fixdfti(-0.99, 0);628 try test_i128_intFromFloat_f64(-0.99, 0);
613 try test__fixdfti(-0.5, 0);629 try test_i128_intFromFloat_f64(-0.5, 0);
614 try test__fixdfti(-math.floatMin(f64), 0);630 try test_i128_intFromFloat_f64(-math.floatMin(f64), 0);
615 try test__fixdfti(0.0, 0);631 try test_i128_intFromFloat_f64(0.0, 0);
616 try test__fixdfti(math.floatMin(f64), 0);632 try test_i128_intFromFloat_f64(math.floatMin(f64), 0);
617 try test__fixdfti(0.5, 0);633 try test_i128_intFromFloat_f64(0.5, 0);
618 try test__fixdfti(0.99, 0);634 try test_i128_intFromFloat_f64(0.99, 0);
619 try test__fixdfti(1.0, 1);635 try test_i128_intFromFloat_f64(1.0, 1);
620 try test__fixdfti(1.5, 1);636 try test_i128_intFromFloat_f64(1.5, 1);
621 try test__fixdfti(1.99, 1);637 try test_i128_intFromFloat_f64(1.99, 1);
622 try test__fixdfti(2.0, 2);638 try test_i128_intFromFloat_f64(2.0, 2);
623 try test__fixdfti(2.01, 2);639 try test_i128_intFromFloat_f64(2.01, 2);
624640
625 try test__fixdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);641 try test_i128_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
626 try test__fixdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);642 try test_i128_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
627643
628 try test__fixdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);644 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
629 try test__fixdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);645 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
630 try test__fixdfti(0x1.0000000000000p+63, 0x8000000000000000);646 try test_i128_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000);
631 try test__fixdfti(0x1.0000000000001p+63, 0x8000000000000800);647 try test_i128_intFromFloat_f64(0x1.0000000000001p+63, 0x8000000000000800);
632648
633 try test__fixdfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);649 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);
634 try test__fixdfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);650 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);
635 try test__fixdfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);651 try test_i128_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
636652
637 try test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);653 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
638 try test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));654 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
639655
640 try test__fixdfti(math.floatMax(f64), math.maxInt(i128));656 try test_i128_intFromFloat_f64(math.floatMax(f64), math.maxInt(i128));
641}657}
642658
643test "fixunsdfti" {659test u128_intFromFloat_f64 {
644 try test__fixunsdfti(0.0, 0);660 try test_u128_intFromFloat_f64(0.0, 0);
645661
646 try test__fixunsdfti(0.5, 0);662 try test_u128_intFromFloat_f64(0.5, 0);
647 try test__fixunsdfti(0.99, 0);663 try test_u128_intFromFloat_f64(0.99, 0);
648 try test__fixunsdfti(1.0, 1);664 try test_u128_intFromFloat_f64(1.0, 1);
649 try test__fixunsdfti(1.5, 1);665 try test_u128_intFromFloat_f64(1.5, 1);
650 try test__fixunsdfti(1.99, 1);666 try test_u128_intFromFloat_f64(1.99, 1);
651 try test__fixunsdfti(2.0, 2);667 try test_u128_intFromFloat_f64(2.0, 2);
652 try test__fixunsdfti(2.01, 2);668 try test_u128_intFromFloat_f64(2.01, 2);
653 try test__fixunsdfti(-0.5, 0);669 try test_u128_intFromFloat_f64(-0.5, 0);
654 try test__fixunsdfti(-0.99, 0);670 try test_u128_intFromFloat_f64(-0.99, 0);
655 try test__fixunsdfti(-1.0, 0);671 try test_u128_intFromFloat_f64(-1.0, 0);
656 try test__fixunsdfti(-1.5, 0);672 try test_u128_intFromFloat_f64(-1.5, 0);
657 try test__fixunsdfti(-1.99, 0);673 try test_u128_intFromFloat_f64(-1.99, 0);
658 try test__fixunsdfti(-2.0, 0);674 try test_u128_intFromFloat_f64(-2.0, 0);
659 try test__fixunsdfti(-2.01, 0);675 try test_u128_intFromFloat_f64(-2.01, 0);
660676
661 try test__fixunsdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);677 try test_u128_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
662 try test__fixunsdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);678 try test_u128_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
663679
664 try test__fixunsdfti(-0x1.FFFFFEp+62, 0);680 try test_u128_intFromFloat_f64(-0x1.FFFFFEp+62, 0);
665 try test__fixunsdfti(-0x1.FFFFFCp+62, 0);681 try test_u128_intFromFloat_f64(-0x1.FFFFFCp+62, 0);
666682
667 try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800);683 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800);
668 try test__fixunsdfti(0x1.0000000000000p+63, 0x8000000000000000);684 try test_u128_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000);
669 try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);685 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
670 try test__fixunsdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);686 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
671687
672 try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+127, 0xFFFFFFFFFFFFF8000000000000000000);688 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+127, 0xFFFFFFFFFFFFF8000000000000000000);
673 try test__fixunsdfti(0x1.0000000000000p+127, 0x80000000000000000000000000000000);689 try test_u128_intFromFloat_f64(0x1.0000000000000p+127, 0x80000000000000000000000000000000);
674 try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);690 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);
675 try test__fixunsdfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);691 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);
676 try test__fixunsdfti(0x1.0000000000000p+128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);692 try test_u128_intFromFloat_f64(0x1.0000000000000p+128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
677693
678 try test__fixunsdfti(-0x1.FFFFFFFFFFFFFp+62, 0);694 try test_u128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, 0);
679 try test__fixunsdfti(-0x1.FFFFFFFFFFFFEp+62, 0);695 try test_u128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, 0);
680}696}
681697
682fn test_fixdfei(comptime T: type, expected: T, a: f64) !void {698fn test_intFromFloat_f64(comptime T: type, expected: T, a: f64) !void {
683 const int = @typeInfo(T).int;699 const int = @typeInfo(T).int;
684 var actual: T = undefined;700 var actual: T = undefined;
685 _ = switch (int.signedness) {701 _ = switch (int.signedness) {
686 .signed => __fixdfei,702 .signed => signed_intFromFloat_f64,
687 .unsigned => __fixunsdfei,703 .unsigned => unsigned_intFromFloat_f64,
688 }(@ptrCast(&actual), int.bits, a);704 }(@ptrCast(&actual), a);
689 try testing.expect(expected == actual);705 try testing.expect(expected == actual);
690}706}
691707
692test "fixdfei" {708test signed_intFromFloat_f64 {
693 try test_fixdfei(i256, -1 << 255, -0x1p255);709 try test_intFromFloat_f64(i256, -1 << 255, -0x1p255);
694 try test_fixdfei(i256, -1 << 127, -0x1p127);710 try test_intFromFloat_f64(i256, -1 << 127, -0x1p127);
695 try test_fixdfei(i256, -1 << 100, -0x1p100);711 try test_intFromFloat_f64(i256, -1 << 100, -0x1p100);
696 try test_fixdfei(i256, -1 << 50, -0x1p50);712 try test_intFromFloat_f64(i256, -1 << 50, -0x1p50);
697 try test_fixdfei(i256, -1 << 1, -0x1p1);713 try test_intFromFloat_f64(i256, -1 << 1, -0x1p1);
698 try test_fixdfei(i256, -1 << 0, -0x1p0);714 try test_intFromFloat_f64(i256, -1 << 0, -0x1p0);
699 try test_fixdfei(i256, 0, 0);715 try test_intFromFloat_f64(i256, 0, 0);
700 try test_fixdfei(i256, 1 << 0, 0x1p0);716 try test_intFromFloat_f64(i256, 1 << 0, 0x1p0);
701 try test_fixdfei(i256, 1 << 1, 0x1p1);717 try test_intFromFloat_f64(i256, 1 << 1, 0x1p1);
702 try test_fixdfei(i256, 1 << 50, 0x1p50);718 try test_intFromFloat_f64(i256, 1 << 50, 0x1p50);
703 try test_fixdfei(i256, 1 << 100, 0x1p100);719 try test_intFromFloat_f64(i256, 1 << 100, 0x1p100);
704 try test_fixdfei(i256, 1 << 127, 0x1p127);720 try test_intFromFloat_f64(i256, 1 << 127, 0x1p127);
705 try test_fixdfei(i256, 1 << 254, 0x1p254);721 try test_intFromFloat_f64(i256, 1 << 254, 0x1p254);
706}722}
707723
708test "fixundfei" {724test unsigned_intFromFloat_f64 {
709 try test_fixdfei(u256, 0, 0);725 try test_intFromFloat_f64(u256, 0, 0);
710 try test_fixdfei(u256, 1 << 0, 0x1p0);726 try test_intFromFloat_f64(u256, 1 << 0, 0x1p0);
711 try test_fixdfei(u256, 1 << 1, 0x1p1);727 try test_intFromFloat_f64(u256, 1 << 1, 0x1p1);
712 try test_fixdfei(u256, 1 << 50, 0x1p50);728 try test_intFromFloat_f64(u256, 1 << 50, 0x1p50);
713 try test_fixdfei(u256, 1 << 100, 0x1p100);729 try test_intFromFloat_f64(u256, 1 << 100, 0x1p100);
714 try test_fixdfei(u256, 1 << 127, 0x1p127);730 try test_intFromFloat_f64(u256, 1 << 127, 0x1p127);
715 try test_fixdfei(u256, 1 << 255, 0x1p255);731 try test_intFromFloat_f64(u256, 1 << 255, 0x1p255);
716}732}
717733
718fn test__fixtfsi(a: f128, expected: i32) !void {734fn test_i32_intFromFloat_f128(a: f128, expected: i32) !void {
719 const x = __fixtfsi(a);735 const x = i32_intFromFloat_f128(a);
720 try testing.expect(x == expected);736 try testing.expect(x == expected);
721}737}
722738
723fn test__fixunstfsi(a: f128, expected: u32) !void {739fn test_u32_intFromFloat_f128(a: f128, expected: u32) !void {
724 const x = __fixunstfsi(a);740 const x = u32_intFromFloat_f128(a);
725 try testing.expect(x == expected);741 try testing.expect(x == expected);
726}742}
727743
728test "fixtfsi" {744test i32_intFromFloat_f128 {
729 try test__fixtfsi(-math.floatMax(f128), math.minInt(i32));745 try test_i32_intFromFloat_f128(-math.floatMax(f128), math.minInt(i32));
730746
731 try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));747 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
732 try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);748 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
733749
734 try test__fixtfsi(-0x1.0000000000000p+127, -0x80000000);750 try test_i32_intFromFloat_f128(-0x1.0000000000000p+127, -0x80000000);
735 try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);751 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
736 try test__fixtfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);752 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
737753
738 try test__fixtfsi(-0x1.0000000000001p+63, -0x80000000);754 try test_i32_intFromFloat_f128(-0x1.0000000000001p+63, -0x80000000);
739 try test__fixtfsi(-0x1.0000000000000p+63, -0x80000000);755 try test_i32_intFromFloat_f128(-0x1.0000000000000p+63, -0x80000000);
740 try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);756 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);
741 try test__fixtfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);757 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);
742758
743 try test__fixtfsi(-0x1.FFFFFEp+62, -0x80000000);759 try test_i32_intFromFloat_f128(-0x1.FFFFFEp+62, -0x80000000);
744 try test__fixtfsi(-0x1.FFFFFCp+62, -0x80000000);760 try test_i32_intFromFloat_f128(-0x1.FFFFFCp+62, -0x80000000);
745761
746 try test__fixtfsi(-0x1.000000p+31, -0x80000000);762 try test_i32_intFromFloat_f128(-0x1.000000p+31, -0x80000000);
747 try test__fixtfsi(-0x1.FFFFFFp+30, -0x7FFFFFC0);763 try test_i32_intFromFloat_f128(-0x1.FFFFFFp+30, -0x7FFFFFC0);
748 try test__fixtfsi(-0x1.FFFFFEp+30, -0x7FFFFF80);764 try test_i32_intFromFloat_f128(-0x1.FFFFFEp+30, -0x7FFFFF80);
749 try test__fixtfsi(-0x1.FFFFFCp+30, -0x7FFFFF00);765 try test_i32_intFromFloat_f128(-0x1.FFFFFCp+30, -0x7FFFFF00);
750766
751 try test__fixtfsi(-2.01, -2);767 try test_i32_intFromFloat_f128(-2.01, -2);
752 try test__fixtfsi(-2.0, -2);768 try test_i32_intFromFloat_f128(-2.0, -2);
753 try test__fixtfsi(-1.99, -1);769 try test_i32_intFromFloat_f128(-1.99, -1);
754 try test__fixtfsi(-1.0, -1);770 try test_i32_intFromFloat_f128(-1.0, -1);
755 try test__fixtfsi(-0.99, 0);771 try test_i32_intFromFloat_f128(-0.99, 0);
756 try test__fixtfsi(-0.5, 0);772 try test_i32_intFromFloat_f128(-0.5, 0);
757 try test__fixtfsi(-math.floatMin(f32), 0);773 try test_i32_intFromFloat_f128(-math.floatMin(f32), 0);
758 try test__fixtfsi(0.0, 0);774 try test_i32_intFromFloat_f128(0.0, 0);
759 try test__fixtfsi(math.floatMin(f32), 0);775 try test_i32_intFromFloat_f128(math.floatMin(f32), 0);
760 try test__fixtfsi(0.5, 0);776 try test_i32_intFromFloat_f128(0.5, 0);
761 try test__fixtfsi(0.99, 0);777 try test_i32_intFromFloat_f128(0.99, 0);
762 try test__fixtfsi(1.0, 1);778 try test_i32_intFromFloat_f128(1.0, 1);
763 try test__fixtfsi(1.5, 1);779 try test_i32_intFromFloat_f128(1.5, 1);
764 try test__fixtfsi(1.99, 1);780 try test_i32_intFromFloat_f128(1.99, 1);
765 try test__fixtfsi(2.0, 2);781 try test_i32_intFromFloat_f128(2.0, 2);
766 try test__fixtfsi(2.01, 2);782 try test_i32_intFromFloat_f128(2.01, 2);
767783
768 try test__fixtfsi(0x1.FFFFFCp+30, 0x7FFFFF00);784 try test_i32_intFromFloat_f128(0x1.FFFFFCp+30, 0x7FFFFF00);
769 try test__fixtfsi(0x1.FFFFFEp+30, 0x7FFFFF80);785 try test_i32_intFromFloat_f128(0x1.FFFFFEp+30, 0x7FFFFF80);
770 try test__fixtfsi(0x1.FFFFFFp+30, 0x7FFFFFC0);786 try test_i32_intFromFloat_f128(0x1.FFFFFFp+30, 0x7FFFFFC0);
771 try test__fixtfsi(0x1.000000p+31, 0x7FFFFFFF);787 try test_i32_intFromFloat_f128(0x1.000000p+31, 0x7FFFFFFF);
772788
773 try test__fixtfsi(0x1.FFFFFCp+62, 0x7FFFFFFF);789 try test_i32_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFFFF);
774 try test__fixtfsi(0x1.FFFFFEp+62, 0x7FFFFFFF);790 try test_i32_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFFFF);
775791
776 try test__fixtfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);792 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
777 try test__fixtfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);793 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
778 try test__fixtfsi(0x1.0000000000000p+63, 0x7FFFFFFF);794 try test_i32_intFromFloat_f128(0x1.0000000000000p+63, 0x7FFFFFFF);
779 try test__fixtfsi(0x1.0000000000001p+63, 0x7FFFFFFF);795 try test_i32_intFromFloat_f128(0x1.0000000000001p+63, 0x7FFFFFFF);
780796
781 try test__fixtfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);797 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
782 try test__fixtfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);798 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
783 try test__fixtfsi(0x1.0000000000000p+127, 0x7FFFFFFF);799 try test_i32_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFF);
784800
785 try test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);801 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
786 try test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));802 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
787803
788 try test__fixtfsi(math.floatMax(f128), math.maxInt(i32));804 try test_i32_intFromFloat_f128(math.floatMax(f128), math.maxInt(i32));
789}805}
790806
791test "fixunstfsi" {807test u32_intFromFloat_f128 {
792 try test__fixunstfsi(math.inf(f128), 0xffffffff);808 try test_u32_intFromFloat_f128(math.inf(f128), 0xffffffff);
793 try test__fixunstfsi(0, 0x0);809 try test_u32_intFromFloat_f128(0, 0x0);
794 try test__fixunstfsi(0x1.23456789abcdefp+5, 0x24);810 try test_u32_intFromFloat_f128(0x1.23456789abcdefp+5, 0x24);
795 try test__fixunstfsi(0x1.23456789abcdefp-3, 0x0);811 try test_u32_intFromFloat_f128(0x1.23456789abcdefp-3, 0x0);
796 try test__fixunstfsi(0x1.23456789abcdefp+20, 0x123456);812 try test_u32_intFromFloat_f128(0x1.23456789abcdefp+20, 0x123456);
797 try test__fixunstfsi(0x1.23456789abcdefp+40, 0xffffffff);813 try test_u32_intFromFloat_f128(0x1.23456789abcdefp+40, 0xffffffff);
798 try test__fixunstfsi(0x1.23456789abcdefp+256, 0xffffffff);814 try test_u32_intFromFloat_f128(0x1.23456789abcdefp+256, 0xffffffff);
799 try test__fixunstfsi(-0x1.23456789abcdefp+3, 0x0);815 try test_u32_intFromFloat_f128(-0x1.23456789abcdefp+3, 0x0);
800816
801 try test__fixunstfsi(0x1p+32, 0xFFFFFFFF);817 try test_u32_intFromFloat_f128(0x1p+32, 0xFFFFFFFF);
802}818}
803819
804fn test__fixtfdi(a: f128, expected: i64) !void {820fn test_i64_intFromFloat_f128(a: f128, expected: i64) !void {
805 const x = __fixtfdi(a);821 const x = i64_intFromFloat_f128(a);
806 try testing.expect(x == expected);822 try testing.expect(x == expected);
807}823}
808824
809fn test__fixunstfdi(a: f128, expected: u64) !void {825fn test_u64_intFromFloat_f128(a: f128, expected: u64) !void {
810 const x = __fixunstfdi(a);826 const x = u64_intFromFloat_f128(a);
811 try testing.expect(x == expected);827 try testing.expect(x == expected);
812}828}
813829
814test "fixtfdi" {830test i64_intFromFloat_f128 {
815 try test__fixtfdi(-math.floatMax(f128), math.minInt(i64));831 try test_i64_intFromFloat_f128(-math.floatMax(f128), math.minInt(i64));
816832
817 try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));833 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
818 try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);834 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
819835
820 try test__fixtfdi(-0x1.0000000000000p+127, -0x8000000000000000);836 try test_i64_intFromFloat_f128(-0x1.0000000000000p+127, -0x8000000000000000);
821 try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);837 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
822 try test__fixtfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);838 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
823839
824 try test__fixtfdi(-0x1.0000000000001p+63, -0x8000000000000000);840 try test_i64_intFromFloat_f128(-0x1.0000000000001p+63, -0x8000000000000000);
825 try test__fixtfdi(-0x1.0000000000000p+63, -0x8000000000000000);841 try test_i64_intFromFloat_f128(-0x1.0000000000000p+63, -0x8000000000000000);
826 try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);842 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
827 try test__fixtfdi(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);843 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
828844
829 try test__fixtfdi(-0x1.FFFFFEp+62, -0x7FFFFF8000000000);845 try test_i64_intFromFloat_f128(-0x1.FFFFFEp+62, -0x7FFFFF8000000000);
830 try test__fixtfdi(-0x1.FFFFFCp+62, -0x7FFFFF0000000000);846 try test_i64_intFromFloat_f128(-0x1.FFFFFCp+62, -0x7FFFFF0000000000);
831847
832 try test__fixtfdi(-0x1.000000p+31, -0x80000000);848 try test_i64_intFromFloat_f128(-0x1.000000p+31, -0x80000000);
833 try test__fixtfdi(-0x1.FFFFFFp+30, -0x7FFFFFC0);849 try test_i64_intFromFloat_f128(-0x1.FFFFFFp+30, -0x7FFFFFC0);
834 try test__fixtfdi(-0x1.FFFFFEp+30, -0x7FFFFF80);850 try test_i64_intFromFloat_f128(-0x1.FFFFFEp+30, -0x7FFFFF80);
835 try test__fixtfdi(-0x1.FFFFFCp+30, -0x7FFFFF00);851 try test_i64_intFromFloat_f128(-0x1.FFFFFCp+30, -0x7FFFFF00);
836852
837 try test__fixtfdi(-2.01, -2);853 try test_i64_intFromFloat_f128(-2.01, -2);
838 try test__fixtfdi(-2.0, -2);854 try test_i64_intFromFloat_f128(-2.0, -2);
839 try test__fixtfdi(-1.99, -1);855 try test_i64_intFromFloat_f128(-1.99, -1);
840 try test__fixtfdi(-1.0, -1);856 try test_i64_intFromFloat_f128(-1.0, -1);
841 try test__fixtfdi(-0.99, 0);857 try test_i64_intFromFloat_f128(-0.99, 0);
842 try test__fixtfdi(-0.5, 0);858 try test_i64_intFromFloat_f128(-0.5, 0);
843 try test__fixtfdi(-math.floatMin(f64), 0);859 try test_i64_intFromFloat_f128(-math.floatMin(f64), 0);
844 try test__fixtfdi(0.0, 0);860 try test_i64_intFromFloat_f128(0.0, 0);
845 try test__fixtfdi(math.floatMin(f64), 0);861 try test_i64_intFromFloat_f128(math.floatMin(f64), 0);
846 try test__fixtfdi(0.5, 0);862 try test_i64_intFromFloat_f128(0.5, 0);
847 try test__fixtfdi(0.99, 0);863 try test_i64_intFromFloat_f128(0.99, 0);
848 try test__fixtfdi(1.0, 1);864 try test_i64_intFromFloat_f128(1.0, 1);
849 try test__fixtfdi(1.5, 1);865 try test_i64_intFromFloat_f128(1.5, 1);
850 try test__fixtfdi(1.99, 1);866 try test_i64_intFromFloat_f128(1.99, 1);
851 try test__fixtfdi(2.0, 2);867 try test_i64_intFromFloat_f128(2.0, 2);
852 try test__fixtfdi(2.01, 2);868 try test_i64_intFromFloat_f128(2.01, 2);
853869
854 try test__fixtfdi(0x1.FFFFFCp+30, 0x7FFFFF00);870 try test_i64_intFromFloat_f128(0x1.FFFFFCp+30, 0x7FFFFF00);
855 try test__fixtfdi(0x1.FFFFFEp+30, 0x7FFFFF80);871 try test_i64_intFromFloat_f128(0x1.FFFFFEp+30, 0x7FFFFF80);
856 try test__fixtfdi(0x1.FFFFFFp+30, 0x7FFFFFC0);872 try test_i64_intFromFloat_f128(0x1.FFFFFFp+30, 0x7FFFFFC0);
857 try test__fixtfdi(0x1.000000p+31, 0x80000000);873 try test_i64_intFromFloat_f128(0x1.000000p+31, 0x80000000);
858874
859 try test__fixtfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);875 try test_i64_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
860 try test__fixtfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);876 try test_i64_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
861877
862 try test__fixtfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);878 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
863 try test__fixtfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);879 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
864 try test__fixtfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);880 try test_i64_intFromFloat_f128(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
865 try test__fixtfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);881 try test_i64_intFromFloat_f128(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
866882
867 try test__fixtfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);883 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
868 try test__fixtfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);884 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
869 try test__fixtfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);885 try test_i64_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
870886
871 try test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);887 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
872 try test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));888 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
873889
874 try test__fixtfdi(math.floatMax(f128), math.maxInt(i64));890 try test_i64_intFromFloat_f128(math.floatMax(f128), math.maxInt(i64));
875}891}
876892
877test "fixunstfdi" {893test u64_intFromFloat_f128 {
878 try test__fixunstfdi(0.0, 0);894 try test_u64_intFromFloat_f128(0.0, 0);
879895
880 try test__fixunstfdi(0.5, 0);896 try test_u64_intFromFloat_f128(0.5, 0);
881 try test__fixunstfdi(0.99, 0);897 try test_u64_intFromFloat_f128(0.99, 0);
882 try test__fixunstfdi(1.0, 1);898 try test_u64_intFromFloat_f128(1.0, 1);
883 try test__fixunstfdi(1.5, 1);899 try test_u64_intFromFloat_f128(1.5, 1);
884 try test__fixunstfdi(1.99, 1);900 try test_u64_intFromFloat_f128(1.99, 1);
885 try test__fixunstfdi(2.0, 2);901 try test_u64_intFromFloat_f128(2.0, 2);
886 try test__fixunstfdi(2.01, 2);902 try test_u64_intFromFloat_f128(2.01, 2);
887 try test__fixunstfdi(-0.5, 0);903 try test_u64_intFromFloat_f128(-0.5, 0);
888 try test__fixunstfdi(-0.99, 0);904 try test_u64_intFromFloat_f128(-0.99, 0);
889 try test__fixunstfdi(-1.0, 0);905 try test_u64_intFromFloat_f128(-1.0, 0);
890 try test__fixunstfdi(-1.5, 0);906 try test_u64_intFromFloat_f128(-1.5, 0);
891 try test__fixunstfdi(-1.99, 0);907 try test_u64_intFromFloat_f128(-1.99, 0);
892 try test__fixunstfdi(-2.0, 0);908 try test_u64_intFromFloat_f128(-2.0, 0);
893 try test__fixunstfdi(-2.01, 0);909 try test_u64_intFromFloat_f128(-2.01, 0);
894910
895 try test__fixunstfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);911 try test_u64_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
896 try test__fixunstfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);912 try test_u64_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
897913
898 try test__fixunstfdi(-0x1.FFFFFEp+62, 0);914 try test_u64_intFromFloat_f128(-0x1.FFFFFEp+62, 0);
899 try test__fixunstfdi(-0x1.FFFFFCp+62, 0);915 try test_u64_intFromFloat_f128(-0x1.FFFFFCp+62, 0);
900916
901 try test__fixunstfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);917 try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
902 try test__fixunstfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);918 try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
903919
904 try test__fixunstfdi(-0x1.FFFFFFFFFFFFFp+62, 0);920 try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, 0);
905 try test__fixunstfdi(-0x1.FFFFFFFFFFFFEp+62, 0);921 try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, 0);
906922
907 try test__fixunstfdi(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF);923 try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF);
908 try test__fixunstfdi(0x1.0000000000000002p+63, 0x8000000000000001);924 try test_u64_intFromFloat_f128(0x1.0000000000000002p+63, 0x8000000000000001);
909 try test__fixunstfdi(0x1.0000000000000000p+63, 0x8000000000000000);925 try test_u64_intFromFloat_f128(0x1.0000000000000000p+63, 0x8000000000000000);
910 try test__fixunstfdi(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF);926 try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF);
911 try test__fixunstfdi(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE);927 try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE);
912 try test__fixunstfdi(0x1p+64, 0xFFFFFFFFFFFFFFFF);928 try test_u64_intFromFloat_f128(0x1p+64, 0xFFFFFFFFFFFFFFFF);
913929
914 try test__fixunstfdi(-0x1.0000000000000000p+63, 0);930 try test_u64_intFromFloat_f128(-0x1.0000000000000000p+63, 0);
915 try test__fixunstfdi(-0x1.FFFFFFFFFFFFFFFCp+62, 0);931 try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFFFCp+62, 0);
916 try test__fixunstfdi(-0x1.FFFFFFFFFFFFFFF8p+62, 0);932 try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFFF8p+62, 0);
917}933}
918934
919fn test__fixtfti(a: f128, expected: i128) !void {935fn test_i128_intFromFloat_f128(a: f128, expected: i128) !void {
920 const x = __fixtfti(a);936 const x = i128_intFromFloat_f128(a);
921 try testing.expect(x == expected);937 try testing.expect(x == expected);
922}938}
923939
924fn test__fixunstfti(a: f128, expected: u128) !void {940fn test_u128_intFromFloat_f128(a: f128, expected: u128) !void {
925 const x = __fixunstfti(a);941 const x = u128_intFromFloat_f128(a);
926 try testing.expect(x == expected);942 try testing.expect(x == expected);
927}943}
928944
929test "fixtfti" {945test i128_intFromFloat_f128 {
930 try test__fixtfti(-math.floatMax(f128), math.minInt(i128));946 try test_i128_intFromFloat_f128(-math.floatMax(f128), math.minInt(i128));
931947
932 try test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));948 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
933 try test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);949 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
934950
935 try test__fixtfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);951 try test_i128_intFromFloat_f128(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
936 try test__fixtfti(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000);952 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000);
937 try test__fixtfti(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000);953 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000);
938954
939 try test__fixtfti(-0x1.0000000000001p+63, -0x8000000000000800);955 try test_i128_intFromFloat_f128(-0x1.0000000000001p+63, -0x8000000000000800);
940 try test__fixtfti(-0x1.0000000000000p+63, -0x8000000000000000);956 try test_i128_intFromFloat_f128(-0x1.0000000000000p+63, -0x8000000000000000);
941 try test__fixtfti(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);957 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
942 try test__fixtfti(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);958 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
943959
944 try test__fixtfti(-0x1.FFFFFEp+62, -0x7fffff8000000000);960 try test_i128_intFromFloat_f128(-0x1.FFFFFEp+62, -0x7fffff8000000000);
945 try test__fixtfti(-0x1.FFFFFCp+62, -0x7fffff0000000000);961 try test_i128_intFromFloat_f128(-0x1.FFFFFCp+62, -0x7fffff0000000000);
946962
947 try test__fixtfti(-2.01, -2);963 try test_i128_intFromFloat_f128(-2.01, -2);
948 try test__fixtfti(-2.0, -2);964 try test_i128_intFromFloat_f128(-2.0, -2);
949 try test__fixtfti(-1.99, -1);965 try test_i128_intFromFloat_f128(-1.99, -1);
950 try test__fixtfti(-1.0, -1);966 try test_i128_intFromFloat_f128(-1.0, -1);
951 try test__fixtfti(-0.99, 0);967 try test_i128_intFromFloat_f128(-0.99, 0);
952 try test__fixtfti(-0.5, 0);968 try test_i128_intFromFloat_f128(-0.5, 0);
953 try test__fixtfti(-math.floatMin(f128), 0);969 try test_i128_intFromFloat_f128(-math.floatMin(f128), 0);
954 try test__fixtfti(0.0, 0);970 try test_i128_intFromFloat_f128(0.0, 0);
955 try test__fixtfti(math.floatMin(f128), 0);971 try test_i128_intFromFloat_f128(math.floatMin(f128), 0);
956 try test__fixtfti(0.5, 0);972 try test_i128_intFromFloat_f128(0.5, 0);
957 try test__fixtfti(0.99, 0);973 try test_i128_intFromFloat_f128(0.99, 0);
958 try test__fixtfti(1.0, 1);974 try test_i128_intFromFloat_f128(1.0, 1);
959 try test__fixtfti(1.5, 1);975 try test_i128_intFromFloat_f128(1.5, 1);
960 try test__fixtfti(1.99, 1);976 try test_i128_intFromFloat_f128(1.99, 1);
961 try test__fixtfti(2.0, 2);977 try test_i128_intFromFloat_f128(2.0, 2);
962 try test__fixtfti(2.01, 2);978 try test_i128_intFromFloat_f128(2.01, 2);
963979
964 try test__fixtfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);980 try test_i128_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
965 try test__fixtfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);981 try test_i128_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
966982
967 try test__fixtfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);983 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
968 try test__fixtfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);984 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
969 try test__fixtfti(0x1.0000000000000p+63, 0x8000000000000000);985 try test_i128_intFromFloat_f128(0x1.0000000000000p+63, 0x8000000000000000);
970 try test__fixtfti(0x1.0000000000001p+63, 0x8000000000000800);986 try test_i128_intFromFloat_f128(0x1.0000000000001p+63, 0x8000000000000800);
971987
972 try test__fixtfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);988 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);
973 try test__fixtfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);989 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);
974 try test__fixtfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);990 try test_i128_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
975991
976 try test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);992 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
977 try test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));993 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
978994
979 try test__fixtfti(math.floatMax(f128), math.maxInt(i128));995 try test_i128_intFromFloat_f128(math.floatMax(f128), math.maxInt(i128));
980}996}
981997
982test "fixunstfti" {998test u128_intFromFloat_f128 {
983 try test__fixunstfti(math.inf(f128), 0xffffffffffffffffffffffffffffffff);999 try test_u128_intFromFloat_f128(math.inf(f128), 0xffffffffffffffffffffffffffffffff);
9841000
985 try test__fixunstfti(0.0, 0);1001 try test_u128_intFromFloat_f128(0.0, 0);
9861002
987 try test__fixunstfti(0.5, 0);1003 try test_u128_intFromFloat_f128(0.5, 0);
988 try test__fixunstfti(0.99, 0);1004 try test_u128_intFromFloat_f128(0.99, 0);
989 try test__fixunstfti(1.0, 1);1005 try test_u128_intFromFloat_f128(1.0, 1);
990 try test__fixunstfti(1.5, 1);1006 try test_u128_intFromFloat_f128(1.5, 1);
991 try test__fixunstfti(1.99, 1);1007 try test_u128_intFromFloat_f128(1.99, 1);
992 try test__fixunstfti(2.0, 2);1008 try test_u128_intFromFloat_f128(2.0, 2);
993 try test__fixunstfti(2.01, 2);1009 try test_u128_intFromFloat_f128(2.01, 2);
994 try test__fixunstfti(-0.01, 0);1010 try test_u128_intFromFloat_f128(-0.01, 0);
995 try test__fixunstfti(-0.99, 0);1011 try test_u128_intFromFloat_f128(-0.99, 0);
9961012
997 try test__fixunstfti(0x1p+128, 0xffffffffffffffffffffffffffffffff);1013 try test_u128_intFromFloat_f128(0x1p+128, 0xffffffffffffffffffffffffffffffff);
9981014
999 try test__fixunstfti(0x1.FFFFFEp+126, 0x7fffff80000000000000000000000000);1015 try test_u128_intFromFloat_f128(0x1.FFFFFEp+126, 0x7fffff80000000000000000000000000);
1000 try test__fixunstfti(0x1.FFFFFEp+127, 0xffffff00000000000000000000000000);1016 try test_u128_intFromFloat_f128(0x1.FFFFFEp+127, 0xffffff00000000000000000000000000);
1001 try test__fixunstfti(0x1.FFFFFEp+128, 0xffffffffffffffffffffffffffffffff);1017 try test_u128_intFromFloat_f128(0x1.FFFFFEp+128, 0xffffffffffffffffffffffffffffffff);
1002 try test__fixunstfti(0x1.FFFFFEp+129, 0xffffffffffffffffffffffffffffffff);1018 try test_u128_intFromFloat_f128(0x1.FFFFFEp+129, 0xffffffffffffffffffffffffffffffff);
1003}1019}
10041020
1005fn test__fixunshfti(a: f16, expected: u128) !void {1021fn test_u128_intFromFloat_f16(a: f16, expected: u128) !void {
1006 const x = __fixunshfti(a);1022 const x = impl.u128_intFromFloat_f16(a);
1007 try testing.expect(x == expected);1023 try testing.expect(x == expected);
1008}1024}
10091025
1010test "fixunshfti for f16" {1026test u128_intFromFloat_f16 {
1011 try test__fixunshfti(math.inf(f16), math.maxInt(u128));1027 try test_u128_intFromFloat_f16(math.inf(f16), math.maxInt(u128));
1012 try test__fixunshfti(math.floatMax(f16), 65504);1028 try test_u128_intFromFloat_f16(math.floatMax(f16), 65504);
1013}1029}
10141030
1015fn test__fixunsxfti(a: f80, expected: u128) !void {1031fn test_u128_intFromFloat_f80(a: f80, expected: u128) !void {
1016 const x = __fixunsxfti(a);1032 const x = impl.u128_intFromFloat_f80(a);
1017 try testing.expect(x == expected);1033 try testing.expect(x == expected);
1018}1034}
10191035
1020test "fixunsxfti for f80" {1036test u128_intFromFloat_f80 {
1021 try test__fixunsxfti(math.inf(f80), math.maxInt(u128));1037 try test_u128_intFromFloat_f80(math.inf(f80), math.maxInt(u128));
1022 try test__fixunsxfti(math.floatMax(f80), math.maxInt(u128));1038 try test_u128_intFromFloat_f80(math.floatMax(f80), math.maxInt(u128));
1023 try test__fixunsxfti(math.maxInt(u64), math.maxInt(u64));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,7 +6,7 @@ const minInt = std.math.minInt;
66
7const builtin = @import("builtin");7const builtin = @import("builtin");
8const compiler_rt = @import("../compiler_rt.zig");8const compiler_rt = @import("../compiler_rt.zig");
9const symbol = @import("../compiler_rt.zig").symbol;9const symbol = compiler_rt.symbol;
1010
11const endian = builtin.cpu.arch.endian();11const endian = builtin.cpu.arch.endian();
1212
lib/compiler_rt/log.zig+112-97
...@@ -11,7 +11,7 @@ const expectEqual = std.testing.expectEqual;...@@ -11,7 +11,7 @@ const expectEqual = std.testing.expectEqual;
11const expectApproxEqRel = std.testing.expectApproxEqRel;11const expectApproxEqRel = std.testing.expectApproxEqRel;
1212
13const compiler_rt = @import("../compiler_rt.zig");13const compiler_rt = @import("../compiler_rt.zig");
14const symbol = @import("../compiler_rt.zig").symbol;14const symbol = compiler_rt.symbol;
1515
16comptime {16comptime {
17 symbol(&__logh, "__logh");17 symbol(&__logh, "__logh");
...@@ -25,12 +25,18 @@ comptime {...@@ -25,12 +25,18 @@ comptime {
25 symbol(&logl, "logl");25 symbol(&logl, "logl");
26}26}
2727
28pub fn __logh(a: f16) callconv(.c) f16 {28fn __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}
31pub fn log_f16(a: f16) f16 {
29 // TODO: more efficient implementation32 // TODO: more efficient implementation
30 return @floatCast(logf(a));33 return @floatCast(log_f32(a));
31}34}
3235
33pub fn logf(x_: f32) callconv(.c) f32 {36fn 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}
39pub fn log_f32(x_: f32) f32 {
34 const ln2_hi: f32 = 6.9313812256e-01;40 const ln2_hi: f32 = 6.9313812256e-01;
35 const ln2_lo: f32 = 9.0580006145e-06;41 const ln2_lo: f32 = 9.0580006145e-06;
36 const Lg1: f32 = 0xaaaaaa.0p-24;42 const Lg1: f32 = 0xaaaaaa.0p-24;
...@@ -82,7 +88,10 @@ pub fn logf(x_: f32) callconv(.c) f32 {...@@ -82,7 +88,10 @@ pub fn logf(x_: f32) callconv(.c) f32 {
82 return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;88 return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
83}89}
8490
85pub fn log(x: f64) callconv(.c) f64 {91fn 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}
94pub fn log_f64(x: f64) f64 {
86 const poly1 = [_]f64{95 const poly1 = [_]f64{
87 -0x1p-1,96 -0x1p-1,
88 0x1.5555555555577p-2,97 0x1.5555555555577p-2,
...@@ -432,11 +441,17 @@ pub fn log(x: f64) callconv(.c) f64 {...@@ -432,11 +441,17 @@ pub fn log(x: f64) callconv(.c) f64 {
432 return @bitCast(y);441 return @bitCast(y);
433}442}
434443
435pub fn __logx(a: f80) callconv(.c) f80 {444fn __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}
447pub fn log_f80(a: f80) f80 {
436 // TODO: more efficient implementation448 // TODO: more efficient implementation
437 return @floatCast(logq(a));449 return @floatCast(log_f128(a));
438}450}
439451
452fn 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/// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic"455/// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic"
441/// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990456/// 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,7 +464,7 @@ pub fn __logx(a: f80) callconv(.c) f80 {
449///464///
450/// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case):465/// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case):
451/// <= 0.5 ulp: 99.96%, worst case <= 0.528 ulp466/// <= 0.5 ulp: 99.96%, worst case <= 0.528 ulp
452pub fn logq(x: f128) callconv(.c) f128 {467pub fn log_f128(x: f128) f128 {
453 const impl = @import("log_f128.zig");468 const impl = @import("log_f128.zig");
454469
455 if (impl.specialCases(x)) |y|470 if (impl.specialCases(x)) |y|
...@@ -626,123 +641,123 @@ pub fn logq(x: f128) callconv(.c) f128 {...@@ -626,123 +641,123 @@ pub fn logq(x: f128) callconv(.c) f128 {
626641
627pub fn logl(x: c_longdouble) callconv(.c) c_longdouble {642pub fn logl(x: c_longdouble) callconv(.c) c_longdouble {
628 switch (@typeInfo(c_longdouble).float.bits) {643 switch (@typeInfo(c_longdouble).float.bits) {
629 64 => return log(x),644 64 => return log_f64(x),
630 80 => return __logx(x),645 80 => return log_f80(x),
631 128 => return logq(x),646 128 => return log_f128(x),
632 else => @compileError("unreachable"),647 else => comptime unreachable,
633 }648 }
634}649}
635650
636test "logf() special" {651test "logf() special" {
637 try expectEqual(logf(0.0), -math.inf(f32));652 try expectEqual(log_f32(0.0), -math.inf(f32));
638 try expectEqual(logf(-0.0), -math.inf(f32));653 try expectEqual(log_f32(-0.0), -math.inf(f32));
639 try expect(math.isPositiveZero(logf(1.0)));654 try expect(math.isPositiveZero(log_f32(1.0)));
640 try expectEqual(logf(math.e), 1.0);655 try expectEqual(log_f32(math.e), 1.0);
641 try expectEqual(logf(math.inf(f32)), math.inf(f32));656 try expectEqual(log_f32(math.inf(f32)), math.inf(f32));
642 try expect(math.isNan(logf(-1.0)));657 try expect(math.isNan(log_f32(-1.0)));
643 try expect(math.isNan(logf(-math.inf(f32))));658 try expect(math.isNan(log_f32(-math.inf(f32))));
644 try expect(math.isNan(logf(math.nan(f32))));659 try expect(math.isNan(log_f32(math.nan(f32))));
645 try expect(math.isNan(logf(math.snan(f32))));660 try expect(math.isNan(log_f32(math.snan(f32))));
646}661}
647662
648test "logf() sanity" {663test "logf() sanity" {
649 try expect(math.isNan(logf(-0x1.0223a0p+3)));664 try expect(math.isNan(log_f32(-0x1.0223a0p+3)));
650 try expectEqual(logf(0x1.161868p+2), 0x1.7815b0p+0);665 try expectEqual(log_f32(0x1.161868p+2), 0x1.7815b0p+0);
651 try expect(math.isNan(logf(-0x1.0c34b4p+3)));666 try expect(math.isNan(log_f32(-0x1.0c34b4p+3)));
652 try expect(math.isNan(logf(-0x1.a206f0p+2)));667 try expect(math.isNan(log_f32(-0x1.a206f0p+2)));
653 try expectEqual(logf(0x1.288bbcp+3), 0x1.1cfcd6p+1);668 try expectEqual(log_f32(0x1.288bbcp+3), 0x1.1cfcd6p+1);
654 try expectEqual(logf(0x1.52efd0p-1), -0x1.a6694cp-2);669 try expectEqual(log_f32(0x1.52efd0p-1), -0x1.a6694cp-2);
655 try expect(math.isNan(logf(-0x1.a05cc8p-2)));670 try expect(math.isNan(log_f32(-0x1.a05cc8p-2)));
656 try expectEqual(logf(0x1.1f9efap-1), -0x1.2742bap-1);671 try expectEqual(log_f32(0x1.1f9efap-1), -0x1.2742bap-1);
657 try expectEqual(logf(0x1.8c5db0p-1), -0x1.062160p-2);672 try expectEqual(log_f32(0x1.8c5db0p-1), -0x1.062160p-2);
658 try expect(math.isNan(logf(-0x1.5b86eap-1)));673 try expect(math.isNan(log_f32(-0x1.5b86eap-1)));
659}674}
660675
661test "logf() boundary" {676test "logf() boundary" {
662 try expectEqual(logf(0x1.fffffep+127), 0x1.62e430p+6); // Max input value677 try expectEqual(log_f32(0x1.fffffep+127), 0x1.62e430p+6); // Max input value
663 try expectEqual(logf(0x1p-149), -0x1.9d1da0p+6); // Min positive input value678 try expectEqual(log_f32(0x1p-149), -0x1.9d1da0p+6); // Min positive input value
664 try expect(math.isNan(logf(-0x1p-149))); // Min negative input value679 try expect(math.isNan(log_f32(-0x1p-149))); // Min negative input value
665 try expectEqual(logf(0x1.000002p+0), 0x1.fffffep-24); // Last value before result reaches +0680 try expectEqual(log_f32(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 -0681 try expectEqual(log_f32(0x1.fffffep-1), -0x1p-24); // Last value before result reaches -0
667 try expectEqual(logf(0x1p-126), -0x1.5d58a0p+6); // First subnormal682 try expectEqual(log_f32(0x1p-126), -0x1.5d58a0p+6); // First subnormal
668 try expect(math.isNan(logf(-0x1p-126))); // First negative subnormal683 try expect(math.isNan(log_f32(-0x1p-126))); // First negative subnormal
669}684}
670685
671test "log() special" {686test "log() special" {
672 try expectEqual(log(0.0), -math.inf(f64));687 try expectEqual(log_f64(0.0), -math.inf(f64));
673 try expectEqual(log(-0.0), -math.inf(f64));688 try expectEqual(log_f64(-0.0), -math.inf(f64));
674 try expect(math.isPositiveZero(log(1.0)));689 try expect(math.isPositiveZero(log_f64(1.0)));
675 try expectEqual(log(math.e), 1.0);690 try expectEqual(log_f64(math.e), 1.0);
676 try expectEqual(log(math.inf(f64)), math.inf(f64));691 try expectEqual(log_f64(math.inf(f64)), math.inf(f64));
677 try expect(math.isNan(log(-1.0)));692 try expect(math.isNan(log_f64(-1.0)));
678 try expect(math.isNan(log(-math.inf(f64))));693 try expect(math.isNan(log_f64(-math.inf(f64))));
679 try expect(math.isNan(log(math.nan(f64))));694 try expect(math.isNan(log_f64(math.nan(f64))));
680 try expect(math.isNan(log(math.snan(f64))));695 try expect(math.isNan(log_f64(math.snan(f64))));
681}696}
682697
683test "log() sanity" {698test "log() sanity" {
684 try expect(math.isNan(log(-0x1.02239f3c6a8f1p+3)));699 try expect(math.isNan(log_f64(-0x1.02239f3c6a8f1p+3)));
685 try expectEqual(log(0x1.161868e18bc67p+2), 0x1.7815b08f99c65p+0);700 try expectEqual(log_f64(0x1.161868e18bc67p+2), 0x1.7815b08f99c65p+0);
686 try expect(math.isNan(log(-0x1.0c34b3e01e6e7p+3)));701 try expect(math.isNan(log_f64(-0x1.0c34b3e01e6e7p+3)));
687 try expect(math.isNan(log(-0x1.a206f0a19dcc4p+2)));702 try expect(math.isNan(log_f64(-0x1.a206f0a19dcc4p+2)));
688 try expectEqual(log(0x1.288bbb0d6a1e6p+3), 0x1.1cfcd53d72604p+1);703 try expectEqual(log_f64(0x1.288bbb0d6a1e6p+3), 0x1.1cfcd53d72604p+1);
689 try expectEqual(log(0x1.52efd0cd80497p-1), -0x1.a6694a4a85621p-2);704 try expectEqual(log_f64(0x1.52efd0cd80497p-1), -0x1.a6694a4a85621p-2);
690 try expect(math.isNan(log(-0x1.a05cc754481d1p-2)));705 try expect(math.isNan(log_f64(-0x1.a05cc754481d1p-2)));
691 try expectEqual(log(0x1.1f9ef934745cbp-1), -0x1.2742bc03d02ddp-1);706 try expectEqual(log_f64(0x1.1f9ef934745cbp-1), -0x1.2742bc03d02ddp-1);
692 try expectEqual(log(0x1.8c5db097f7442p-1), -0x1.06215de4a3f92p-2);707 try expectEqual(log_f64(0x1.8c5db097f7442p-1), -0x1.06215de4a3f92p-2);
693 try expect(math.isNan(log(-0x1.5b86ea8118a0ep-1)));708 try expect(math.isNan(log_f64(-0x1.5b86ea8118a0ep-1)));
694}709}
695710
696test "log() boundary" {711test "log() boundary" {
697 try expectEqual(log(0x1.fffffffffffffp+1023), 0x1.62e42fefa39efp+9); // Max input value712 try expectEqual(log_f64(0x1.fffffffffffffp+1023), 0x1.62e42fefa39efp+9); // Max input value
698 try expectEqual(log(0x1p-1074), -0x1.74385446d71c3p+9); // Min positive input value713 try expectEqual(log_f64(0x1p-1074), -0x1.74385446d71c3p+9); // Min positive input value
699 try expect(math.isNan(log(-0x1p-1074))); // Min negative input value714 try expect(math.isNan(log_f64(-0x1p-1074))); // Min negative input value
700 try expectEqual(log(0x1.0000000000001p+0), 0x1.fffffffffffffp-53); // Last value before result reaches +0715 try expectEqual(log_f64(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 -0716 try expectEqual(log_f64(0x1.fffffffffffffp-1), -0x1p-53); // Last value before result reaches -0
702 try expectEqual(log(0x1p-1022), -0x1.6232bdd7abcd2p+9); // First subnormal717 try expectEqual(log_f64(0x1p-1022), -0x1.6232bdd7abcd2p+9); // First subnormal
703 try expect(math.isNan(log(-0x1p-1022))); // First negative subnormal718 try expect(math.isNan(log_f64(-0x1p-1022))); // First negative subnormal
704}719}
705720
706test "logq() special" {721test "logq() special" {
707 try expectEqual(logq(0.0), -math.inf(f128));722 try expectEqual(log_f128(0.0), -math.inf(f128));
708 try expectEqual(logq(-0.0), -math.inf(f128));723 try expectEqual(log_f128(-0.0), -math.inf(f128));
709 try expect(math.isPositiveZero(logq(1.0)));724 try expect(math.isPositiveZero(log_f128(1.0)));
710 // Sadly, the rounding gods decided that 0.9999999999999999999999999999999999725 // Sadly, the rounding gods decided that 0.9999999999999999999999999999999999
711 // is the correctly rounded value of logq(math.e)726 // is the correctly rounded value of log_f128(math.e)
712 try expectApproxEqRel(logq(math.e), 1.0, math.floatEpsAt(f128, 1.0));727 try expectApproxEqRel(log_f128(math.e), 1.0, math.floatEpsAt(f128, 1.0));
713 try expectEqual(logq(math.inf(f128)), math.inf(f128));728 try expectEqual(log_f128(math.inf(f128)), math.inf(f128));
714 try expect(math.isNan(logq(-1.0)));729 try expect(math.isNan(log_f128(-1.0)));
715 try expect(math.isNan(logq(-math.inf(f128))));730 try expect(math.isNan(log_f128(-math.inf(f128))));
716 try expect(math.isNan(logq(math.nan(f128))));731 try expect(math.isNan(log_f128(math.nan(f128))));
717 try expect(math.isNan(logq(math.snan(f128))));732 try expect(math.isNan(log_f128(math.snan(f128))));
718}733}
719734
720test "logq() boundary" {735test "logq() boundary" {
721 try expectEqual(logq(0x1.ffffffffffffffffffffffffffffp16383), 0x1.62e42fefa39ef35793c7673007e6p13); // Max input value736 try expectEqual(log_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1.62e42fefa39ef35793c7673007e6p13); // Max input value
722 try expectEqual(logq(0x1p-16494), -0x1.6546282207802c89d24d65e96274p13); // Min positive input value737 try expectEqual(log_f128(0x1p-16494), -0x1.6546282207802c89d24d65e96274p13); // Min positive input value
723 try expect(math.isNan(logq(-0x1p-16494))); // Min negative input value738 try expect(math.isNan(log_f128(-0x1p-16494))); // Min negative input value
724 try expectEqual(logq(0x1.0000000000000000000000000001p0), 0x1.ffffffffffffffffffffffffffffp-113); // Last value before result reaches +0739 try expectEqual(log_f128(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 -0740 try expectEqual(log_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1p-113); // Last value before result reaches -0
726 try expectEqual(logq(0x1p-16382), -0x1.62d918ce2421d65ff90ac8f4ce66p13); // First subnormal741 try expectEqual(log_f128(0x1p-16382), -0x1.62d918ce2421d65ff90ac8f4ce66p13); // First subnormal
727 try expect(math.isNan(logq(-0x1p-16382))); // First negative subnormal742 try expect(math.isNan(log_f128(-0x1p-16382))); // First negative subnormal
728}743}
729744
730test "logq() sanity" {745test "logq() sanity" {
731 try expectEqual(logq(4.151135979023751199079583784623537e-4), -7.7869583453055243113993340258295346e0);746 try expectEqual(log_f128(4.151135979023751199079583784623537e-4), -7.7869583453055243113993340258295346e0);
732 try expectEqual(logq(9.614234245933828353176667689130293e-14), -2.9972946567656004014786271559909435e1);747 try expectEqual(log_f128(9.614234245933828353176667689130293e-14), -2.9972946567656004014786271559909435e1);
733 try expectEqual(logq(1.012889803704721484375e13), 2.9946413646144315985379677542014356e1);748 try expectEqual(log_f128(1.012889803704721484375e13), 2.9946413646144315985379677542014356e1);
734 try expectEqual(logq(2.397741857206453154086912e24), 5.613656963346284538829358703465392e1);749 try expectEqual(log_f128(2.397741857206453154086912e24), 5.613656963346284538829358703465392e1);
735 try expectEqual(logq(3.442377567808290806386655232e27), 6.3405959896920645453203836625419693e1);750 try expectEqual(log_f128(3.442377567808290806386655232e27), 6.3405959896920645453203836625419693e1);
736 try expectEqual(logq(1.0689155158234028407981544637594257e-8), -1.835403614606774451014272772421113e1);751 try expectEqual(log_f128(1.0689155158234028407981544637594257e-8), -1.835403614606774451014272772421113e1);
737 try expectEqual(logq(1.4813913545768791536741499811327596e-10), -2.263286917934202003739900705050399e1);752 try expectEqual(log_f128(1.4813913545768791536741499811327596e-10), -2.263286917934202003739900705050399e1);
738 try expectEqual(logq(4.518948965781299591064453125e10), 2.453413036705097282892685629562292e1);753 try expectEqual(log_f128(4.518948965781299591064453125e10), 2.453413036705097282892685629562292e1);
739 try expectEqual(logq(1.200355637363589375e14), 3.2418809179272977400408325788186897e1);754 try expectEqual(log_f128(1.200355637363589375e14), 3.2418809179272977400408325788186897e1);
740 try expectEqual(logq(6.6145398293682003021240234375e9), 2.261253606737223221601998075023261e1);755 try expectEqual(log_f128(6.6145398293682003021240234375e9), 2.261253606737223221601998075023261e1);
741 try expectEqual(logq(5.16179116383965741056e20), 4.7692985503915646405875629300054525e1);756 try expectEqual(log_f128(5.16179116383965741056e20), 4.7692985503915646405875629300054525e1);
742 // testing near 1757 // testing near 1
743 try expectEqual(logq(1.026586845186097528392910049888087e0), 2.6239557099466251374193777672800004e-2);758 try expectEqual(log_f128(1.026586845186097528392910049888087e0), 2.6239557099466251374193777672800004e-2);
744 try expectEqual(logq(9.878220373715243107115568932385941e-1), -1.2252721576456821219120474521538944e-2);759 try expectEqual(log_f128(9.878220373715243107115568932385941e-1), -1.2252721576456821219120474521538944e-2);
745 try expectEqual(logq(9.417921077517196685541245315675951e-1), -5.997072116986790367958922503195352e-2);760 try expectEqual(log_f128(9.417921077517196685541245315675951e-1), -5.997072116986790367958922503195352e-2);
746 try expectEqual(logq(1.043095786320424537962914257605007e0), 4.219300911769055080390811808602425e-2);761 try expectEqual(log_f128(1.043095786320424537962914257605007e0), 4.219300911769055080390811808602425e-2);
747 try expectEqual(logq(1.019043049323190694932517175175235e0), 1.8863999985309781522599012445793722e-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,12 +25,18 @@ comptime {
25 symbol(&log10l, "log10l");25 symbol(&log10l, "log10l");
26}26}
2727
28pub fn __log10h(a: f16) callconv(.c) f16 {28fn __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}
31pub fn log10_f16(a: f16) f16 {
29 // TODO: more efficient implementation32 // TODO: more efficient implementation
30 return @floatCast(log10f(a));33 return @floatCast(log10_f32(a));
31}34}
3235
33pub fn log10f(x_: f32) callconv(.c) f32 {36fn 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}
39pub fn log10_f32(x_: f32) f32 {
34 const ivln10hi: f32 = 4.3432617188e-01;40 const ivln10hi: f32 = 4.3432617188e-01;
35 const ivln10lo: f32 = -3.1689971365e-05;41 const ivln10lo: f32 = -3.1689971365e-05;
36 const log10_2hi: f32 = 3.0102920532e-01;42 const log10_2hi: f32 = 3.0102920532e-01;
...@@ -90,7 +96,10 @@ pub fn log10f(x_: f32) callconv(.c) f32 {...@@ -90,7 +96,10 @@ pub fn log10f(x_: f32) callconv(.c) f32 {
90 return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi;96 return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi;
91}97}
9298
93pub fn log10(x_: f64) callconv(.c) f64 {99fn 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}
102pub fn log10_f64(x_: f64) f64 {
94 const ivln10hi: f64 = 4.34294481878168880939e-01;103 const ivln10hi: f64 = 4.34294481878168880939e-01;
95 const ivln10lo: f64 = 2.50829467116452752298e-11;104 const ivln10lo: f64 = 2.50829467116452752298e-11;
96 const log10_2hi: f64 = 3.01029995663611771306e-01;105 const log10_2hi: f64 = 3.01029995663611771306e-01;
...@@ -165,11 +174,17 @@ pub fn log10(x_: f64) callconv(.c) f64 {...@@ -165,11 +174,17 @@ pub fn log10(x_: f64) callconv(.c) f64 {
165 return val_lo + val_hi;174 return val_lo + val_hi;
166}175}
167176
168pub fn __log10x(a: f80) callconv(.c) f80 {177fn __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}
180pub fn log10_f80(a: f80) f80 {
169 // TODO: more efficient implementation181 // TODO: more efficient implementation
170 return @floatCast(log10q(a));182 return @floatCast(log10_f128(a));
171}183}
172184
185fn 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/// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic"188/// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic"
174/// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990189/// 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,7 +197,7 @@ pub fn __log10x(a: f80) callconv(.c) f80 {
182///197///
183/// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case):198/// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case):
184/// <= 0.5 ulp: 99.96%, worst case <= 0.565 ulp199/// <= 0.5 ulp: 99.96%, worst case <= 0.565 ulp
185pub fn log10q(x: f128) callconv(.c) f128 {200pub fn log10_f128(x: f128) f128 {
186 const impl = @import("log_f128.zig");201 const impl = @import("log_f128.zig");
187202
188 if (impl.specialCases(x)) |y|203 if (impl.specialCases(x)) |y|
...@@ -359,124 +374,124 @@ pub fn log10q(x: f128) callconv(.c) f128 {...@@ -359,124 +374,124 @@ pub fn log10q(x: f128) callconv(.c) f128 {
359374
360pub fn log10l(x: c_longdouble) callconv(.c) c_longdouble {375pub fn log10l(x: c_longdouble) callconv(.c) c_longdouble {
361 switch (@typeInfo(c_longdouble).float.bits) {376 switch (@typeInfo(c_longdouble).float.bits) {
362 64 => return log10(x),377 64 => return log10_f64(x),
363 80 => return __log10x(x),378 80 => return log10_f80(x),
364 128 => return log10q(x),379 128 => return log10_f128(x),
365 else => @compileError("unreachable"),380 else => comptime unreachable,
366 }381 }
367}382}
368383
369test "log10f() special" {384test "log10f() special" {
370 try expectEqual(log10f(0.0), -math.inf(f32));385 try expectEqual(log10_f32(0.0), -math.inf(f32));
371 try expectEqual(log10f(-0.0), -math.inf(f32));386 try expectEqual(log10_f32(-0.0), -math.inf(f32));
372 try expect(math.isPositiveZero(log10f(1.0)));387 try expect(math.isPositiveZero(log10_f32(1.0)));
373 try expectEqual(log10f(10.0), 1.0);388 try expectEqual(log10_f32(10.0), 1.0);
374 try expectEqual(log10f(0.1), -1.0);389 try expectEqual(log10_f32(0.1), -1.0);
375 try expectEqual(log10f(math.inf(f32)), math.inf(f32));390 try expectEqual(log10_f32(math.inf(f32)), math.inf(f32));
376 try expect(math.isNan(log10f(-1.0)));391 try expect(math.isNan(log10_f32(-1.0)));
377 try expect(math.isNan(log10f(-math.inf(f32))));392 try expect(math.isNan(log10_f32(-math.inf(f32))));
378 try expect(math.isNan(log10f(math.nan(f32))));393 try expect(math.isNan(log10_f32(math.nan(f32))));
379 try expect(math.isNan(log10f(math.snan(f32))));394 try expect(math.isNan(log10_f32(math.snan(f32))));
380}395}
381396
382test "log10f() sanity" {397test "log10f() sanity" {
383 try expect(math.isNan(log10f(-0x1.0223a0p+3)));398 try expect(math.isNan(log10_f32(-0x1.0223a0p+3)));
384 try expectEqual(log10f(0x1.161868p+2), 0x1.46a9bcp-1);399 try expectEqual(log10_f32(0x1.161868p+2), 0x1.46a9bcp-1);
385 try expect(math.isNan(log10f(-0x1.0c34b4p+3)));400 try expect(math.isNan(log10_f32(-0x1.0c34b4p+3)));
386 try expect(math.isNan(log10f(-0x1.a206f0p+2)));401 try expect(math.isNan(log10_f32(-0x1.a206f0p+2)));
387 try expectEqual(log10f(0x1.288bbcp+3), 0x1.ef1300p-1);402 try expectEqual(log10_f32(0x1.288bbcp+3), 0x1.ef1300p-1);
388 try expectEqual(log10f(0x1.52efd0p-1), -0x1.6ee6dcp-3); // Disagrees with GCC in last bit403 try expectEqual(log10_f32(0x1.52efd0p-1), -0x1.6ee6dcp-3); // Disagrees with GCC in last bit
389 try expect(math.isNan(log10f(-0x1.a05cc8p-2)));404 try expect(math.isNan(log10_f32(-0x1.a05cc8p-2)));
390 try expectEqual(log10f(0x1.1f9efap-1), -0x1.0075ccp-2);405 try expectEqual(log10_f32(0x1.1f9efap-1), -0x1.0075ccp-2);
391 try expectEqual(log10f(0x1.8c5db0p-1), -0x1.c75df8p-4);406 try expectEqual(log10_f32(0x1.8c5db0p-1), -0x1.c75df8p-4);
392 try expect(math.isNan(log10f(-0x1.5b86eap-1)));407 try expect(math.isNan(log10_f32(-0x1.5b86eap-1)));
393}408}
394409
395test "log10f() boundary" {410test "log10f() boundary" {
396 try expectEqual(log10f(0x1.fffffep+127), 0x1.344136p+5); // Max input value411 try expectEqual(log10_f32(0x1.fffffep+127), 0x1.344136p+5); // Max input value
397 try expectEqual(log10f(0x1p-149), -0x1.66d3e8p+5); // Min positive input value412 try expectEqual(log10_f32(0x1p-149), -0x1.66d3e8p+5); // Min positive input value
398 try expect(math.isNan(log10f(-0x1p-149))); // Min negative input value413 try expect(math.isNan(log10_f32(-0x1p-149))); // Min negative input value
399 try expectEqual(log10f(0x1.000002p+0), 0x1.bcb7b0p-25); // Last value before result reaches +0414 try expectEqual(log10_f32(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 -0415 try expectEqual(log10_f32(0x1.fffffep-1), -0x1.bcb7b2p-26); // Last value before result reaches -0
401 try expectEqual(log10f(0x1p-126), -0x1.2f7030p+5); // First subnormal416 try expectEqual(log10_f32(0x1p-126), -0x1.2f7030p+5); // First subnormal
402 try expect(math.isNan(log10f(-0x1p-126))); // First negative subnormal417 try expect(math.isNan(log10_f32(-0x1p-126))); // First negative subnormal
403}418}
404419
405test "log10() special" {420test "log10() special" {
406 try expectEqual(log10(0.0), -math.inf(f64));421 try expectEqual(log10_f64(0.0), -math.inf(f64));
407 try expectEqual(log10(-0.0), -math.inf(f64));422 try expectEqual(log10_f64(-0.0), -math.inf(f64));
408 try expect(math.isPositiveZero(log10(1.0)));423 try expect(math.isPositiveZero(log10_f64(1.0)));
409 try expectEqual(log10(10.0), 1.0);424 try expectEqual(log10_f64(10.0), 1.0);
410 try expectEqual(log10(0.1), -1.0);425 try expectEqual(log10_f64(0.1), -1.0);
411 try expectEqual(log10(math.inf(f64)), math.inf(f64));426 try expectEqual(log10_f64(math.inf(f64)), math.inf(f64));
412 try expect(math.isNan(log10(-1.0)));427 try expect(math.isNan(log10_f64(-1.0)));
413 try expect(math.isNan(log10(-math.inf(f64))));428 try expect(math.isNan(log10_f64(-math.inf(f64))));
414 try expect(math.isNan(log10(math.nan(f64))));429 try expect(math.isNan(log10_f64(math.nan(f64))));
415 try expect(math.isNan(log10(math.snan(f64))));430 try expect(math.isNan(log10_f64(math.snan(f64))));
416}431}
417432
418test "log10() sanity" {433test "log10() sanity" {
419 try expect(math.isNan(log10(-0x1.02239f3c6a8f1p+3)));434 try expect(math.isNan(log10_f64(-0x1.02239f3c6a8f1p+3)));
420 try expectEqual(log10(0x1.161868e18bc67p+2), 0x1.46a9bd1d2eb87p-1);435 try expectEqual(log10_f64(0x1.161868e18bc67p+2), 0x1.46a9bd1d2eb87p-1);
421 try expect(math.isNan(log10(-0x1.0c34b3e01e6e7p+3)));436 try expect(math.isNan(log10_f64(-0x1.0c34b3e01e6e7p+3)));
422 try expect(math.isNan(log10(-0x1.a206f0a19dcc4p+2)));437 try expect(math.isNan(log10_f64(-0x1.a206f0a19dcc4p+2)));
423 try expectEqual(log10(0x1.288bbb0d6a1e6p+3), 0x1.ef12fff994862p-1);438 try expectEqual(log10_f64(0x1.288bbb0d6a1e6p+3), 0x1.ef12fff994862p-1);
424 try expectEqual(log10(0x1.52efd0cd80497p-1), -0x1.6ee6db5a155cbp-3);439 try expectEqual(log10_f64(0x1.52efd0cd80497p-1), -0x1.6ee6db5a155cbp-3);
425 try expect(math.isNan(log10(-0x1.a05cc754481d1p-2)));440 try expect(math.isNan(log10_f64(-0x1.a05cc754481d1p-2)));
426 try expectEqual(log10(0x1.1f9ef934745cbp-1), -0x1.0075cda79d321p-2);441 try expectEqual(log10_f64(0x1.1f9ef934745cbp-1), -0x1.0075cda79d321p-2);
427 try expectEqual(log10(0x1.8c5db097f7442p-1), -0x1.c75df6442465ap-4);442 try expectEqual(log10_f64(0x1.8c5db097f7442p-1), -0x1.c75df6442465ap-4);
428 try expect(math.isNan(log10(-0x1.5b86ea8118a0ep-1)));443 try expect(math.isNan(log10_f64(-0x1.5b86ea8118a0ep-1)));
429}444}
430445
431test "log10() boundary" {446test "log10() boundary" {
432 try expectEqual(log10(0x1.fffffffffffffp+1023), 0x1.34413509f79ffp+8); // Max input value447 try expectEqual(log10_f64(0x1.fffffffffffffp+1023), 0x1.34413509f79ffp+8); // Max input value
433 try expectEqual(log10(0x1p-1074), -0x1.434e6420f4374p+8); // Min positive input value448 try expectEqual(log10_f64(0x1p-1074), -0x1.434e6420f4374p+8); // Min positive input value
434 try expect(math.isNan(log10(-0x1p-1074))); // Min negative input value449 try expect(math.isNan(log10_f64(-0x1p-1074))); // Min negative input value
435 try expectEqual(log10(0x1.0000000000001p+0), 0x1.bcb7b1526e50dp-54); // Last value before result reaches +0450 try expectEqual(log10_f64(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 -0451 try expectEqual(log10_f64(0x1.fffffffffffffp-1), -0x1.bcb7b1526e50fp-55); // Last value before result reaches -0
437 try expectEqual(log10(0x1p-1022), -0x1.33a7146f72a42p+8); // First subnormal452 try expectEqual(log10_f64(0x1p-1022), -0x1.33a7146f72a42p+8); // First subnormal
438 try expect(math.isNan(log10(-0x1p-1022))); // First negative subnormal453 try expect(math.isNan(log10_f64(-0x1p-1022))); // First negative subnormal
439}454}
440455
441test "log10q() special" {456test "log10q() special" {
442 try expectEqual(log10q(0.0), -math.inf(f128));457 try expectEqual(log10_f128(0.0), -math.inf(f128));
443 try expectEqual(log10q(-0.0), -math.inf(f128));458 try expectEqual(log10_f128(-0.0), -math.inf(f128));
444 try expect(math.isPositiveZero(log10q(1.0)));459 try expect(math.isPositiveZero(log10_f128(1.0)));
445 try expectEqual(log10q(10.0), 1.0);460 try expectEqual(log10_f128(10.0), 1.0);
446 try expectEqual(log10q(0.1), -1.0);461 try expectEqual(log10_f128(0.1), -1.0);
447 try expectEqual(log10q(math.inf(f128)), math.inf(f128));462 try expectEqual(log10_f128(math.inf(f128)), math.inf(f128));
448 try expect(math.isNan(log10q(-1.0)));463 try expect(math.isNan(log10_f128(-1.0)));
449 try expect(math.isNan(log10q(-math.inf(f128))));464 try expect(math.isNan(log10_f128(-math.inf(f128))));
450 try expect(math.isNan(log10q(math.nan(f128))));465 try expect(math.isNan(log10_f128(math.nan(f128))));
451 try expect(math.isNan(log10q(math.snan(f128))));466 try expect(math.isNan(log10_f128(math.snan(f128))));
452}467}
453468
454test "log10q() sanity" {469test "log10q() sanity" {
455 try expectEqual(log10q(2.1744503117482705706605762784484114e1949), 1.949337349488073972035715318447419e3);470 try expectEqual(log10_f128(2.1744503117482705706605762784484114e1949), 1.949337349488073972035715318447419e3);
456 try expectEqual(log10q(2.3695331993665660983204066767386505e2150), 2.1503746627979481420243846411400265e3);471 try expectEqual(log10_f128(2.3695331993665660983204066767386505e2150), 2.1503746627979481420243846411400265e3);
457 try expectEqual(log10q(1.8071775728314983136779370752110857e612), 6.122570008283284411311428111991705e2);472 try expectEqual(log10_f128(1.8071775728314983136779370752110857e612), 6.122570008283284411311428111991705e2);
458 try expectEqual(log10q(2.612170297226630737309271722008693e-2629), -2.628582998513179919647069989114319e3);473 try expectEqual(log10_f128(2.612170297226630737309271722008693e-2629), -2.628582998513179919647069989114319e3);
459 try expectEqual(log10q(8.485091636263895897993044621224502e-3748), -3.7470713434630800881474518447042895e3);474 try expectEqual(log10_f128(8.485091636263895897993044621224502e-3748), -3.7470713434630800881474518447042895e3);
460 try expectEqual(log10q(4.3668077579803801413736022136116655e-4051), -4.0503598359268068567757367259544416e3);475 try expectEqual(log10_f128(4.3668077579803801413736022136116655e-4051), -4.0503598359268068567757367259544416e3);
461 try expectEqual(log10q(2.9321353260885285826237030859036923e4830), 4.830467184010313310864606285356782e3);476 try expectEqual(log10_f128(2.9321353260885285826237030859036923e4830), 4.830467184010313310864606285356782e3);
462 try expectEqual(log10q(6.6119754254652455408442826553161645e-1417), -1.416179668769227128601620567685071e3);477 try expectEqual(log10_f128(6.6119754254652455408442826553161645e-1417), -1.416179668769227128601620567685071e3);
463 try expectEqual(log10q(5.2459104673488555418645321788108695e4178), 4.178719820874155944446586083585479e3);478 try expectEqual(log10_f128(5.2459104673488555418645321788108695e4178), 4.178719820874155944446586083585479e3);
464 try expectEqual(log10q(7.809812890804996586377267218360886e-418), -4.1710735937091966815220294599598215e2);479 try expectEqual(log10_f128(7.809812890804996586377267218360886e-418), -4.1710735937091966815220294599598215e2);
465 // testing near 1480 // testing near 1
466 try expectEqual(log10q(1.0291437165967803055610652052109798e0), 1.2476026819466393459130418401605807e-2);481 try expectEqual(log10_f128(1.0291437165967803055610652052109798e0), 1.2476026819466393459130418401605807e-2);
467 try expectEqual(log10q(1.043095786320424537962914257605007e0), 1.8324191034706598279642145362763252e-2);482 try expectEqual(log10_f128(1.043095786320424537962914257605007e0), 1.8324191034706598279642145362763252e-2);
468 try expectEqual(log10q(9.900264873754467234601150948947179e-1), -4.3531860417287584780652055666513634e-3);483 try expectEqual(log10_f128(9.900264873754467234601150948947179e-1), -4.3531860417287584780652055666513634e-3);
469 try expectEqual(log10q(1.038295346547007736348611217636062e0), 1.6320907588397540309035279023485962e-2);484 try expectEqual(log10_f128(1.038295346547007736348611217636062e0), 1.6320907588397540309035279023485962e-2);
470 try expectEqual(log10q(9.821701941230028324703038578036285e-1), -7.813249520562034832371814409278784e-3);485 try expectEqual(log10_f128(9.821701941230028324703038578036285e-1), -7.813249520562034832371814409278784e-3);
471 try expectEqual(log10q(9.593555263530179895381522214847791e-1), -1.8020418356217558657107271163588764e-2);486 try expectEqual(log10_f128(9.593555263530179895381522214847791e-1), -1.8020418356217558657107271163588764e-2);
472}487}
473488
474test "log10q() boundary" {489test "log10q() boundary" {
475 try expectEqual(log10q(0x1.ffffffffffffffffffffffffffffp16383), 0x1.34413509f79fef311f12b35816f9p12); // Max input value490 try expectEqual(log10_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1.34413509f79fef311f12b35816f9p12); // Max input value
476 try expectEqual(log10q(0x1p-16494), -0x1.3653051d20c18a143b801b7c5661p12); // Min positive input value491 try expectEqual(log10_f128(0x1p-16494), -0x1.3653051d20c18a143b801b7c5661p12); // Min positive input value
477 try expect(math.isNan(log10q(-0x1p-16494))); // Min negative input value492 try expect(math.isNan(log10_f128(-0x1p-16494))); // Min negative input value
478 try expectEqual(log10q(0x1.0000000000000000000000000001p0), 0x1.bcb7b1526e50e32a6ab7555f5a67p-114); // Last value before result reaches +0493 try expectEqual(log10_f128(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 -0494 try expectEqual(log10_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1.bcb7b1526e50e32a6ab7555f5a68p-115); // Last value before result reaches -0
480 try expectEqual(log10q(0x1p-16382), -0x1.343793004f503231a589bac27c38p12); // First subnormal495 try expectEqual(log10_f128(0x1p-16382), -0x1.343793004f503231a589bac27c38p12); // First subnormal
481 try expect(math.isNan(log10q(-0x1p-16382))); // First negative subnormal496 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,12 +26,18 @@ comptime {
26 symbol(&log2l, "log2l");26 symbol(&log2l, "log2l");
27}27}
2828
29pub fn __log2h(a: f16) callconv(.c) f16 {29fn __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}
32pub fn log2_f16(a: f16) f16 {
30 // TODO: more efficient implementation33 // TODO: more efficient implementation
31 return @floatCast(log2f(a));34 return @floatCast(log2_f32(a));
32}35}
3336
34pub fn log2f(x_: f32) callconv(.c) f32 {37fn 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}
40pub fn log2_f32(x_: f32) f32 {
35 const ivln2hi: f32 = 1.4428710938e+00;41 const ivln2hi: f32 = 1.4428710938e+00;
36 const ivln2lo: f32 = -1.7605285393e-04;42 const ivln2lo: f32 = -1.7605285393e-04;
37 const Lg1: f32 = 0xaaaaaa.0p-24;43 const Lg1: f32 = 0xaaaaaa.0p-24;
...@@ -87,7 +93,10 @@ pub fn log2f(x_: f32) callconv(.c) f32 {...@@ -87,7 +93,10 @@ pub fn log2f(x_: f32) callconv(.c) f32 {
87 return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + @as(f32, @floatFromInt(k));93 return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + @as(f32, @floatFromInt(k));
88}94}
8995
90pub fn log2(x_: f64) callconv(.c) f64 {96fn 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}
99pub fn log2_f64(x_: f64) f64 {
91 const ivln2hi: f64 = 1.44269504072144627571e+00;100 const ivln2hi: f64 = 1.44269504072144627571e+00;
92 const ivln2lo: f64 = 1.67517131648865118353e-10;101 const ivln2lo: f64 = 1.67517131648865118353e-10;
93 const Lg1: f64 = 6.666666666666735130e-01;102 const Lg1: f64 = 6.666666666666735130e-01;
...@@ -158,11 +167,17 @@ pub fn log2(x_: f64) callconv(.c) f64 {...@@ -158,11 +167,17 @@ pub fn log2(x_: f64) callconv(.c) f64 {
158 return val_lo + val_hi;167 return val_lo + val_hi;
159}168}
160169
161pub fn __log2x(a: f80) callconv(.c) f80 {170fn __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}
173pub fn log2_f80(a: f80) f80 {
162 // TODO: more efficient implementation174 // TODO: more efficient implementation
163 return @floatCast(log2q(a));175 return @floatCast(log2_f128(a));
164}176}
165177
178fn 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/// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic"181/// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic"
167/// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990182/// 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,7 +190,7 @@ pub fn __log2x(a: f80) callconv(.c) f80 {
175///190///
176/// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case):191/// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case):
177/// <= 0.5 ulp: 99.86%, worst case <= 0.546 ulp192/// <= 0.5 ulp: 99.86%, worst case <= 0.546 ulp
178pub fn log2q(x: f128) callconv(.c) f128 {193pub fn log2_f128(x: f128) f128 {
179 const impl = @import("log_f128.zig");194 const impl = @import("log_f128.zig");
180195
181 if (impl.specialCases(x)) |y|196 if (impl.specialCases(x)) |y|
...@@ -351,117 +366,117 @@ pub fn log2q(x: f128) callconv(.c) f128 {...@@ -351,117 +366,117 @@ pub fn log2q(x: f128) callconv(.c) f128 {
351366
352pub fn log2l(x: c_longdouble) callconv(.c) c_longdouble {367pub fn log2l(x: c_longdouble) callconv(.c) c_longdouble {
353 switch (@typeInfo(c_longdouble).float.bits) {368 switch (@typeInfo(c_longdouble).float.bits) {
354 64 => return log2(x),369 64 => return log2_f64(x),
355 80 => return __log2x(x),370 80 => return log2_f80(x),
356 128 => return log2q(x),371 128 => return log2_f128(x),
357 else => @compileError("unreachable"),372 else => comptime unreachable,
358 }373 }
359}374}
360375
361test "log2f() special" {376test "log2f() special" {
362 try expectEqual(log2f(0.0), -math.inf(f32));377 try expectEqual(log2_f32(0.0), -math.inf(f32));
363 try expectEqual(log2f(-0.0), -math.inf(f32));378 try expectEqual(log2_f32(-0.0), -math.inf(f32));
364 try expect(math.isPositiveZero(log2f(1.0)));379 try expect(math.isPositiveZero(log2_f32(1.0)));
365 try expectEqual(log2f(2.0), 1.0);380 try expectEqual(log2_f32(2.0), 1.0);
366 try expectEqual(log2f(math.inf(f32)), math.inf(f32));381 try expectEqual(log2_f32(math.inf(f32)), math.inf(f32));
367 try expect(math.isNan(log2f(-1.0)));382 try expect(math.isNan(log2_f32(-1.0)));
368 try expect(math.isNan(log2f(-math.inf(f32))));383 try expect(math.isNan(log2_f32(-math.inf(f32))));
369 try expect(math.isNan(log2f(math.nan(f32))));384 try expect(math.isNan(log2_f32(math.nan(f32))));
370 try expect(math.isNan(log2f(math.snan(f32))));385 try expect(math.isNan(log2_f32(math.snan(f32))));
371}386}
372387
373test "log2f() sanity" {388test "log2f() sanity" {
374 try expect(math.isNan(log2f(-0x1.0223a0p+3)));389 try expect(math.isNan(log2_f32(-0x1.0223a0p+3)));
375 try expectEqual(log2f(0x1.161868p+2), 0x1.0f49acp+1);390 try expectEqual(log2_f32(0x1.161868p+2), 0x1.0f49acp+1);
376 try expect(math.isNan(log2f(-0x1.0c34b4p+3)));391 try expect(math.isNan(log2_f32(-0x1.0c34b4p+3)));
377 try expect(math.isNan(log2f(-0x1.a206f0p+2)));392 try expect(math.isNan(log2_f32(-0x1.a206f0p+2)));
378 try expectEqual(log2f(0x1.288bbcp+3), 0x1.9b2676p+1);393 try expectEqual(log2_f32(0x1.288bbcp+3), 0x1.9b2676p+1);
379 try expectEqual(log2f(0x1.52efd0p-1), -0x1.30b494p-1); // Disagrees with GCC in last bit394 try expectEqual(log2_f32(0x1.52efd0p-1), -0x1.30b494p-1); // Disagrees with GCC in last bit
380 try expect(math.isNan(log2f(-0x1.a05cc8p-2)));395 try expect(math.isNan(log2_f32(-0x1.a05cc8p-2)));
381 try expectEqual(log2f(0x1.1f9efap-1), -0x1.a9f89ap-1);396 try expectEqual(log2_f32(0x1.1f9efap-1), -0x1.a9f89ap-1);
382 try expectEqual(log2f(0x1.8c5db0p-1), -0x1.7a2c96p-2);397 try expectEqual(log2_f32(0x1.8c5db0p-1), -0x1.7a2c96p-2);
383 try expect(math.isNan(log2f(-0x1.5b86eap-1)));398 try expect(math.isNan(log2_f32(-0x1.5b86eap-1)));
384}399}
385400
386test "log2f() boundary" {401test "log2f() boundary" {
387 try expectEqual(log2f(0x1.fffffep+127), 0x1p+7); // Max input value402 try expectEqual(log2_f32(0x1.fffffep+127), 0x1p+7); // Max input value
388 try expectEqual(log2f(0x1p-149), -0x1.2ap+7); // Min positive input value403 try expectEqual(log2_f32(0x1p-149), -0x1.2ap+7); // Min positive input value
389 try expect(math.isNan(log2f(-0x1p-149))); // Min negative input value404 try expect(math.isNan(log2_f32(-0x1p-149))); // Min negative input value
390 try expectEqual(log2f(0x1.000002p+0), 0x1.715474p-23); // Last value before result reaches +0405 try expectEqual(log2_f32(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 -0406 try expectEqual(log2_f32(0x1.fffffep-1), -0x1.715478p-24); // Last value before result reaches -0
392 try expectEqual(log2f(0x1p-126), -0x1.f8p+6); // First subnormal407 try expectEqual(log2_f32(0x1p-126), -0x1.f8p+6); // First subnormal
393 try expect(math.isNan(log2f(-0x1p-126))); // First negative subnormal408 try expect(math.isNan(log2_f32(-0x1p-126))); // First negative subnormal
394409
395}410}
396411
397test "log2() special" {412test "log2() special" {
398 try expectEqual(log2(0.0), -math.inf(f64));413 try expectEqual(log2_f64(0.0), -math.inf(f64));
399 try expectEqual(log2(-0.0), -math.inf(f64));414 try expectEqual(log2_f64(-0.0), -math.inf(f64));
400 try expect(math.isPositiveZero(log2(1.0)));415 try expect(math.isPositiveZero(log2_f64(1.0)));
401 try expectEqual(log2(2.0), 1.0);416 try expectEqual(log2_f64(2.0), 1.0);
402 try expectEqual(log2(math.inf(f64)), math.inf(f64));417 try expectEqual(log2_f64(math.inf(f64)), math.inf(f64));
403 try expect(math.isNan(log2(-1.0)));418 try expect(math.isNan(log2_f64(-1.0)));
404 try expect(math.isNan(log2(-math.inf(f64))));419 try expect(math.isNan(log2_f64(-math.inf(f64))));
405 try expect(math.isNan(log2(math.nan(f64))));420 try expect(math.isNan(log2_f64(math.nan(f64))));
406 try expect(math.isNan(log2(math.snan(f64))));421 try expect(math.isNan(log2_f64(math.snan(f64))));
407}422}
408423
409test "log2() sanity" {424test "log2() sanity" {
410 try expect(math.isNan(log2(-0x1.02239f3c6a8f1p+3)));425 try expect(math.isNan(log2_f64(-0x1.02239f3c6a8f1p+3)));
411 try expectEqual(log2(0x1.161868e18bc67p+2), 0x1.0f49ac3838580p+1);426 try expectEqual(log2_f64(0x1.161868e18bc67p+2), 0x1.0f49ac3838580p+1);
412 try expect(math.isNan(log2(-0x1.0c34b3e01e6e7p+3)));427 try expect(math.isNan(log2_f64(-0x1.0c34b3e01e6e7p+3)));
413 try expect(math.isNan(log2(-0x1.a206f0a19dcc4p+2)));428 try expect(math.isNan(log2_f64(-0x1.a206f0a19dcc4p+2)));
414 try expectEqual(log2(0x1.288bbb0d6a1e6p+3), 0x1.9b26760c2a57ep+1);429 try expectEqual(log2_f64(0x1.288bbb0d6a1e6p+3), 0x1.9b26760c2a57ep+1);
415 try expectEqual(log2(0x1.52efd0cd80497p-1), -0x1.30b490ef684c7p-1);430 try expectEqual(log2_f64(0x1.52efd0cd80497p-1), -0x1.30b490ef684c7p-1);
416 try expect(math.isNan(log2(-0x1.a05cc754481d1p-2)));431 try expect(math.isNan(log2_f64(-0x1.a05cc754481d1p-2)));
417 try expectEqual(log2(0x1.1f9ef934745cbp-1), -0x1.a9f89b5f5acb8p-1);432 try expectEqual(log2_f64(0x1.1f9ef934745cbp-1), -0x1.a9f89b5f5acb8p-1);
418 try expectEqual(log2(0x1.8c5db097f7442p-1), -0x1.7a2c947173f06p-2);433 try expectEqual(log2_f64(0x1.8c5db097f7442p-1), -0x1.7a2c947173f06p-2);
419 try expect(math.isNan(log2(-0x1.5b86ea8118a0ep-1)));434 try expect(math.isNan(log2_f64(-0x1.5b86ea8118a0ep-1)));
420}435}
421436
422test "log2() boundary" {437test "log2() boundary" {
423 try expectEqual(log2(0x1.fffffffffffffp+1023), 0x1p+10); // Max input value438 try expectEqual(log2_f64(0x1.fffffffffffffp+1023), 0x1p+10); // Max input value
424 try expectEqual(log2(0x1p-1074), -0x1.0c8p+10); // Min positive input value439 try expectEqual(log2_f64(0x1p-1074), -0x1.0c8p+10); // Min positive input value
425 try expect(math.isNan(log2(-0x1p-1074))); // Min negative input value440 try expect(math.isNan(log2_f64(-0x1p-1074))); // Min negative input value
426 try expectEqual(log2(0x1.0000000000001p+0), 0x1.71547652b82fdp-52); // Last value before result reaches +0441 try expectEqual(log2_f64(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 -0442 try expectEqual(log2_f64(0x1.fffffffffffffp-1), -0x1.71547652b82fep-53); // Last value before result reaches -0
428 try expectEqual(log2(0x1p-1022), -0x1.ffp+9); // First subnormal443 try expectEqual(log2_f64(0x1p-1022), -0x1.ffp+9); // First subnormal
429 try expect(math.isNan(log2(-0x1p-1022))); // First negative subnormal444 try expect(math.isNan(log2_f64(-0x1p-1022))); // First negative subnormal
430}445}
431446
432test "log2q() special" {447test "log2q() special" {
433 try expectEqual(log2q(0.0), -math.inf(f128));448 try expectEqual(log2_f128(0.0), -math.inf(f128));
434 try expectEqual(log2q(-0.0), -math.inf(f128));449 try expectEqual(log2_f128(-0.0), -math.inf(f128));
435 try expect(math.isPositiveZero(log2q(1.0)));450 try expect(math.isPositiveZero(log2_f128(1.0)));
436 try expectEqual(log2q(2.0), 1.0);451 try expectEqual(log2_f128(2.0), 1.0);
437 try expectEqual(log2q(math.inf(f128)), math.inf(f128));452 try expectEqual(log2_f128(math.inf(f128)), math.inf(f128));
438 try expect(math.isNan(log2q(-1.0)));453 try expect(math.isNan(log2_f128(-1.0)));
439 try expect(math.isNan(log2q(-math.inf(f128))));454 try expect(math.isNan(log2_f128(-math.inf(f128))));
440 try expect(math.isNan(log2q(math.nan(f128))));455 try expect(math.isNan(log2_f128(math.nan(f128))));
441 try expect(math.isNan(log2q(math.snan(f128))));456 try expect(math.isNan(log2_f128(math.snan(f128))));
442}457}
443458
444test "log2q() boundary" {459test "log2q() boundary" {
445 try expectEqual(log2q(0x1.ffffffffffffffffffffffffffffp16383), 0x1p14); // Max input value460 try expectEqual(log2_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1p14); // Max input value
446 try expectEqual(log2q(0x1p-16494), -0x1.01b8p14); // Min positive input value461 try expectEqual(log2_f128(0x1p-16494), -0x1.01b8p14); // Min positive input value
447 try expect(math.isNan(log2q(-0x1p-16494))); // Min negative input value462 try expect(math.isNan(log2_f128(-0x1p-16494))); // Min negative input value
448 try expectEqual(log2q(0x1.0000000000000000000000000001p0), 0x1.71547652b82fe1777d0ffda0d23ap-112); // Last value before result reaches +0463 try expectEqual(log2_f128(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 -0464 try expectEqual(log2_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1.71547652b82fe1777d0ffda0d23bp-113); // Last value before result reaches -0
450 try expectEqual(log2q(0x1p-16382), -0x1.fffp13); // First subnormal465 try expectEqual(log2_f128(0x1p-16382), -0x1.fffp13); // First subnormal
451 try expect(math.isNan(log2q(-0x1p-16382))); // First negative subnormal466 try expect(math.isNan(log2_f128(-0x1p-16382))); // First negative subnormal
452}467}
453468
454test "log2q() sanity" {469test "log2q() sanity" {
455 try expectEqual(log2q(8.0965013884643408203125e11), 3.955850767769801288865582596068254e1);470 try expectEqual(log2_f128(8.0965013884643408203125e11), 3.955850767769801288865582596068254e1);
456 try expectEqual(log2q(8.346531942223744e15), 5.28900982928636641107356163006646e1);471 try expectEqual(log2_f128(8.346531942223744e15), 5.28900982928636641107356163006646e1);
457 try expectEqual(log2q(9.707809913413123613777865431464565e-20), -6.315941603809020445822192336703809e1);472 try expectEqual(log2_f128(9.707809913413123613777865431464565e-20), -6.315941603809020445822192336703809e1);
458 try expectEqual(log2q(1.9179565888043380306021427656243352e-24), -7.878670421065570557450089031998522e1);473 try expectEqual(log2_f128(1.9179565888043380306021427656243352e-24), -7.878670421065570557450089031998522e1);
459 try expectEqual(log2q(2.5260048200126556877075044745936796e-25), -8.17113449801679676275805009400338e1);474 try expectEqual(log2_f128(2.5260048200126556877075044745936796e-25), -8.17113449801679676275805009400338e1);
460 try expectEqual(log2q(3.1170134002568967640399932861328125e7), 2.489366102143423848582774267206741e1);475 try expectEqual(log2_f128(3.1170134002568967640399932861328125e7), 2.489366102143423848582774267206741e1);
461 // test near 1476 // test near 1
462 try expectEqual(log2q(1.026586845186097528392910049888087e0), 3.7855678902522753591699367969189364e-2);477 try expectEqual(log2_f128(1.026586845186097528392910049888087e0), 3.7855678902522753591699367969189364e-2);
463 try expectEqual(log2q(1.0005582850578053877743656130405725e0), 8.052103367568488432896147152682078e-4);478 try expectEqual(log2_f128(1.0005582850578053877743656130405725e0), 8.052103367568488432896147152682078e-4);
464 try expectEqual(log2q(1.0370174103591254835765589348284266e0), 5.244011558596899945639244281954306e-2);479 try expectEqual(log2_f128(1.0370174103591254835765589348284266e0), 5.244011558596899945639244281954306e-2);
465 try expectEqual(log2q(1.0429996503525671713075162472250667e0), 6.073867421942172944687194557176633e-2);480 try expectEqual(log2_f128(1.0429996503525671713075162472250667e0), 6.073867421942172944687194557176633e-2);
466 try expectEqual(log2q(1.0383384027961064621892184334228659e0), 5.4276706191956281784022630732940314e-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,19 +3,80 @@ const isNan = std.math.isNan;
3const isInf = std.math.isInf;3const isInf = std.math.isInf;
4const copysign = std.math.copysign;4const copysign = std.math.copysign;
55
6pub fn Complex(comptime T: type) type {6const compiler_rt = @import("../compiler_rt.zig");
7 return extern struct {7const symbol = compiler_rt.symbol;
8 real: T,8const Complex = compiler_rt.Complex;
9 imag: T,9
10 };10comptime {
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
24fn __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}
30pub fn mul_cf16(a: Complex(f16), b: Complex(f16)) Complex(f16) {
31 return mulc3(f16, a, b);
32}
33
34fn __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}
40pub fn mul_cf32(a: Complex(f32), b: Complex(f32)) Complex(f32) {
41 return mulc3(f32, a, b);
42}
43
44fn __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}
50pub fn mul_cf64(a: Complex(f64), b: Complex(f64)) Complex(f64) {
51 return mulc3(f64, a, b);
52}
53
54fn __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}
60pub fn mul_cf80(a: Complex(f80), b: Complex(f80)) Complex(f80) {
61 return mulc3(f80, a, b);
62}
63
64fn __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}
70pub fn mul_cf128(a: Complex(f128), b: Complex(f128)) Complex(f128) {
71 return mulc3(f128, a, b);
11}72}
1273
13/// Implementation based on Annex G of C17 Standard (N2176)74/// Implementation based on Annex G of C17 Standard (N2176)
14pub inline fn mulc3(comptime T: type, a_in: T, b_in: T, c_in: T, d_in: T) Complex(T) {75inline fn mulc3(comptime T: type, lhs: Complex(T), rhs: Complex(T)) Complex(T) {
15 var a = a_in;76 var a = lhs.real;
16 var b = b_in;77 var b = lhs.imag;
17 var c = c_in;78 var c = rhs.real;
18 var d = d_in;79 var d = rhs.imag;
1980
20 const ac = a * c;81 const ac = a * c;
21 const bd = b * d;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,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 return z;139 return z;
79}140}
141
142test {
143 _ = @import("mulc3_test.zig");
144}
lib/compiler_rt/mulc3_test.zig+23-42
...@@ -2,64 +2,45 @@ const std = @import("std");...@@ -2,64 +2,45 @@ const std = @import("std");
2const math = std.math;2const math = std.math;
3const expect = std.testing.expect;3const expect = std.testing.expect;
44
5const Complex = @import("./mulc3.zig").Complex;5const Complex = @import("../compiler_rt.zig").Complex;
6const __mulhc3 = @import("./mulhc3.zig").__mulhc3;6const impl = @import("mulc3.zig");
7const __mulsc3 = @import("./mulsc3.zig").__mulsc3;7const mul_cf16 = impl.mul_cf16;
8const __muldc3 = @import("./muldc3.zig").__muldc3;8const mul_cf32 = impl.mul_cf32;
9const __mulxc3 = @import("./mulxc3.zig").__mulxc3;9const mul_cf64 = impl.mul_cf64;
10const __multc3 = @import("./multc3.zig").__multc3;10const mul_cf80 = impl.mul_cf80;
11const mul_cf128 = impl.mul_cf128;
1112
12test "mulc3" {13test "mulc3" {
13 try testMul(f16, __mulhc3);14 try testMul(f16, mul_cf16);
14 try testMul(f32, __mulsc3);15 try testMul(f32, mul_cf32);
15 try testMul(f64, __muldc3);16 try testMul(f64, mul_cf64);
16 try testMul(f80, __mulxc3);17 try testMul(f80, mul_cf80);
17 try testMul(f128, __multc3);18 try testMul(f128, mul_cf128);
18}19}
1920
20fn testMul(comptime T: type, comptime f: fn (T, T, T, T) callconv(.c) Complex(T)) !void {21fn testMul(comptime T: type, comptime f: fn (Complex(T), Complex(T)) Complex(T)) !void {
21 {22 {
22 const a: T = 1.0;23 const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -1.0, .imag = 0.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);
28 try expect(result.real == -1.0);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;28 const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -4.0, .imag = 0.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);
38 try expect(result.real == -4.0);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 // if one operand is an infinity and the other operand is a nonzero finite number or an infinity,33 // if one operand is an infinity and the other operand is a nonzero finite number or an infinity,
43 // then the result of the * operator is an infinity;34 // then the result of the * operator is an infinity;
44 const a: T = math.inf(T);35 const result = f(.{ .real = math.inf(T), .imag = -math.inf(T) }, .{ .real = 1.0, .imag = 0.0 });
45 const b: T = -math.inf(T);36 try expect(math.isPositiveInf(result.real));
46 const c: T = 1.0;37 try expect(math.isNegativeInf(result.imag));
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));
52 }38 }
53 {39 {
54 // if one operand is an infinity and the other operand is a nonzero finite number or an infinity,40 // if one operand is an infinity and the other operand is a nonzero finite number or an infinity,
55 // then the result of the * operator is an infinity;41 // then the result of the * operator is an infinity;
56 const a: T = math.inf(T);42 const result = f(.{ .real = math.inf(T), .imag = -1.0 }, .{ .real = 1.0, .imag = math.inf(T) });
57 const b: T = -1.0;43 try expect(math.isPositiveInf(result.real));
58 const c: T = 1.0;44 try expect(math.isPositiveInf(result.imag));
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));
64 }45 }
65}46}
lib/compiler_rt/muldc3.zig deleted-12
...@@ -1,12 +0,0 @@
1const mulc3 = @import("./mulc3.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3
4comptime {
5 if (@import("builtin").zig_backend != .stage2_c) {
6 symbol(&__muldc3, "__muldc3");
7 }
8}
9
10pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const mulf3 = @import("./mulf3.zig").mulf3;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_dmul, "__aeabi_dmul");
8 } else {
9 symbol(&__muldf3, "__muldf3");
10 }
11}
12
13pub fn __muldf3(a: f64, b: f64) callconv(.c) f64 {
14 return mulf3(f64, a, b);
15}
16
17fn __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,10 +2,76 @@ const std = @import("std");
2const math = std.math;2const math = std.math;
3const builtin = @import("builtin");3const builtin = @import("builtin");
4const compiler_rt = @import("../compiler_rt.zig");4const compiler_rt = @import("../compiler_rt.zig");
5const symbol = compiler_rt.symbol;
6
7comptime {
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
28fn __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}
31pub fn mul_f16(a: f16, b: f16) f16 {
32 return mulf3(f16, a, b);
33}
34
35fn __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}
38fn __aeabi_fmul(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
39 return mul_f32(a, b);
40}
41pub fn mul_f32(a: f32, b: f32) f32 {
42 return mulf3(f32, a, b);
43}
44
45fn __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}
48fn __aeabi_dmul(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
49 return mul_f64(a, b);
50}
51pub fn mul_f64(a: f64, b: f64) f64 {
52 return mulf3(f64, a, b);
53}
54
55fn __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}
58pub fn mul_f80(a: f80, b: f80) f80 {
59 return mulf3(f80, a, b);
60}
61
62fn __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}
65fn _Qp_mul(c: *f128, a: *const f128, b: *const f128) callconv(.c) void {
66 c.* = mul_f128(a.*, b.*);
67}
68pub fn mul_f128(a: f128, b: f128) f128 {
69 return mulf3(f128, a, b);
70}
571
6/// Ported from:72/// Ported from:
7/// https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/lib/builtins/fp_mul_impl.inc73/// https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/lib/builtins/fp_mul_impl.inc
8pub inline fn mulf3(comptime T: type, a: T, b: T) T {74inline fn mulf3(comptime T: type, a: T, b: T) T {
9 @setRuntimeSafety(compiler_rt.test_safety);75 @setRuntimeSafety(compiler_rt.test_safety);
10 const typeWidth = @typeInfo(T).float.bits;76 const typeWidth = @typeInfo(T).float.bits;
11 const significandBits = math.floatMantissaBits(T);77 const significandBits = math.floatMantissaBits(T);
lib/compiler_rt/mulf3_test.zig+48-46
...@@ -7,10 +7,12 @@ const math = std.math;...@@ -7,10 +7,12 @@ const math = std.math;
7const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64);7const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64);
8const inf128: f128 = @bitCast(@as(u128, 0x7fff000000000000) << 64);8const inf128: f128 = @bitCast(@as(u128, 0x7fff000000000000) << 64);
99
10const __multf3 = @import("multf3.zig").__multf3;10const impl = @import("mulf3.zig");
11const __mulxf3 = @import("mulxf3.zig").__mulxf3;11const mul_f16 = impl.mul_f16;
12const __muldf3 = @import("muldf3.zig").__muldf3;12const mul_f32 = impl.mul_f32;
13const __mulsf3 = @import("mulsf3.zig").__mulsf3;13const mul_f64 = impl.mul_f64;
14const mul_f80 = impl.mul_f80;
15const mul_f128 = impl.mul_f128;
1416
15// return true if equal17// return true if equal
16// use two 64-bit integers instead of one 128-bit integer18// 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,8 +36,8 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {
34 return false;36 return false;
35}37}
3638
37fn test__multf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {39fn test_mul_f128(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {
38 const x = __multf3(a, b);40 const x = mul_f128(a, b);
3941
40 if (compareResultLD(x, expected_hi, expected_lo))42 if (compareResultLD(x, expected_hi, expected_lo))
41 return;43 return;
...@@ -49,68 +51,68 @@ fn makeNaN128(rand: u64) f128 {...@@ -49,68 +51,68 @@ fn makeNaN128(rand: u64) f128 {
49}51}
50test "multf3" {52test "multf3" {
51 // qNaN * any = qNaN53 // qNaN * any = qNaN
52 try test__multf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);54 try test_mul_f128(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
5355
54 // NaN * any = NaN56 // NaN * any = NaN
55 const a = makeNaN128(0x800030000000);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 // inf * any = inf59 // inf * any = inf
58 try test__multf3(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0);60 try test_mul_f128(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0);
5961
60 // any * any62 // any * any
61 try test__multf3(63 try test_mul_f128(
62 @as(f128, @bitCast(@as(u128, 0x40042eab345678439abcdefea5678234))),64 @as(f128, @bitCast(@as(u128, 0x40042eab345678439abcdefea5678234))),
63 @as(f128, @bitCast(@as(u128, 0x3ffeedcb34a235253948765432134675))),65 @as(f128, @bitCast(@as(u128, 0x3ffeedcb34a235253948765432134675))),
64 0x400423e7f9e3c9fc,66 0x400423e7f9e3c9fc,
65 0xd906c2c2a85777c4,67 0xd906c2c2a85777c4,
66 );68 );
6769
68 try test__multf3(70 try test_mul_f128(
69 @as(f128, @bitCast(@as(u128, 0x3fcd353e45674d89abacc3a2ebf3ff50))),71 @as(f128, @bitCast(@as(u128, 0x3fcd353e45674d89abacc3a2ebf3ff50))),
70 @as(f128, @bitCast(@as(u128, 0x3ff6ed8764648369535adf4be3214568))),72 @as(f128, @bitCast(@as(u128, 0x3ff6ed8764648369535adf4be3214568))),
71 0x3fc52a163c6223fc,73 0x3fc52a163c6223fc,
72 0xc94c4bf0430768b4,74 0xc94c4bf0430768b4,
73 );75 );
7476
75 try test__multf3(77 try test_mul_f128(
76 0x1.234425696abcad34a35eeffefdcbap+456,78 0x1.234425696abcad34a35eeffefdcbap+456,
77 0x451.ed98d76e5d46e5f24323dff21ffp+600,79 0x451.ed98d76e5d46e5f24323dff21ffp+600,
78 0x44293a91de5e0e94,80 0x44293a91de5e0e94,
79 0xe8ed17cc2cdf64ac,81 0xe8ed17cc2cdf64ac,
80 );82 );
8183
82 try test__multf3(84 try test_mul_f128(
83 @as(f128, @bitCast(@as(u128, 0x3f154356473c82a9fabf2d22ace345df))),85 @as(f128, @bitCast(@as(u128, 0x3f154356473c82a9fabf2d22ace345df))),
84 @as(f128, @bitCast(@as(u128, 0x3e38eda98765476743ab21da23d45679))),86 @as(f128, @bitCast(@as(u128, 0x3e38eda98765476743ab21da23d45679))),
85 0x3d4f37c1a3137cae,87 0x3d4f37c1a3137cae,
86 0xfc6807048bc2836a,88 0xfc6807048bc2836a,
87 );89 );
8890
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);
9092
91 // Denormal operands.93 // Denormal operands.
92 try test__multf3(94 try test_mul_f128(
93 0x0.0000000000000000000000000001p-16382,95 0x0.0000000000000000000000000001p-16382,
94 0x1p16383,96 0x1p16383,
95 0x3f90000000000000,97 0x3f90000000000000,
96 0x0,98 0x0,
97 );99 );
98 try test__multf3(100 try test_mul_f128(
99 0x1p16383,101 0x1p16383,
100 0x0.0000000000000000000000000001p-16382,102 0x0.0000000000000000000000000001p-16382,
101 0x3f90000000000000,103 0x3f90000000000000,
102 0x0,104 0x0,
103 );105 );
104106
105 try test__multf3(0x1.0000_0000_0000_0000_0000_0000_0001p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0002);107 try test_mul_f128(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);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);
107 try test__multf3(2.0, math.floatTrueMin(f128), 0x0000_0000_0000_0000, 0x0000_0000_0000_0002);109 try test_mul_f128(2.0, math.floatTrueMin(f128), 0x0000_0000_0000_0000, 0x0000_0000_0000_0002);
108}110}
109111
110const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1)));112const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1)));
111113
112fn test__mulxf3(a: f80, b: f80, expected: u80) !void {114fn test_mul_f80(a: f80, b: f80, expected: u80) !void {
113 const x = __mulxf3(a, b);115 const x = mul_f80(a, b);
114 const rep: u80 = @bitCast(x);116 const rep: u80 = @bitCast(x);
115117
116 if (rep == expected)118 if (rep == expected)
...@@ -124,47 +126,47 @@ fn test__mulxf3(a: f80, b: f80, expected: u80) !void {...@@ -124,47 +126,47 @@ fn test__mulxf3(a: f80, b: f80, expected: u80) !void {
124126
125test "mulxf3" {127test "mulxf3" {
126 // NaN * any = NaN128 // NaN * any = NaN
127 try test__mulxf3(qnan80, 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));129 try test_mul_f80(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)));130 try test_mul_f80(@as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
129131
130 // any * NaN = NaN132 // any * NaN = NaN
131 try test__mulxf3(0x1.23456789abcdefp+5, qnan80, @as(u80, @bitCast(qnan80)));133 try test_mul_f80(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)));134 try test_mul_f80(0x1.23456789abcdefp+5, @as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), @as(u80, @bitCast(qnan80)));
133135
134 // NaN * inf = NaN136 // 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)));
136138
137 // inf * NaN = NaN139 // 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)));
139141
140 // inf * inf = inf142 // 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))));
142144
143 // inf * -inf = -inf145 // 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))));
145147
146 // -inf + inf = -inf148 // -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))));
148150
149 // inf * any = inf151 // 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))));
151153
152 // any * inf = inf154 // 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))));
154156
155 // any * any157 // any * any
156 try test__mulxf3(0x1.0p+0, 0x1.dcba987654321p+5, 0x4004_ee5d_4c3b_2a19_0800);158 try test_mul_f80(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); // exact159 try test_mul_f80(0x1.0000_0000_0000_0004p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0003); // exact
158160
159 try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.0p+5, 0x4004_8000_0000_0000_0001); // exact161 try test_mul_f80(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 down162 try test_mul_f80(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 even163 try test_mul_f80(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 up164 try test_mul_f80(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); // exact165 try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.0p+6, 0x4005_8000_0000_0000_0001); // exact
164166
165 try test__mulxf3(0x1.0000_0001p+0, 0x1.0000_0001p+0, 0x3FFF_8000_0001_0000_0000); // round down to even167 try test_mul_f80(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 up168 try test_mul_f80(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 -> normal169 try test_mul_f80(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 -> normal170 try test_mul_f80(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 -> denormal171 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const mulc3 = @import("./mulc3.zig");
4
5comptime {
6 if (@import("builtin").zig_backend != .stage2_c) {
7 symbol(&__mulhc3, "__mulhc3");
8 }
9}
10
11pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const mulf3 = @import("./mulf3.zig").mulf3;
4
5comptime {
6 symbol(&__mulhf3, "__mulhf3");
7}
8
9pub 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 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const mulc3 = @import("./mulc3.zig");
3
4comptime {
5 if (@import("builtin").zig_backend != .stage2_c) {
6 symbol(&__mulsc3, "__mulsc3");
7 }
8}
9
10pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const mulf3 = @import("./mulf3.zig").mulf3;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_fmul, "__aeabi_fmul");
8 } else {
9 symbol(&__mulsf3, "__mulsf3");
10 }
11}
12
13pub fn __mulsf3(a: f32, b: f32) callconv(.c) f32 {
14 return mulf3(f32, a, b);
15}
16
17fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const mulc3 = @import("./mulc3.zig");
4
5comptime {
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
13pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const mulf3 = @import("./mulf3.zig").mulf3;
4
5comptime {
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
16pub fn __multf3(a: f128, b: f128) callconv(.c) f128 {
17 return mulf3(f128, a, b);
18}
19
20fn _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,7 +1,8 @@
1const testing = @import("std").testing;1const testing = @import("std").testing;
22
3const mulv = @import("mulo.zig");3const mulv = @import("mulo.zig");
4const symbol = @import("../compiler_rt.zig").symbol;4const compiler_rt = @import("../compiler_rt.zig");
5const symbol = compiler_rt.symbol;
56
6comptime {7comptime {
7 symbol(&__mulvsi3, "__mulvsi3");8 symbol(&__mulvsi3, "__mulvsi3");
...@@ -10,7 +11,7 @@ comptime {...@@ -10,7 +11,7 @@ comptime {
10pub fn __mulvsi3(a: i32, b: i32) callconv(.c) i32 {11pub fn __mulvsi3(a: i32, b: i32) callconv(.c) i32 {
11 var overflow: c_int = 0;12 var overflow: c_int = 0;
12 const sum = mulv.__mulosi4(a, b, &overflow);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 return sum;15 return sum;
15}16}
1617
lib/compiler_rt/mulxc3.zig deleted-13
...@@ -1,13 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const mulc3 = @import("./mulc3.zig");
4
5comptime {
6 if (@import("builtin").zig_backend != .stage2_c) {
7 symbol(&__mulxc3, "__mulxc3");
8 }
9}
10
11pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const mulf3 = @import("./mulf3.zig").mulf3;
4
5comptime {
6 symbol(&__mulxf3, "__mulxf3");
7}
8
9pub 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,8 +33,7 @@ inline fn negvXi(comptime ST: type, a: ST) ST {
33 };33 };
34 const N: UT = @bitSizeOf(ST);34 const N: UT = @bitSizeOf(ST);
35 const min: ST = @as(ST, @bitCast((@as(UT, 1) << (N - 1))));35 const min: ST = @as(ST, @bitCast((@as(UT, 1) << (N - 1))));
36 if (a == min)36 if (a == min) @panic("integer overflow");
37 @panic("compiler_rt negv: overflow");
38 return -a;37 return -a;
39}38}
4039
lib/compiler_rt/os_version_check.zig-1
...@@ -3,7 +3,6 @@ const testing = std.testing;...@@ -3,7 +3,6 @@ const testing = std.testing;
3const builtin = @import("builtin");3const builtin = @import("builtin");
4const compiler_rt = @import("../compiler_rt.zig");4const compiler_rt = @import("../compiler_rt.zig");
5const symbol = compiler_rt.symbol;5const symbol = compiler_rt.symbol;
6const panic = @import("../compiler_rt.zig").panic;
76
8const have_availability_version_check = builtin.os.tag.isDarwin() and7const have_availability_version_check = builtin.os.tag.isDarwin() and
9 builtin.os.version_range.semver.min.order(.{ .major = 10, .minor = 15, .patch = 0 }).compare(.gte);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,6 +1,7 @@
1//! parity - if number of bits set is even => 0, else => 11//! parity - if number of bits set is even => 0, else => 1
2//! - pariytXi2_generic for big and little endian2//! - pariytXi2_generic for big and little endian
3const symbol = @import("../compiler_rt.zig").symbol;3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
45
5comptime {6comptime {
6 symbol(&__paritysi2, "__paritysi2");7 symbol(&__paritysi2, "__paritysi2");
lib/compiler_rt/popcount.zig+2-1
...@@ -6,7 +6,8 @@...@@ -6,7 +6,8 @@
6//! TAOCP: Combinational Algorithms, Bitwise Tricks And Techniques,6//! TAOCP: Combinational Algorithms, Bitwise Tricks And Techniques,
7//! subsubsection "Working with the rightmost bits" and "Sideways addition".7//! subsubsection "Working with the rightmost bits" and "Sideways addition".
88
9const symbol = @import("../compiler_rt.zig").symbol;9const compiler_rt = @import("../compiler_rt.zig");
10const symbol = compiler_rt.symbol;
1011
11comptime {12comptime {
12 symbol(&__popcountsi2, "__popcountsi2");13 symbol(&__popcountsi2, "__popcountsi2");
lib/compiler_rt/powiXf2.zig+28-11
...@@ -4,16 +4,18 @@...@@ -4,16 +4,18 @@
4//! error propagation and this method is optimized for performance, not accuracy.4//! error propagation and this method is optimized for performance, not accuracy.
55
6const compiler_rt = @import("../compiler_rt.zig");6const compiler_rt = @import("../compiler_rt.zig");
7const symbol = @import("../compiler_rt.zig").symbol;7const symbol = compiler_rt.symbol;
88
9comptime {9comptime {
10 symbol(&__powihf2, "__powihf2");10 symbol(&__powihf2, "__powihf2");
11 symbol(&__powisf2, "__powisf2");11 symbol(&__powisf2, "__powisf2");
12 symbol(&__powidf2, "__powidf2");12 symbol(&__powidf2, "__powidf2");
13 if (compiler_rt.want_ppc_abi)
14 symbol(&__powitf2, "__powikf2");
15 symbol(&__powitf2, "__powitf2");
16 symbol(&__powixf2, "__powixf2");13 symbol(&__powixf2, "__powixf2");
14 if (compiler_rt.want_ppc_abi) {
15 symbol(&__powitf2, "__powikf2");
16 } else {
17 symbol(&__powitf2, "__powitf2");
18 }
17}19}
1820
19inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT {21inline 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,26 +34,41 @@ inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT {
32 return if (is_recip) 1 / r else r;34 return if (is_recip) 1 / r else r;
33}35}
3436
35pub fn __powihf2(a: f16, b: i32) callconv(.c) f16 {37fn __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}
40pub fn powi_f16(a: f16, b: i32) f16 {
36 return powiXf2(f16, a, b);41 return powiXf2(f16, a, b);
37}42}
3843
39pub fn __powisf2(a: f32, b: i32) callconv(.c) f32 {44fn __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}
47pub fn powi_f32(a: f32, b: i32) f32 {
40 return powiXf2(f32, a, b);48 return powiXf2(f32, a, b);
41}49}
4250
43pub fn __powidf2(a: f64, b: i32) callconv(.c) f64 {51fn __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}
54pub fn powi_f64(a: f64, b: i32) f64 {
44 return powiXf2(f64, a, b);55 return powiXf2(f64, a, b);
45}56}
4657
47pub fn __powitf2(a: f128, b: i32) callconv(.c) f128 {58fn __powixf2(a: compiler_rt.f80.Abi, b: i32) callconv(.c) compiler_rt.f80.Abi {
48 return powiXf2(f128, a, b);59 return compiler_rt.f80.toAbi(powi_f80(compiler_rt.f80.fromAbi(a), b));
49}60}
5061pub fn powi_f80(a: f80, b: i32) f80 {
51pub fn __powixf2(a: f80, b: i32) callconv(.c) f80 {
52 return powiXf2(f80, a, b);62 return powiXf2(f80, a, b);
53}63}
5464
65fn __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}
68pub fn powi_f128(a: f128, b: i32) f128 {
69 return powiXf2(f128, a, b);
70}
71
55test {72test {
56 _ = @import("powiXf2_test.zig");73 _ = @import("powiXf2_test.zig");
57}74}
lib/compiler_rt/powiXf2_test.zig+531-525
...@@ -2,562 +2,568 @@...@@ -2,562 +2,568 @@
2// powisf2_test.c, powidf2_test.c, powitf2_test.c, powixf2_test.c2// powisf2_test.c, powidf2_test.c, powitf2_test.c, powixf2_test.c
3// powihf2 adapted from powisf2 tests3// powihf2 adapted from powisf2 tests
44
5const powiXf2 = @import("powiXf2.zig");
6const std = @import("std");5const std = @import("std");
7const builtin = @import("builtin");
8const testing = std.testing;6const testing = std.testing;
9const math = std.math;7const math = std.math;
108
11fn test__powihf2(a: f16, b: i32, expected: f16) !void {9const impl = @import("powiXf2.zig");
12 const result = powiXf2.__powihf2(a, b);10
11const powi_f16 = impl.powi_f16;
12const powi_f32 = impl.powi_f32;
13const powi_f64 = impl.powi_f64;
14const powi_f80 = impl.powi_f80;
15const powi_f128 = impl.powi_f128;
16
17fn test_powi_f16(a: f16, b: i32, expected: f16) !void {
18 const result = powi_f16(a, b);
13 try testing.expectEqual(expected, result);19 try testing.expectEqual(expected, result);
14}20}
1521
16fn test__powisf2(a: f32, b: i32, expected: f32) !void {22fn test_powi_f32(a: f32, b: i32, expected: f32) !void {
17 const result = powiXf2.__powisf2(a, b);23 const result = powi_f32(a, b);
18 try testing.expectEqual(expected, result);24 try testing.expectEqual(expected, result);
19}25}
2026
21fn test__powidf2(a: f64, b: i32, expected: f64) !void {27fn test_powi_f64(a: f64, b: i32, expected: f64) !void {
22 const result = powiXf2.__powidf2(a, b);28 const result = powi_f64(a, b);
23 try testing.expectEqual(expected, result);29 try testing.expectEqual(expected, result);
24}30}
2531
26fn test__powitf2(a: f128, b: i32, expected: f128) !void {32fn test_powi_f80(a: f80, b: i32, expected: f80) !void {
27 const result = powiXf2.__powitf2(a, b);33 const result = powi_f80(a, b);
28 try testing.expectEqual(expected, result);34 try testing.expectEqual(expected, result);
29}35}
3036
31fn test__powixf2(a: f80, b: i32, expected: f80) !void {37fn test_powi_f128(a: f128, b: i32, expected: f128) !void {
32 const result = powiXf2.__powixf2(a, b);38 const result = powi_f128(a, b);
33 try testing.expectEqual(expected, result);39 try testing.expectEqual(expected, result);
34}40}
3541
36test "powihf2" {42test powi_f16 {
37 const inf_f16 = math.inf(f16);43 const inf_f16 = math.inf(f16);
38 try test__powisf2(0, 0, 1);44 try test_powi_f16(0, 0, 1);
39 try test__powihf2(1, 0, 1);45 try test_powi_f16(1, 0, 1);
40 try test__powihf2(1.5, 0, 1);46 try test_powi_f16(1.5, 0, 1);
41 try test__powihf2(2, 0, 1);47 try test_powi_f16(2, 0, 1);
42 try test__powihf2(inf_f16, 0, 1);48 try test_powi_f16(inf_f16, 0, 1);
4349
44 try test__powihf2(-0.0, 0, 1);50 try test_powi_f16(-0.0, 0, 1);
45 try test__powihf2(-1, 0, 1);51 try test_powi_f16(-1, 0, 1);
46 try test__powihf2(-1.5, 0, 1);52 try test_powi_f16(-1.5, 0, 1);
47 try test__powihf2(-2, 0, 1);53 try test_powi_f16(-2, 0, 1);
48 try test__powihf2(-inf_f16, 0, 1);54 try test_powi_f16(-inf_f16, 0, 1);
4955
50 try test__powihf2(0, 1, 0);56 try test_powi_f16(0, 1, 0);
51 try test__powihf2(0, 2, 0);57 try test_powi_f16(0, 2, 0);
52 try test__powihf2(0, 3, 0);58 try test_powi_f16(0, 3, 0);
53 try test__powihf2(0, 4, 0);59 try test_powi_f16(0, 4, 0);
54 try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);60 try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
55 try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);61 try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
5662
57 try test__powihf2(-0.0, 1, -0.0);63 try test_powi_f16(-0.0, 1, -0.0);
58 try test__powihf2(-0.0, 2, 0);64 try test_powi_f16(-0.0, 2, 0);
59 try test__powihf2(-0.0, 3, -0.0);65 try test_powi_f16(-0.0, 3, -0.0);
60 try test__powihf2(-0.0, 4, 0);66 try test_powi_f16(-0.0, 4, 0);
61 try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);67 try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
62 try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);68 try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
6369
64 try test__powihf2(1, 1, 1);70 try test_powi_f16(1, 1, 1);
65 try test__powihf2(1, 2, 1);71 try test_powi_f16(1, 2, 1);
66 try test__powihf2(1, 3, 1);72 try test_powi_f16(1, 3, 1);
67 try test__powihf2(1, 4, 1);73 try test_powi_f16(1, 4, 1);
68 try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);74 try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
69 try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);75 try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
7076
71 try test__powihf2(inf_f16, 1, inf_f16);77 try test_powi_f16(inf_f16, 1, inf_f16);
72 try test__powihf2(inf_f16, 2, inf_f16);78 try test_powi_f16(inf_f16, 2, inf_f16);
73 try test__powihf2(inf_f16, 3, inf_f16);79 try test_powi_f16(inf_f16, 3, inf_f16);
74 try test__powihf2(inf_f16, 4, inf_f16);80 try test_powi_f16(inf_f16, 4, inf_f16);
75 try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16);81 try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16);
76 try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f16);82 try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f16);
7783
78 try test__powihf2(-inf_f16, 1, -inf_f16);84 try test_powi_f16(-inf_f16, 1, -inf_f16);
79 try test__powihf2(-inf_f16, 2, inf_f16);85 try test_powi_f16(-inf_f16, 2, inf_f16);
80 try test__powihf2(-inf_f16, 3, -inf_f16);86 try test_powi_f16(-inf_f16, 3, -inf_f16);
81 try test__powihf2(-inf_f16, 4, inf_f16);87 try test_powi_f16(-inf_f16, 4, inf_f16);
82 try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16);88 try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16);
83 try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -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);91 try test_powi_f16(0, -1, inf_f16);
86 try test__powihf2(0, -2, inf_f16);92 try test_powi_f16(0, -2, inf_f16);
87 try test__powihf2(0, -3, inf_f16);93 try test_powi_f16(0, -3, inf_f16);
88 try test__powihf2(0, -4, inf_f16);94 try test_powi_f16(0, -4, inf_f16);
89 try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // 0 ^ anything = +inf95 try test_powi_f16(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);96 try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f16);
91 try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16);97 try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16);
9298
93 try test__powihf2(-0.0, -1, -inf_f16);99 try test_powi_f16(-0.0, -1, -inf_f16);
94 try test__powihf2(-0.0, -2, inf_f16);100 try test_powi_f16(-0.0, -2, inf_f16);
95 try test__powihf2(-0.0, -3, -inf_f16);101 try test_powi_f16(-0.0, -3, -inf_f16);
96 try test__powihf2(-0.0, -4, inf_f16);102 try test_powi_f16(-0.0, -4, inf_f16);
97 try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // -0 ^ anything even = +inf103 try test_powi_f16(-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 = -inf104 try test_powi_f16(-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);105 try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16);
100106
101 try test__powihf2(1, -1, 1);107 try test_powi_f16(1, -1, 1);
102 try test__powihf2(1, -2, 1);108 try test_powi_f16(1, -2, 1);
103 try test__powihf2(1, -3, 1);109 try test_powi_f16(1, -3, 1);
104 try test__powihf2(1, -4, 1);110 try test_powi_f16(1, -4, 1);
105 try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); // 1.0 ^ anything = 1111 try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); // 1.0 ^ anything = 1
106 try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);112 try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
107 try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);113 try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
108114
109 try test__powihf2(inf_f16, -1, 0);115 try test_powi_f16(inf_f16, -1, 0);
110 try test__powihf2(inf_f16, -2, 0);116 try test_powi_f16(inf_f16, -2, 0);
111 try test__powihf2(inf_f16, -3, 0);117 try test_powi_f16(inf_f16, -3, 0);
112 try test__powihf2(inf_f16, -4, 0);118 try test_powi_f16(inf_f16, -4, 0);
113 try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);119 try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
114 try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);120 try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
115 try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 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);123 try test_powi_f16(-inf_f16, -1, -0.0);
118 try test__powihf2(-inf_f16, -2, 0);124 try test_powi_f16(-inf_f16, -2, 0);
119 try test__powihf2(-inf_f16, -3, -0.0);125 try test_powi_f16(-inf_f16, -3, -0.0);
120 try test__powihf2(-inf_f16, -4, 0);126 try test_powi_f16(-inf_f16, -4, 0);
121 try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);127 try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
122 try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);128 try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
123 try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);129 try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
124130
125 try test__powihf2(2, 10, 1024.0);131 try test_powi_f16(2, 10, 1024.0);
126 try test__powihf2(-2, 10, 1024.0);132 try test_powi_f16(-2, 10, 1024.0);
127 try test__powihf2(2, -10, 1.0 / 1024.0);133 try test_powi_f16(2, -10, 1.0 / 1024.0);
128 try test__powihf2(-2, -10, 1.0 / 1024.0);134 try test_powi_f16(-2, -10, 1.0 / 1024.0);
129135
130 try test__powihf2(2, 14, 16384.0);136 try test_powi_f16(2, 14, 16384.0);
131 try test__powihf2(-2, 14, 16384.0);137 try test_powi_f16(-2, 14, 16384.0);
132 try test__powihf2(2, 15, 32768.0);138 try test_powi_f16(2, 15, 32768.0);
133 try test__powihf2(-2, 15, -32768.0);139 try test_powi_f16(-2, 15, -32768.0);
134 try test__powihf2(2, 16, inf_f16);140 try test_powi_f16(2, 16, inf_f16);
135 try test__powihf2(-2, 16, inf_f16);141 try test_powi_f16(-2, 16, inf_f16);
136142
137 try test__powihf2(2, -13, 1.0 / 8192.0);143 try test_powi_f16(2, -13, 1.0 / 8192.0);
138 try test__powihf2(-2, -13, -1.0 / 8192.0);144 try test_powi_f16(-2, -13, -1.0 / 8192.0);
139 try test__powihf2(2, -15, 1.0 / 32768.0);145 try test_powi_f16(2, -15, 1.0 / 32768.0);
140 try test__powihf2(-2, -15, -1.0 / 32768.0);146 try test_powi_f16(-2, -15, -1.0 / 32768.0);
141 try test__powihf2(2, -16, 0.0); // expected = 0.0 = 1/(-2**16)147 try test_powi_f16(2, -16, 0.0); // expected = 0.0 = 1/(-2**16)
142 try test__powihf2(-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}
144150
145test "powisf2" {151test powi_f32 {
146 const inf_f32 = math.inf(f32);152 const inf_f32 = math.inf(f32);
147 try test__powisf2(0, 0, 1);153 try test_powi_f32(0, 0, 1);
148 try test__powisf2(1, 0, 1);154 try test_powi_f32(1, 0, 1);
149 try test__powisf2(1.5, 0, 1);155 try test_powi_f32(1.5, 0, 1);
150 try test__powisf2(2, 0, 1);156 try test_powi_f32(2, 0, 1);
151 try test__powisf2(inf_f32, 0, 1);157 try test_powi_f32(inf_f32, 0, 1);
152158
153 try test__powisf2(-0.0, 0, 1);159 try test_powi_f32(-0.0, 0, 1);
154 try test__powisf2(-1, 0, 1);160 try test_powi_f32(-1, 0, 1);
155 try test__powisf2(-1.5, 0, 1);161 try test_powi_f32(-1.5, 0, 1);
156 try test__powisf2(-2, 0, 1);162 try test_powi_f32(-2, 0, 1);
157 try test__powisf2(-inf_f32, 0, 1);163 try test_powi_f32(-inf_f32, 0, 1);
158164
159 try test__powisf2(0, 1, 0);165 try test_powi_f32(0, 1, 0);
160 try test__powisf2(0, 2, 0);166 try test_powi_f32(0, 2, 0);
161 try test__powisf2(0, 3, 0);167 try test_powi_f32(0, 3, 0);
162 try test__powisf2(0, 4, 0);168 try test_powi_f32(0, 4, 0);
163 try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);169 try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
164 try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);170 try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
165171
166 try test__powisf2(-0.0, 1, -0.0);172 try test_powi_f32(-0.0, 1, -0.0);
167 try test__powisf2(-0.0, 2, 0);173 try test_powi_f32(-0.0, 2, 0);
168 try test__powisf2(-0.0, 3, -0.0);174 try test_powi_f32(-0.0, 3, -0.0);
169 try test__powisf2(-0.0, 4, 0);175 try test_powi_f32(-0.0, 4, 0);
170 try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);176 try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
171 try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);177 try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
172178
173 try test__powisf2(1, 1, 1);179 try test_powi_f32(1, 1, 1);
174 try test__powisf2(1, 2, 1);180 try test_powi_f32(1, 2, 1);
175 try test__powisf2(1, 3, 1);181 try test_powi_f32(1, 3, 1);
176 try test__powisf2(1, 4, 1);182 try test_powi_f32(1, 4, 1);
177 try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);183 try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
178 try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);184 try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
179185
180 try test__powisf2(inf_f32, 1, inf_f32);186 try test_powi_f32(inf_f32, 1, inf_f32);
181 try test__powisf2(inf_f32, 2, inf_f32);187 try test_powi_f32(inf_f32, 2, inf_f32);
182 try test__powisf2(inf_f32, 3, inf_f32);188 try test_powi_f32(inf_f32, 3, inf_f32);
183 try test__powisf2(inf_f32, 4, inf_f32);189 try test_powi_f32(inf_f32, 4, inf_f32);
184 try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32);190 try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32);
185 try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f32);191 try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f32);
186192
187 try test__powisf2(-inf_f32, 1, -inf_f32);193 try test_powi_f32(-inf_f32, 1, -inf_f32);
188 try test__powisf2(-inf_f32, 2, inf_f32);194 try test_powi_f32(-inf_f32, 2, inf_f32);
189 try test__powisf2(-inf_f32, 3, -inf_f32);195 try test_powi_f32(-inf_f32, 3, -inf_f32);
190 try test__powisf2(-inf_f32, 4, inf_f32);196 try test_powi_f32(-inf_f32, 4, inf_f32);
191 try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32);197 try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32);
192 try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f32);198 try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f32);
193199
194 try test__powisf2(0, -1, inf_f32);200 try test_powi_f32(0, -1, inf_f32);
195 try test__powisf2(0, -2, inf_f32);201 try test_powi_f32(0, -2, inf_f32);
196 try test__powisf2(0, -3, inf_f32);202 try test_powi_f32(0, -3, inf_f32);
197 try test__powisf2(0, -4, inf_f32);203 try test_powi_f32(0, -4, inf_f32);
198 try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32);204 try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32);
199 try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f32);205 try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f32);
200 try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32);206 try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32);
201207
202 try test__powisf2(-0.0, -1, -inf_f32);208 try test_powi_f32(-0.0, -1, -inf_f32);
203 try test__powisf2(-0.0, -2, inf_f32);209 try test_powi_f32(-0.0, -2, inf_f32);
204 try test__powisf2(-0.0, -3, -inf_f32);210 try test_powi_f32(-0.0, -3, -inf_f32);
205 try test__powisf2(-0.0, -4, inf_f32);211 try test_powi_f32(-0.0, -4, inf_f32);
206 try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32);212 try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32);
207 try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f32);213 try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f32);
208 try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32);214 try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32);
209215
210 try test__powisf2(1, -1, 1);216 try test_powi_f32(1, -1, 1);
211 try test__powisf2(1, -2, 1);217 try test_powi_f32(1, -2, 1);
212 try test__powisf2(1, -3, 1);218 try test_powi_f32(1, -3, 1);
213 try test__powisf2(1, -4, 1);219 try test_powi_f32(1, -4, 1);
214 try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);220 try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
215 try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);221 try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
216 try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);222 try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
217223
218 try test__powisf2(inf_f32, -1, 0);224 try test_powi_f32(inf_f32, -1, 0);
219 try test__powisf2(inf_f32, -2, 0);225 try test_powi_f32(inf_f32, -2, 0);
220 try test__powisf2(inf_f32, -3, 0);226 try test_powi_f32(inf_f32, -3, 0);
221 try test__powisf2(inf_f32, -4, 0);227 try test_powi_f32(inf_f32, -4, 0);
222 try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);228 try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
223 try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);229 try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
224 try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);230 try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
225231
226 try test__powisf2(-inf_f32, -1, -0.0);232 try test_powi_f32(-inf_f32, -1, -0.0);
227 try test__powisf2(-inf_f32, -2, 0);233 try test_powi_f32(-inf_f32, -2, 0);
228 try test__powisf2(-inf_f32, -3, -0.0);234 try test_powi_f32(-inf_f32, -3, -0.0);
229 try test__powisf2(-inf_f32, -4, 0);235 try test_powi_f32(-inf_f32, -4, 0);
230 try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);236 try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
231 try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);237 try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
232 try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);238 try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
233239
234 try test__powisf2(2.0, 10, 1024.0);240 try test_powi_f32(2.0, 10, 1024.0);
235 try test__powisf2(-2, 10, 1024.0);241 try test_powi_f32(-2, 10, 1024.0);
236 try test__powisf2(2, -10, 1.0 / 1024.0);242 try test_powi_f32(2, -10, 1.0 / 1024.0);
237 try test__powisf2(-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);245 try test_powi_f32(2, 19, 524288.0);
240 try test__powisf2(-2, 19, -524288.0);246 try test_powi_f32(-2, 19, -524288.0);
241 try test__powisf2(2, -19, 1.0 / 524288.0);247 try test_powi_f32(2, -19, 1.0 / 524288.0);
242 try test__powisf2(-2, -19, -1.0 / 524288.0);248 try test_powi_f32(-2, -19, -1.0 / 524288.0);
243249
244 try test__powisf2(2, 31, 2147483648.0);250 try test_powi_f32(2, 31, 2147483648.0);
245 try test__powisf2(-2, 31, -2147483648.0);251 try test_powi_f32(-2, 31, -2147483648.0);
246 try test__powisf2(2, -31, 1.0 / 2147483648.0);252 try test_powi_f32(2, -31, 1.0 / 2147483648.0);
247 try test__powisf2(-2, -31, -1.0 / 2147483648.0);253 try test_powi_f32(-2, -31, -1.0 / 2147483648.0);
248}254}
249255
250test "powidf2" {256test powi_f64 {
251 const inf_f64 = math.inf(f64);257 const inf_f64 = math.inf(f64);
252 try test__powidf2(0, 0, 1);258 try test_powi_f64(0, 0, 1);
253 try test__powidf2(1, 0, 1);259 try test_powi_f64(1, 0, 1);
254 try test__powidf2(1.5, 0, 1);260 try test_powi_f64(1.5, 0, 1);
255 try test__powidf2(2, 0, 1);261 try test_powi_f64(2, 0, 1);
256 try test__powidf2(inf_f64, 0, 1);262 try test_powi_f64(inf_f64, 0, 1);
257263
258 try test__powidf2(-0.0, 0, 1);264 try test_powi_f64(-0.0, 0, 1);
259 try test__powidf2(-1, 0, 1);265 try test_powi_f64(-1, 0, 1);
260 try test__powidf2(-1.5, 0, 1);266 try test_powi_f64(-1.5, 0, 1);
261 try test__powidf2(-2, 0, 1);267 try test_powi_f64(-2, 0, 1);
262 try test__powidf2(-inf_f64, 0, 1);268 try test_powi_f64(-inf_f64, 0, 1);
263269
264 try test__powidf2(0, 1, 0);270 try test_powi_f64(0, 1, 0);
265 try test__powidf2(0, 2, 0);271 try test_powi_f64(0, 2, 0);
266 try test__powidf2(0, 3, 0);272 try test_powi_f64(0, 3, 0);
267 try test__powidf2(0, 4, 0);273 try test_powi_f64(0, 4, 0);
268 try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);274 try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
269 try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);275 try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
270276
271 try test__powidf2(-0.0, 1, -0.0);277 try test_powi_f64(-0.0, 1, -0.0);
272 try test__powidf2(-0.0, 2, 0);278 try test_powi_f64(-0.0, 2, 0);
273 try test__powidf2(-0.0, 3, -0.0);279 try test_powi_f64(-0.0, 3, -0.0);
274 try test__powidf2(-0.0, 4, 0);280 try test_powi_f64(-0.0, 4, 0);
275 try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);281 try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
276 try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);282 try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
277283
278 try test__powidf2(1, 1, 1);284 try test_powi_f64(1, 1, 1);
279 try test__powidf2(1, 2, 1);285 try test_powi_f64(1, 2, 1);
280 try test__powidf2(1, 3, 1);286 try test_powi_f64(1, 3, 1);
281 try test__powidf2(1, 4, 1);287 try test_powi_f64(1, 4, 1);
282 try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);288 try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
283 try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);289 try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
284290
285 try test__powidf2(inf_f64, 1, inf_f64);291 try test_powi_f64(inf_f64, 1, inf_f64);
286 try test__powidf2(inf_f64, 2, inf_f64);292 try test_powi_f64(inf_f64, 2, inf_f64);
287 try test__powidf2(inf_f64, 3, inf_f64);293 try test_powi_f64(inf_f64, 3, inf_f64);
288 try test__powidf2(inf_f64, 4, inf_f64);294 try test_powi_f64(inf_f64, 4, inf_f64);
289 try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64);295 try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64);
290 try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f64);296 try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f64);
291297
292 try test__powidf2(-inf_f64, 1, -inf_f64);298 try test_powi_f64(-inf_f64, 1, -inf_f64);
293 try test__powidf2(-inf_f64, 2, inf_f64);299 try test_powi_f64(-inf_f64, 2, inf_f64);
294 try test__powidf2(-inf_f64, 3, -inf_f64);300 try test_powi_f64(-inf_f64, 3, -inf_f64);
295 try test__powidf2(-inf_f64, 4, inf_f64);301 try test_powi_f64(-inf_f64, 4, inf_f64);
296 try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64);302 try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64);
297 try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f64);303 try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f64);
298304
299 try test__powidf2(0, -1, inf_f64);305 try test_powi_f64(0, -1, inf_f64);
300 try test__powidf2(0, -2, inf_f64);306 try test_powi_f64(0, -2, inf_f64);
301 try test__powidf2(0, -3, inf_f64);307 try test_powi_f64(0, -3, inf_f64);
302 try test__powidf2(0, -4, inf_f64);308 try test_powi_f64(0, -4, inf_f64);
303 try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64);309 try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64);
304 try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f64);310 try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f64);
305 try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64);311 try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64);
306312
307 try test__powidf2(-0.0, -1, -inf_f64);313 try test_powi_f64(-0.0, -1, -inf_f64);
308 try test__powidf2(-0.0, -2, inf_f64);314 try test_powi_f64(-0.0, -2, inf_f64);
309 try test__powidf2(-0.0, -3, -inf_f64);315 try test_powi_f64(-0.0, -3, -inf_f64);
310 try test__powidf2(-0.0, -4, inf_f64);316 try test_powi_f64(-0.0, -4, inf_f64);
311 try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64);317 try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64);
312 try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f64);318 try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f64);
313 try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64);319 try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64);
314320
315 try test__powidf2(1, -1, 1);321 try test_powi_f64(1, -1, 1);
316 try test__powidf2(1, -2, 1);322 try test_powi_f64(1, -2, 1);
317 try test__powidf2(1, -3, 1);323 try test_powi_f64(1, -3, 1);
318 try test__powidf2(1, -4, 1);324 try test_powi_f64(1, -4, 1);
319 try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);325 try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
320 try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);326 try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
321 try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);327 try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
322328
323 try test__powidf2(inf_f64, -1, 0);329 try test_powi_f64(inf_f64, -1, 0);
324 try test__powidf2(inf_f64, -2, 0);330 try test_powi_f64(inf_f64, -2, 0);
325 try test__powidf2(inf_f64, -3, 0);331 try test_powi_f64(inf_f64, -3, 0);
326 try test__powidf2(inf_f64, -4, 0);332 try test_powi_f64(inf_f64, -4, 0);
327 try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);333 try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
328 try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);334 try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
329 try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);335 try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
330336
331 try test__powidf2(-inf_f64, -1, -0.0);337 try test_powi_f64(-inf_f64, -1, -0.0);
332 try test__powidf2(-inf_f64, -2, 0);338 try test_powi_f64(-inf_f64, -2, 0);
333 try test__powidf2(-inf_f64, -3, -0.0);339 try test_powi_f64(-inf_f64, -3, -0.0);
334 try test__powidf2(-inf_f64, -4, 0);340 try test_powi_f64(-inf_f64, -4, 0);
335 try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);341 try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
336 try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);342 try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
337 try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);343 try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
338344
339 try test__powidf2(2, 10, 1024.0);345 try test_powi_f64(2, 10, 1024.0);
340 try test__powidf2(-2, 10, 1024.0);346 try test_powi_f64(-2, 10, 1024.0);
341 try test__powidf2(2, -10, 1.0 / 1024.0);347 try test_powi_f64(2, -10, 1.0 / 1024.0);
342 try test__powidf2(-2, -10, 1.0 / 1024.0);348 try test_powi_f64(-2, -10, 1.0 / 1024.0);
343349
344 try test__powidf2(2, 19, 524288.0);350 try test_powi_f64(2, 19, 524288.0);
345 try test__powidf2(-2, 19, -524288.0);351 try test_powi_f64(-2, 19, -524288.0);
346 try test__powidf2(2, -19, 1.0 / 524288.0);352 try test_powi_f64(2, -19, 1.0 / 524288.0);
347 try test__powidf2(-2, -19, -1.0 / 524288.0);353 try test_powi_f64(-2, -19, -1.0 / 524288.0);
348354
349 try test__powidf2(2, 31, 2147483648.0);355 try test_powi_f64(2, 31, 2147483648.0);
350 try test__powidf2(-2, 31, -2147483648.0);356 try test_powi_f64(-2, 31, -2147483648.0);
351 try test__powidf2(2, -31, 1.0 / 2147483648.0);357 try test_powi_f64(2, -31, 1.0 / 2147483648.0);
352 try test__powidf2(-2, -31, -1.0 / 2147483648.0);358 try test_powi_f64(-2, -31, -1.0 / 2147483648.0);
353}359}
354360
355test "powitf2" {361test powi_f80 {
356 const inf_f128 = math.inf(f128);362 const inf_f80 = math.inf(f80);
357 try test__powitf2(0, 0, 1);363 try test_powi_f80(0, 0, 1);
358 try test__powitf2(1, 0, 1);364 try test_powi_f80(1, 0, 1);
359 try test__powitf2(1.5, 0, 1);365 try test_powi_f80(1.5, 0, 1);
360 try test__powitf2(2, 0, 1);366 try test_powi_f80(2, 0, 1);
361 try test__powitf2(inf_f128, 0, 1);367 try test_powi_f80(inf_f80, 0, 1);
362368
363 try test__powitf2(-0.0, 0, 1);369 try test_powi_f80(-0.0, 0, 1);
364 try test__powitf2(-1, 0, 1);370 try test_powi_f80(-1, 0, 1);
365 try test__powitf2(-1.5, 0, 1);371 try test_powi_f80(-1.5, 0, 1);
366 try test__powitf2(-2, 0, 1);372 try test_powi_f80(-2, 0, 1);
367 try test__powitf2(-inf_f128, 0, 1);373 try test_powi_f80(-inf_f80, 0, 1);
368374
369 try test__powitf2(0, 1, 0);375 try test_powi_f80(0, 1, 0);
370 try test__powitf2(0, 2, 0);376 try test_powi_f80(0, 2, 0);
371 try test__powitf2(0, 3, 0);377 try test_powi_f80(0, 3, 0);
372 try test__powitf2(0, 4, 0);378 try test_powi_f80(0, 4, 0);
373 try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);379 try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
374 try test__powitf2(0, 0x7FFFFFFF, 0);380 try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
375381
376 try test__powitf2(-0.0, 1, -0.0);382 try test_powi_f80(-0.0, 1, -0.0);
377 try test__powitf2(-0.0, 2, 0);383 try test_powi_f80(-0.0, 2, 0);
378 try test__powitf2(-0.0, 3, -0.0);384 try test_powi_f80(-0.0, 3, -0.0);
379 try test__powitf2(-0.0, 4, 0);385 try test_powi_f80(-0.0, 4, 0);
380 try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);386 try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
381 try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);387 try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
382388
383 try test__powitf2(1, 1, 1);389 try test_powi_f80(1, 1, 1);
384 try test__powitf2(1, 2, 1);390 try test_powi_f80(1, 2, 1);
385 try test__powitf2(1, 3, 1);391 try test_powi_f80(1, 3, 1);
386 try test__powitf2(1, 4, 1);392 try test_powi_f80(1, 4, 1);
387 try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);393 try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
388 try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);394 try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
389395
390 try test__powitf2(inf_f128, 1, inf_f128);396 try test_powi_f80(inf_f80, 1, inf_f80);
391 try test__powitf2(inf_f128, 2, inf_f128);397 try test_powi_f80(inf_f80, 2, inf_f80);
392 try test__powitf2(inf_f128, 3, inf_f128);398 try test_powi_f80(inf_f80, 3, inf_f80);
393 try test__powitf2(inf_f128, 4, inf_f128);399 try test_powi_f80(inf_f80, 4, inf_f80);
394 try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128);400 try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80);
395 try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f128);401 try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f80);
396402
397 try test__powitf2(-inf_f128, 1, -inf_f128);403 try test_powi_f80(-inf_f80, 1, -inf_f80);
398 try test__powitf2(-inf_f128, 2, inf_f128);404 try test_powi_f80(-inf_f80, 2, inf_f80);
399 try test__powitf2(-inf_f128, 3, -inf_f128);405 try test_powi_f80(-inf_f80, 3, -inf_f80);
400 try test__powitf2(-inf_f128, 4, inf_f128);406 try test_powi_f80(-inf_f80, 4, inf_f80);
401 try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128);407 try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80);
402 try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f128);408 try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f80);
403409
404 try test__powitf2(0, -1, inf_f128);410 try test_powi_f80(0, -1, inf_f80);
405 try test__powitf2(0, -2, inf_f128);411 try test_powi_f80(0, -2, inf_f80);
406 try test__powitf2(0, -3, inf_f128);412 try test_powi_f80(0, -3, inf_f80);
407 try test__powitf2(0, -4, inf_f128);413 try test_powi_f80(0, -4, inf_f80);
408 try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128);414 try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80);
409 try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f128);415 try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f80);
410 try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128);416 try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80);
411417
412 try test__powitf2(-0.0, -1, -inf_f128);418 try test_powi_f80(-0.0, -1, -inf_f80);
413 try test__powitf2(-0.0, -2, inf_f128);419 try test_powi_f80(-0.0, -2, inf_f80);
414 try test__powitf2(-0.0, -3, -inf_f128);420 try test_powi_f80(-0.0, -3, -inf_f80);
415 try test__powitf2(-0.0, -4, inf_f128);421 try test_powi_f80(-0.0, -4, inf_f80);
416 try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128);422 try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80);
417 try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f128);423 try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f80);
418 try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128);424 try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80);
419425
420 try test__powitf2(1, -1, 1);426 try test_powi_f80(1, -1, 1);
421 try test__powitf2(1, -2, 1);427 try test_powi_f80(1, -2, 1);
422 try test__powitf2(1, -3, 1);428 try test_powi_f80(1, -3, 1);
423 try test__powitf2(1, -4, 1);429 try test_powi_f80(1, -4, 1);
424 try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);430 try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
425 try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);431 try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
426 try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);432 try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
427433
428 try test__powitf2(inf_f128, -1, 0);434 try test_powi_f80(inf_f80, -1, 0);
429 try test__powitf2(inf_f128, -2, 0);435 try test_powi_f80(inf_f80, -2, 0);
430 try test__powitf2(inf_f128, -3, 0);436 try test_powi_f80(inf_f80, -3, 0);
431 try test__powitf2(inf_f128, -4, 0);437 try test_powi_f80(inf_f80, -4, 0);
432 try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);438 try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
433 try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);439 try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
434 try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);440 try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
435441
436 try test__powitf2(-inf_f128, -1, -0.0);442 try test_powi_f80(-inf_f80, -1, -0.0);
437 try test__powitf2(-inf_f128, -2, 0);443 try test_powi_f80(-inf_f80, -2, 0);
438 try test__powitf2(-inf_f128, -3, -0.0);444 try test_powi_f80(-inf_f80, -3, -0.0);
439 try test__powitf2(-inf_f128, -4, 0);445 try test_powi_f80(-inf_f80, -4, 0);
440 try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);446 try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
441 try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);447 try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
442 try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);448 try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
443449
444 try test__powitf2(2, 10, 1024.0);450 try test_powi_f80(2, 10, 1024.0);
445 try test__powitf2(-2, 10, 1024.0);451 try test_powi_f80(-2, 10, 1024.0);
446 try test__powitf2(2, -10, 1.0 / 1024.0);452 try test_powi_f80(2, -10, 1.0 / 1024.0);
447 try test__powitf2(-2, -10, 1.0 / 1024.0);453 try test_powi_f80(-2, -10, 1.0 / 1024.0);
448454
449 try test__powitf2(2, 19, 524288.0);455 try test_powi_f80(2, 19, 524288.0);
450 try test__powitf2(-2, 19, -524288.0);456 try test_powi_f80(-2, 19, -524288.0);
451 try test__powitf2(2, -19, 1.0 / 524288.0);457 try test_powi_f80(2, -19, 1.0 / 524288.0);
452 try test__powitf2(-2, -19, -1.0 / 524288.0);458 try test_powi_f80(-2, -19, -1.0 / 524288.0);
453459
454 try test__powitf2(2, 31, 2147483648.0);460 try test_powi_f80(2, 31, 2147483648.0);
455 try test__powitf2(-2, 31, -2147483648.0);461 try test_powi_f80(-2, 31, -2147483648.0);
456 try test__powitf2(2, -31, 1.0 / 2147483648.0);462 try test_powi_f80(2, -31, 1.0 / 2147483648.0);
457 try test__powitf2(-2, -31, -1.0 / 2147483648.0);463 try test_powi_f80(-2, -31, -1.0 / 2147483648.0);
458}464}
459465
460test "powixf2" {466test powi_f128 {
461 const inf_f80 = math.inf(f80);467 const inf_f128 = math.inf(f128);
462 try test__powixf2(0, 0, 1);468 try test_powi_f128(0, 0, 1);
463 try test__powixf2(1, 0, 1);469 try test_powi_f128(1, 0, 1);
464 try test__powixf2(1.5, 0, 1);470 try test_powi_f128(1.5, 0, 1);
465 try test__powixf2(2, 0, 1);471 try test_powi_f128(2, 0, 1);
466 try test__powixf2(inf_f80, 0, 1);472 try test_powi_f128(inf_f128, 0, 1);
467473
468 try test__powixf2(-0.0, 0, 1);474 try test_powi_f128(-0.0, 0, 1);
469 try test__powixf2(-1, 0, 1);475 try test_powi_f128(-1, 0, 1);
470 try test__powixf2(-1.5, 0, 1);476 try test_powi_f128(-1.5, 0, 1);
471 try test__powixf2(-2, 0, 1);477 try test_powi_f128(-2, 0, 1);
472 try test__powixf2(-inf_f80, 0, 1);478 try test_powi_f128(-inf_f128, 0, 1);
473479
474 try test__powixf2(0, 1, 0);480 try test_powi_f128(0, 1, 0);
475 try test__powixf2(0, 2, 0);481 try test_powi_f128(0, 2, 0);
476 try test__powixf2(0, 3, 0);482 try test_powi_f128(0, 3, 0);
477 try test__powixf2(0, 4, 0);483 try test_powi_f128(0, 4, 0);
478 try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);484 try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
479 try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);485 try test_powi_f128(0, 0x7FFFFFFF, 0);
480486
481 try test__powixf2(-0.0, 1, -0.0);487 try test_powi_f128(-0.0, 1, -0.0);
482 try test__powixf2(-0.0, 2, 0);488 try test_powi_f128(-0.0, 2, 0);
483 try test__powixf2(-0.0, 3, -0.0);489 try test_powi_f128(-0.0, 3, -0.0);
484 try test__powixf2(-0.0, 4, 0);490 try test_powi_f128(-0.0, 4, 0);
485 try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);491 try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
486 try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);492 try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
487493
488 try test__powixf2(1, 1, 1);494 try test_powi_f128(1, 1, 1);
489 try test__powixf2(1, 2, 1);495 try test_powi_f128(1, 2, 1);
490 try test__powixf2(1, 3, 1);496 try test_powi_f128(1, 3, 1);
491 try test__powixf2(1, 4, 1);497 try test_powi_f128(1, 4, 1);
492 try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);498 try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
493 try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);499 try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
494500
495 try test__powixf2(inf_f80, 1, inf_f80);501 try test_powi_f128(inf_f128, 1, inf_f128);
496 try test__powixf2(inf_f80, 2, inf_f80);502 try test_powi_f128(inf_f128, 2, inf_f128);
497 try test__powixf2(inf_f80, 3, inf_f80);503 try test_powi_f128(inf_f128, 3, inf_f128);
498 try test__powixf2(inf_f80, 4, inf_f80);504 try test_powi_f128(inf_f128, 4, inf_f128);
499 try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80);505 try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128);
500 try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f80);506 try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f128);
501507
502 try test__powixf2(-inf_f80, 1, -inf_f80);508 try test_powi_f128(-inf_f128, 1, -inf_f128);
503 try test__powixf2(-inf_f80, 2, inf_f80);509 try test_powi_f128(-inf_f128, 2, inf_f128);
504 try test__powixf2(-inf_f80, 3, -inf_f80);510 try test_powi_f128(-inf_f128, 3, -inf_f128);
505 try test__powixf2(-inf_f80, 4, inf_f80);511 try test_powi_f128(-inf_f128, 4, inf_f128);
506 try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80);512 try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128);
507 try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f80);513 try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f128);
508514
509 try test__powixf2(0, -1, inf_f80);515 try test_powi_f128(0, -1, inf_f128);
510 try test__powixf2(0, -2, inf_f80);516 try test_powi_f128(0, -2, inf_f128);
511 try test__powixf2(0, -3, inf_f80);517 try test_powi_f128(0, -3, inf_f128);
512 try test__powixf2(0, -4, inf_f80);518 try test_powi_f128(0, -4, inf_f128);
513 try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80);519 try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128);
514 try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f80);520 try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f128);
515 try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80);521 try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128);
516522
517 try test__powixf2(-0.0, -1, -inf_f80);523 try test_powi_f128(-0.0, -1, -inf_f128);
518 try test__powixf2(-0.0, -2, inf_f80);524 try test_powi_f128(-0.0, -2, inf_f128);
519 try test__powixf2(-0.0, -3, -inf_f80);525 try test_powi_f128(-0.0, -3, -inf_f128);
520 try test__powixf2(-0.0, -4, inf_f80);526 try test_powi_f128(-0.0, -4, inf_f128);
521 try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80);527 try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128);
522 try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f80);528 try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f128);
523 try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80);529 try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128);
524530
525 try test__powixf2(1, -1, 1);531 try test_powi_f128(1, -1, 1);
526 try test__powixf2(1, -2, 1);532 try test_powi_f128(1, -2, 1);
527 try test__powixf2(1, -3, 1);533 try test_powi_f128(1, -3, 1);
528 try test__powixf2(1, -4, 1);534 try test_powi_f128(1, -4, 1);
529 try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);535 try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
530 try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);536 try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
531 try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);537 try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
532538
533 try test__powixf2(inf_f80, -1, 0);539 try test_powi_f128(inf_f128, -1, 0);
534 try test__powixf2(inf_f80, -2, 0);540 try test_powi_f128(inf_f128, -2, 0);
535 try test__powixf2(inf_f80, -3, 0);541 try test_powi_f128(inf_f128, -3, 0);
536 try test__powixf2(inf_f80, -4, 0);542 try test_powi_f128(inf_f128, -4, 0);
537 try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);543 try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
538 try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);544 try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
539 try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);545 try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
540546
541 try test__powixf2(-inf_f80, -1, -0.0);547 try test_powi_f128(-inf_f128, -1, -0.0);
542 try test__powixf2(-inf_f80, -2, 0);548 try test_powi_f128(-inf_f128, -2, 0);
543 try test__powixf2(-inf_f80, -3, -0.0);549 try test_powi_f128(-inf_f128, -3, -0.0);
544 try test__powixf2(-inf_f80, -4, 0);550 try test_powi_f128(-inf_f128, -4, 0);
545 try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);551 try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
546 try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);552 try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
547 try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);553 try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
548554
549 try test__powixf2(2, 10, 1024.0);555 try test_powi_f128(2, 10, 1024.0);
550 try test__powixf2(-2, 10, 1024.0);556 try test_powi_f128(-2, 10, 1024.0);
551 try test__powixf2(2, -10, 1.0 / 1024.0);557 try test_powi_f128(2, -10, 1.0 / 1024.0);
552 try test__powixf2(-2, -10, 1.0 / 1024.0);558 try test_powi_f128(-2, -10, 1.0 / 1024.0);
553559
554 try test__powixf2(2, 19, 524288.0);560 try test_powi_f128(2, 19, 524288.0);
555 try test__powixf2(-2, 19, -524288.0);561 try test_powi_f128(-2, 19, -524288.0);
556 try test__powixf2(2, -19, 1.0 / 524288.0);562 try test_powi_f128(2, -19, 1.0 / 524288.0);
557 try test__powixf2(-2, -19, -1.0 / 524288.0);563 try test_powi_f128(-2, -19, -1.0 / 524288.0);
558564
559 try test__powixf2(2, 31, 2147483648.0);565 try test_powi_f128(2, 31, 2147483648.0);
560 try test__powixf2(-2, 31, -2147483648.0);566 try test_powi_f128(-2, 31, -2147483648.0);
561 try test__powixf2(2, -31, 1.0 / 2147483648.0);567 try test_powi_f128(2, -31, 1.0 / 2147483648.0);
562 try test__powixf2(-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,19 +18,23 @@ comptime {
18 symbol(&roundf, "roundf");18 symbol(&roundf, "roundf");
19 symbol(&round, "round");19 symbol(&round, "round");
20 symbol(&__roundx, "__roundx");20 symbol(&__roundx, "__roundx");
21 if (compiler_rt.want_ppc_abi) {21 if (compiler_rt.want_ppc_abi) symbol(&roundq, "roundf128");
22 symbol(&roundq, "roundf128");
23 }
24 symbol(&roundq, "roundq");22 symbol(&roundq, "roundq");
25 symbol(&roundl, "roundl");23 symbol(&roundl, "roundl");
26}24}
2725
28pub fn __roundh(x: f16) callconv(.c) f16 {26fn __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}
29pub fn round_f16(x: f16) f16 {
29 // TODO: more efficient implementation30 // TODO: more efficient implementation
30 return @floatCast(roundf(x));31 return @floatCast(round_f32(x));
31}32}
3233
33pub fn roundf(x_: f32) callconv(.c) f32 {34fn 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}
37pub fn round_f32(x_: f32) f32 {
34 const f32_toint = 1.0 / math.floatEps(f32);38 const f32_toint = 1.0 / math.floatEps(f32);
3539
36 var x = x_;40 var x = x_;
...@@ -65,7 +69,10 @@ pub fn roundf(x_: f32) callconv(.c) f32 {...@@ -65,7 +69,10 @@ pub fn roundf(x_: f32) callconv(.c) f32 {
65 }69 }
66}70}
6771
68pub fn round(x_: f64) callconv(.c) f64 {72fn 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}
75pub fn round_f64(x_: f64) f64 {
69 const f64_toint = 1.0 / math.floatEps(f64);76 const f64_toint = 1.0 / math.floatEps(f64);
7077
71 var x = x_;78 var x = x_;
...@@ -100,12 +107,18 @@ pub fn round(x_: f64) callconv(.c) f64 {...@@ -100,12 +107,18 @@ pub fn round(x_: f64) callconv(.c) f64 {
100 }107 }
101}108}
102109
103pub fn __roundx(x: f80) callconv(.c) f80 {110fn __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}
113pub fn round_f80(x: f80) f80 {
104 // TODO: more efficient implementation114 // TODO: more efficient implementation
105 return @floatCast(roundq(x));115 return @floatCast(round_f128(x));
106}116}
107117
108pub fn roundq(x_: f128) callconv(.c) f128 {118fn 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}
121pub fn round_f128(x_: f128) f128 {
109 const f128_toint = 1.0 / math.floatEps(f128);122 const f128_toint = 1.0 / math.floatEps(f128);
110123
111 var x = x_;124 var x = x_;
...@@ -142,54 +155,79 @@ pub fn roundq(x_: f128) callconv(.c) f128 {...@@ -142,54 +155,79 @@ pub fn roundq(x_: f128) callconv(.c) f128 {
142155
143pub fn roundl(x: c_longdouble) callconv(.c) c_longdouble {156pub fn roundl(x: c_longdouble) callconv(.c) c_longdouble {
144 switch (@typeInfo(c_longdouble).float.bits) {157 switch (@typeInfo(c_longdouble).float.bits) {
145 64 => return round(x),158 64 => return round_f64(x),
146 80 => return __roundx(x),159 80 => return round_f80(x),
147 128 => return roundq(x),160 128 => return round_f128(x),
148 else => @compileError("unreachable"),161 else => comptime unreachable,
149 }162 }
150}163}
151164
152test "round32" {165test round_f16 {
153 try expect(roundf(1.3) == 1.0);166 try expect(round_f16(1.3) == 1.0);
154 try expect(roundf(-1.3) == -1.0);167 try expect(round_f16(-1.3) == -1.0);
155 try expect(roundf(0.2) == 0.0);168 try expect(round_f16(1.8) == 2.0);
156 try expect(roundf(1.8) == 2.0);169 try expect(round_f16(-1.8) == -2.0);
157}170 try expect(math.isPositiveZero(round_f16(0.2)));
158171 try expect(math.isNegativeZero(round_f16(-0.2)));
159test "round64" {172 try expect(math.isPositiveZero(round_f16(0.0)));
160 try expect(round(1.3) == 1.0);173 try expect(math.isNegativeZero(round_f16(-0.0)));
161 try expect(round(-1.3) == -1.0);174 try expect(math.isPositiveInf(round_f16(math.inf(f32))));
162 try expect(round(0.2) == 0.0);175 try expect(math.isNegativeInf(round_f16(-math.inf(f32))));
163 try expect(round(1.8) == 2.0);176 try expect(math.isNan(round_f16(math.nan(f32))));
164}177}
165178
166test "round128" {179test round_f32 {
167 try expect(roundq(1.3) == 1.0);180 try expect(round_f32(1.3) == 1.0);
168 try expect(roundq(-1.3) == -1.0);181 try expect(round_f32(-1.3) == -1.0);
169 try expect(roundq(0.2) == 0.0);182 try expect(round_f32(1.8) == 2.0);
170 try expect(roundq(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}
172192
173test "round32.special" {193test round_f64 {
174 try expect(roundf(0.0) == 0.0);194 try expect(round_f64(1.3) == 1.0);
175 try expect(roundf(-0.0) == -0.0);195 try expect(round_f64(-1.3) == -1.0);
176 try expect(math.isPositiveInf(roundf(math.inf(f32))));196 try expect(round_f64(1.8) == 2.0);
177 try expect(math.isNegativeInf(roundf(-math.inf(f32))));197 try expect(round_f64(-1.8) == -2.0);
178 try expect(math.isNan(roundf(math.nan(f32))));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}
180206
181test "round64.special" {207test round_f80 {
182 try expect(round(0.0) == 0.0);208 try expect(round_f80(1.3) == 1.0);
183 try expect(round(-0.0) == -0.0);209 try expect(round_f80(-1.3) == -1.0);
184 try expect(math.isPositiveInf(round(math.inf(f64))));210 try expect(round_f80(1.8) == 2.0);
185 try expect(math.isNegativeInf(round(-math.inf(f64))));211 try expect(round_f80(-1.8) == -2.0);
186 try expect(math.isNan(round(math.nan(f64))));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}
188220
189test "round128.special" {221test round_f128 {
190 try expect(roundq(0.0) == 0.0);222 try expect(round_f128(1.3) == 1.0);
191 try expect(roundq(-0.0) == -0.0);223 try expect(round_f128(-1.3) == -1.0);
192 try expect(math.isPositiveInf(roundq(math.inf(f128))));224 try expect(round_f128(1.8) == 2.0);
193 try expect(math.isNegativeInf(roundq(-math.inf(f128))));225 try expect(round_f128(-1.8) == -2.0);
194 try expect(math.isNan(roundq(math.nan(f128))));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,31 +13,37 @@ const expect = std.testing.expect;
13const expectApproxEqAbs = std.testing.expectApproxEqAbs;13const expectApproxEqAbs = std.testing.expectApproxEqAbs;
1414
15const compiler_rt = @import("../compiler_rt.zig");15const compiler_rt = @import("../compiler_rt.zig");
16const symbol = @import("../compiler_rt.zig").symbol;16const symbol = compiler_rt.symbol;
17const trig = @import("trig.zig");17const trig = @import("trig.zig");
18const rem_pio2 = @import("rem_pio2.zig").rem_pio2;18const rem_pio2 = @import("rem_pio2.zig").rem_pio2;
19const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;19const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;
20const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l;20const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l;
2121
22comptime {22comptime {
23 symbol(&sinh, "__sinh");23 symbol(&__sinh, "__sinh");
24 symbol(&sinl, "__sinl");
25 symbol(&sinf, "sinf");24 symbol(&sinf, "sinf");
26 symbol(&sin, "sin");25 symbol(&sin, "sin");
27 symbol(&sinx, "__sinx");26 symbol(&__sinx, "__sinx");
28 if (compiler_rt.want_ppc_abi) {27 if (compiler_rt.want_ppc_abi) {
29 symbol(&sinq, "sinf128");28 symbol(&sinq, "sinf128");
30 }29 }
31 symbol(&sinq, "sinq");30 symbol(&sinq, "sinq");
32 symbol(&sinl, "sinl");31 symbol(&sinl, "sinl");
32 symbol(&sinl, "__sinl"); // required by musl
33}33}
3434
35pub fn sinh(x: f16) callconv(.c) f16 {35fn __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}
38pub fn sin_f16(x: f16) f16 {
36 // TODO: more efficient implementation39 // TODO: more efficient implementation
37 return @floatCast(sinf(x));40 return @floatCast(sin_f32(x));
38}41}
3942
40pub fn sinf(x: f32) callconv(.c) f32 {43fn 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}
46pub fn sin_f32(x: f32) f32 {
41 // Small multiples of pi/2 rounded to double precision.47 // Small multiples of pi/2 rounded to double precision.
42 const s1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D1848 const s1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18
43 const s2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D1849 const s2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18
...@@ -98,7 +104,10 @@ pub fn sinf(x: f32) callconv(.c) f32 {...@@ -98,7 +104,10 @@ pub fn sinf(x: f32) callconv(.c) f32 {
98 };104 };
99}105}
100106
101pub fn sin(x: f64) callconv(.c) f64 {107fn 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}
110pub fn sin_f64(x: f64) f64 {
102 var ix = @as(u64, @bitCast(x)) >> 32;111 var ix = @as(u64, @bitCast(x)) >> 32;
103 ix &= 0x7fffffff;112 ix &= 0x7fffffff;
104113
...@@ -133,7 +142,10 @@ pub fn sin(x: f64) callconv(.c) f64 {...@@ -133,7 +142,10 @@ pub fn sin(x: f64) callconv(.c) f64 {
133 };142 };
134}143}
135144
136fn sinx(x: f80) callconv(.c) f80 {145fn __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}
148pub fn sin_f80(x: f80) f80 {
137 const se = ld.signExponent(x) & 0x7fff;149 const se = ld.signExponent(x) & 0x7fff;
138 if (se == 0x7fff) {150 if (se == 0x7fff) {
139 return x - x;151 return x - x;
...@@ -160,7 +172,10 @@ fn sinx(x: f80) callconv(.c) f80 {...@@ -160,7 +172,10 @@ fn sinx(x: f80) callconv(.c) f80 {
160 };172 };
161}173}
162174
163pub fn sinq(x: f128) callconv(.c) f128 {175fn 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}
178pub fn sin_f128(x: f128) f128 {
164 const se = ld.signExponent(x) & 0x7fff;179 const se = ld.signExponent(x) & 0x7fff;
165 if (se == 0x7fff) {180 if (se == 0x7fff) {
166 return x - x;181 return x - x;
...@@ -189,20 +204,21 @@ pub fn sinq(x: f128) callconv(.c) f128 {...@@ -189,20 +204,21 @@ pub fn sinq(x: f128) callconv(.c) f128 {
189204
190pub fn sinl(x: c_longdouble) callconv(.c) c_longdouble {205pub fn sinl(x: c_longdouble) callconv(.c) c_longdouble {
191 switch (@typeInfo(c_longdouble).float.bits) {206 switch (@typeInfo(c_longdouble).float.bits) {
192 64 => return sin(x),207 64 => return sin_f64(x),
193 80 => return sinx(x),208 80 => return sin_f80(x),
194 128 => return sinq(x),209 128 => return sin_f128(x),
195 else => @compileError("unreachable"),210 else => comptime unreachable,
196 }211 }
197}212}
198213
199fn testSinSpecial(comptime T: type) !void {214fn testSinSpecial(comptime T: type) !void {
200 const f = switch (T) {215 const f = switch (T) {
201 f32 => sinf,216 f16 => sin_f16,
202 f64 => sin,217 f32 => sin_f32,
203 f80 => sinx,218 f64 => sin_f64,
204 f128 => sinq,219 f80 => sin_f80,
205 else => @compileError("unimplemented"),220 f128 => sin_f128,
221 else => comptime unreachable,
206 };222 };
207223
208 try expect(math.isPositiveZero(f(0.0)));224 try expect(math.isPositiveZero(f(0.0)));
...@@ -214,13 +230,13 @@ fn testSinSpecial(comptime T: type) !void {...@@ -214,13 +230,13 @@ fn testSinSpecial(comptime T: type) !void {
214230
215test "sin32.normal" {231test "sin32.normal" {
216 const epsilon = math.floatEps(f32);232 const epsilon = math.floatEps(f32);
217 try expectApproxEqAbs(@as(f32, 0.0), sinf(0.0), epsilon);233 try expectApproxEqAbs(@as(f32, 0.0), sin_f32(0.0), epsilon);
218 try expectApproxEqAbs(@as(f32, 0.19866933), sinf(0.2), epsilon);234 try expectApproxEqAbs(@as(f32, 0.19866933), sin_f32(0.2), epsilon);
219 try expectApproxEqAbs(@as(f32, 0.77851737), sinf(0.8923), epsilon);235 try expectApproxEqAbs(@as(f32, 0.77851737), sin_f32(0.8923), epsilon);
220 try expectApproxEqAbs(@as(f32, 0.997495), sinf(1.5), epsilon);236 try expectApproxEqAbs(@as(f32, 0.997495), sin_f32(1.5), epsilon);
221 try expectApproxEqAbs(@as(f32, -0.997495), sinf(-1.5), epsilon);237 try expectApproxEqAbs(@as(f32, -0.997495), sin_f32(-1.5), epsilon);
222 try expectApproxEqAbs(@as(f32, -0.24654257), sinf(37.45), epsilon);238 try expectApproxEqAbs(@as(f32, -0.24654257), sin_f32(37.45), epsilon);
223 try expectApproxEqAbs(@as(f32, 0.9161657), sinf(89.123), epsilon);239 try expectApproxEqAbs(@as(f32, 0.9161657), sin_f32(89.123), epsilon);
224}240}
225241
226test "sin32.special" {242test "sin32.special" {
...@@ -229,13 +245,13 @@ test "sin32.special" {...@@ -229,13 +245,13 @@ test "sin32.special" {
229245
230test "sin64.normal" {246test "sin64.normal" {
231 const epsilon = math.floatEps(f64);247 const epsilon = math.floatEps(f64);
232 try expectApproxEqAbs(@as(f64, 0.0), sin(0.0), epsilon);248 try expectApproxEqAbs(@as(f64, 0.0), sin_f64(0.0), epsilon);
233 try expectApproxEqAbs(@as(f64, 0.19866933079506122), sin(0.2), epsilon);249 try expectApproxEqAbs(@as(f64, 0.19866933079506122), sin_f64(0.2), epsilon);
234 try expectApproxEqAbs(@as(f64, 0.7785173385577349), sin(0.8923), epsilon);250 try expectApproxEqAbs(@as(f64, 0.7785173385577349), sin_f64(0.8923), epsilon);
235 try expectApproxEqAbs(@as(f64, 0.9974949866040544), sin(1.5), epsilon);251 try expectApproxEqAbs(@as(f64, 0.9974949866040544), sin_f64(1.5), epsilon);
236 try expectApproxEqAbs(@as(f64, -0.9974949866040544), sin(-1.5), epsilon);252 try expectApproxEqAbs(@as(f64, -0.9974949866040544), sin_f64(-1.5), epsilon);
237 try expectApproxEqAbs(@as(f64, -0.24654331551411082), sin(37.45), epsilon);253 try expectApproxEqAbs(@as(f64, -0.24654331551411082), sin_f64(37.45), epsilon);
238 try expectApproxEqAbs(@as(f64, 0.9161652766622714), sin(89.123), epsilon);254 try expectApproxEqAbs(@as(f64, 0.9161652766622714), sin_f64(89.123), epsilon);
239}255}
240256
241test "sin64.special" {257test "sin64.special" {
...@@ -244,13 +260,13 @@ test "sin64.special" {...@@ -244,13 +260,13 @@ test "sin64.special" {
244260
245test "sin80.normal" {261test "sin80.normal" {
246 const epsilon = math.floatEps(f80);262 const epsilon = math.floatEps(f80);
247 try expectApproxEqAbs(@as(f80, 0.0), sinx(0.0), epsilon);263 try expectApproxEqAbs(@as(f80, 0.0), sin_f80(0.0), epsilon);
248 try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), sinx(0.2), epsilon);264 try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), sin_f80(0.2), epsilon);
249 try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), sinx(0.8923), epsilon);265 try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), sin_f80(0.8923), epsilon);
250 try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), sinx(1.5), epsilon);266 try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), sin_f80(1.5), epsilon);
251 try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), sinx(-1.5), epsilon);267 try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), sin_f80(-1.5), epsilon);
252 try expectApproxEqAbs(@as(f80, -0.24654331551411356504), sinx(37.45), epsilon);268 try expectApproxEqAbs(@as(f80, -0.24654331551411356504), sin_f80(37.45), epsilon);
253 try expectApproxEqAbs(@as(f80, 0.91616527666226951006), sinx(89.123), epsilon);269 try expectApproxEqAbs(@as(f80, 0.91616527666226951006), sin_f80(89.123), epsilon);
254}270}
255271
256test "sin80.special" {272test "sin80.special" {
...@@ -259,13 +275,13 @@ test "sin80.special" {...@@ -259,13 +275,13 @@ test "sin80.special" {
259275
260test "sin128.normal" {276test "sin128.normal" {
261 const epsilon = math.floatEps(f128);277 const epsilon = math.floatEps(f128);
262 try expectApproxEqAbs(@as(f128, 0.0), sinq(0.0), epsilon);278 try expectApproxEqAbs(@as(f128, 0.0), sin_f128(0.0), epsilon);
263 try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), sinq(0.2), epsilon);279 try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), sin_f128(0.2), epsilon);
264 try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), sinq(0.8923), epsilon);280 try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), sin_f128(0.8923), epsilon);
265 try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), sinq(1.5), epsilon);281 try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), sin_f128(1.5), epsilon);
266 try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), sinq(-1.5), epsilon);282 try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), sin_f128(-1.5), epsilon);
267 try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), sinq(37.45), epsilon);283 try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), sin_f128(37.45), epsilon);
268 try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), sinq(89.123), epsilon);284 try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), sin_f128(89.123), epsilon);
269}285}
270286
271test "sin128.special" {287test "sin128.special" {
...@@ -274,10 +290,10 @@ test "sin128.special" {...@@ -274,10 +290,10 @@ test "sin128.special" {
274290
275test "sin32 #9901" {291test "sin32 #9901" {
276 const float: f32 = @bitCast(@as(u32, 0b11100011111111110000000000000000));292 const float: f32 = @bitCast(@as(u32, 0b11100011111111110000000000000000));
277 _ = sinf(float);293 _ = sin_f32(float);
278}294}
279295
280test "sin64 #9901" {296test "sin64 #9901" {
281 const float: f64 = @bitCast(@as(u64, 0b1111111101000001000000001111110111111111100000000000000000000001));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,16 +25,23 @@ comptime {
25 symbol(&sincosl, "sincosl");25 symbol(&sincosl, "sincosl");
26}26}
2727
28pub fn sincosh(x: f16, r_sin: *f16, r_cos: *f16) callconv(.c) void {28fn 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}
33pub fn sincos_f16(x: f16) struct { f16, f16 } {
29 // TODO: more efficient implementation34 // TODO: more efficient implementation
30 var big_sin: f32 = undefined;35 const s, const c = sincos_f32(x);
31 var big_cos: f32 = undefined;36 return .{ @floatCast(s), @floatCast(c) };
32 sincosf(x, &big_sin, &big_cos);
33 r_sin.* = @as(f16, @floatCast(big_sin));
34 r_cos.* = @as(f16, @floatCast(big_cos));
35}37}
3638
37pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {39fn 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}
44pub fn sincos_f32(x: f32) struct { f32, f32 } {
38 const sc1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D1845 const sc1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18
39 const sc2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D1846 const sc2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18
40 const sc3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D247 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,13 +63,9 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {
56 mem.doNotOptimizeAway(x + 0x1p120);63 mem.doNotOptimizeAway(x + 0x1p120);
57 }64 }
58 }65 }
59 r_sin.* = x;66 return .{ x, 1.0 };
60 r_cos.* = 1.0;
61 return;
62 }67 }
63 r_sin.* = trig.sindf(x);68 return .{ trig.sindf(x), trig.cosdf(x) };
64 r_cos.* = trig.cosdf(x);
65 return;
66 }69 }
6770
68 // |x| ~<= 5*pi/471 // |x| ~<= 5*pi/4
...@@ -70,18 +73,16 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {...@@ -70,18 +73,16 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {
70 // |x| ~<= 3pi/473 // |x| ~<= 3pi/4
71 if (ix <= 0x4016cbe3) {74 if (ix <= 0x4016cbe3) {
72 if (sign) {75 if (sign) {
73 r_sin.* = -trig.cosdf(x + sc1pio2);76 return .{ -trig.cosdf(x + sc1pio2), trig.sindf(x + sc1pio2) };
74 r_cos.* = trig.sindf(x + sc1pio2);
75 } else {77 } else {
76 r_sin.* = trig.cosdf(sc1pio2 - x);78 return .{ trig.cosdf(sc1pio2 - x), trig.sindf(sc1pio2 - x) };
77 r_cos.* = trig.sindf(sc1pio2 - x);
78 }79 }
79 return;
80 }80 }
81 // -sin(x+c) is not correct if x+c could be 0: -0 vs +081 // -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);82 return .{
83 r_cos.* = -trig.cosdf(if (sign) x + sc2pio2 else x - sc2pio2);83 -trig.sindf(if (sign) x + sc2pio2 else x - sc2pio2),
84 return;84 -trig.cosdf(if (sign) x + sc2pio2 else x - sc2pio2),
85 };
85 }86 }
8687
87 // |x| ~<= 9*pi/488 // |x| ~<= 9*pi/4
...@@ -89,25 +90,21 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {...@@ -89,25 +90,21 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {
89 // |x| ~<= 7*pi/490 // |x| ~<= 7*pi/4
90 if (ix <= 0x40afeddf) {91 if (ix <= 0x40afeddf) {
91 if (sign) {92 if (sign) {
92 r_sin.* = trig.cosdf(x + sc3pio2);93 return .{ trig.cosdf(x + sc3pio2), -trig.sindf(x + sc3pio2) };
93 r_cos.* = -trig.sindf(x + sc3pio2);
94 } else {94 } else {
95 r_sin.* = -trig.cosdf(x - sc3pio2);95 return .{ -trig.cosdf(x - sc3pio2), trig.sindf(x - sc3pio2) };
96 r_cos.* = trig.sindf(x - sc3pio2);
97 }96 }
98 return;
99 }97 }
100 r_sin.* = trig.sindf(if (sign) x + sc4pio2 else x - sc4pio2);98 return .{
101 r_cos.* = trig.cosdf(if (sign) x + sc4pio2 else x - sc4pio2);99 trig.sindf(if (sign) x + sc4pio2 else x - sc4pio2),
102 return;100 trig.cosdf(if (sign) x + sc4pio2 else x - sc4pio2),
101 };
103 }102 }
104103
105 // sin(Inf or NaN) is NaN104 // sin(Inf or NaN) is NaN
106 if (ix >= 0x7f800000) {105 if (ix >= 0x7f800000) {
107 const result = x - x;106 const result = x - x;
108 r_sin.* = result;107 return .{ result, result };
109 r_cos.* = result;
110 return;
111 }108 }
112109
113 // general argument reduction needed110 // general argument reduction needed
...@@ -115,27 +112,20 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {...@@ -115,27 +112,20 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {
115 const n = rem_pio2f(x, &y);112 const n = rem_pio2f(x, &y);
116 const s = trig.sindf(y);113 const s = trig.sindf(y);
117 const c = trig.cosdf(y);114 const c = trig.cosdf(y);
118 switch (n & 3) {115 return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) {
119 0 => {116 0 => .{ s, c },
120 r_sin.* = s;117 1 => .{ c, -s },
121 r_cos.* = c;118 2 => .{ -s, -c },
122 },119 3 => .{ -c, s },
123 1 => {120 };
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 }
136}121}
137122
138pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void {123fn 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}
128pub fn sincos_f64(x: f64) struct { f64, f64 } {
139 const ix = @as(u32, @truncate(@as(u64, @bitCast(x)) >> 32)) & 0x7fffffff;129 const ix = @as(u32, @truncate(@as(u64, @bitCast(x)) >> 32)) & 0x7fffffff;
140130
141 // |x| ~< pi/4131 // |x| ~< pi/4
...@@ -150,21 +140,15 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void {...@@ -150,21 +140,15 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void {
150 mem.doNotOptimizeAway(x + 0x1p120);140 mem.doNotOptimizeAway(x + 0x1p120);
151 }141 }
152 }142 }
153 r_sin.* = x;143 return .{ x, 1.0 };
154 r_cos.* = 1.0;
155 return;
156 }144 }
157 r_sin.* = trig.sin(x, 0.0, 0);145 return .{ trig.sin(x, 0.0, 0), trig.cos(x, 0.0) };
158 r_cos.* = trig.cos(x, 0.0);
159 return;
160 }146 }
161147
162 // sincos(Inf or NaN) is NaN148 // sincos(Inf or NaN) is NaN
163 if (ix >= 0x7ff00000) {149 if (ix >= 0x7ff00000) {
164 const result = x - x;150 const result = x - x;
165 r_sin.* = result;151 return .{ result, result };
166 r_cos.* = result;
167 return;
168 }152 }
169153
170 // argument reduction needed154 // argument reduction needed
...@@ -172,33 +156,24 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void {...@@ -172,33 +156,24 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void {
172 const n = rem_pio2(x, &y);156 const n = rem_pio2(x, &y);
173 const s = trig.sin(y[0], y[1], 1);157 const s = trig.sin(y[0], y[1], 1);
174 const c = trig.cos(y[0], y[1]);158 const c = trig.cos(y[0], y[1]);
175 switch (n & 3) {159 return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) {
176 0 => {160 0 => .{ s, c },
177 r_sin.* = s;161 1 => .{ c, -s },
178 r_cos.* = c;162 2 => .{ -s, -c },
179 },163 3 => .{ -c, s },
180 1 => {164 };
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 }
193}165}
194166
195pub fn sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void {167fn 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}
172pub fn sincos_f80(x: f80) struct { f80, f80 } {
196 const se = ld.signExponent(x) & 0x7fff;173 const se = ld.signExponent(x) & 0x7fff;
197 if (se == 0x7fff) {174 if (se == 0x7fff) {
198 const result = x - x;175 const result = x - x;
199 r_sin.* = result;176 return .{ result, result };
200 r_cos.* = result;
201 return;
202 }177 }
203178
204 if (@abs(x) < trig.pi_4) {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,47 +182,34 @@ pub fn sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void {
207 if (compiler_rt.want_float_exceptions and se == 0) {182 if (compiler_rt.want_float_exceptions and se == 0) {
208 mem.doNotOptimizeAway(x * 0x1p-120);183 mem.doNotOptimizeAway(x * 0x1p-120);
209 }184 }
210 r_sin.* = x;
211 // raise inexact if x!=0185 // raise inexact if x!=0
212 r_cos.* = 1.0 + x;186 return .{ x, 1.0 + x };
213 return;
214 }187 }
215 r_sin.* = trig.sinx(x, 0.0, 0);188 return .{ trig.sinx(x, 0.0, 0), trig.cosx(x, 0.0) };
216 r_cos.* = trig.cosx(x, 0.0);
217 return;
218 }189 }
219190
220 var y: [2]f80 = undefined;191 var y: [2]f80 = undefined;
221 const n = rem_pio2l(f80, x, &y);192 const n = rem_pio2l(f80, x, &y);
222 const s = trig.sinx(y[0], y[1], 1);193 const s = trig.sinx(y[0], y[1], 1);
223 const c = trig.cosx(y[0], y[1]);194 const c = trig.cosx(y[0], y[1]);
224 switch (n & 3) {195 return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) {
225 0 => {196 0 => .{ s, c },
226 r_sin.* = s;197 1 => .{ c, -s },
227 r_cos.* = c;198 2 => .{ -s, -c },
228 },199 3 => .{ -c, s },
229 1 => {200 };
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 }
242}201}
243202
244pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void {203fn 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}
208pub fn sincos_f128(x: f128) struct { f128, f128 } {
245 const se = ld.signExponent(x) & 0x7fff;209 const se = ld.signExponent(x) & 0x7fff;
246 if (se == 0x7fff) {210 if (se == 0x7fff) {
247 const result = x - x;211 const result = x - x;
248 r_sin.* = result;212 return .{ result, result };
249 r_cos.* = result;
250 return;
251 }213 }
252214
253 if (@abs(x) < trig.pi_4) {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,78 +218,63 @@ pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void {
256 if (compiler_rt.want_float_exceptions and se == 0) {218 if (compiler_rt.want_float_exceptions and se == 0) {
257 mem.doNotOptimizeAway(x * 0x1p-120);219 mem.doNotOptimizeAway(x * 0x1p-120);
258 }220 }
259 r_sin.* = x;
260 // raise inexact if x!=0221 // raise inexact if x!=0
261 r_cos.* = 1.0 + x;222 return .{ x, 1.0 + x };
262 return;
263 }223 }
264 r_sin.* = trig.sinq(x, 0.0, 0);224 return .{ trig.sinq(x, 0.0, 0), trig.cosq(x, 0.0) };
265 r_cos.* = trig.cosq(x, 0.0);
266 return;
267 }225 }
268226
269 var y: [2]f128 = undefined;227 var y: [2]f128 = undefined;
270 const n = rem_pio2l(f128, x, &y);228 const n = rem_pio2l(f128, x, &y);
271 const s = trig.sinq(y[0], y[1], 1);229 const s = trig.sinq(y[0], y[1], 1);
272 const c = trig.cosq(y[0], y[1]);230 const c = trig.cosq(y[0], y[1]);
273 switch (n & 3) {231 return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) {
274 0 => {232 0 => .{ s, c },
275 r_sin.* = s;233 1 => .{ c, -s },
276 r_cos.* = c;234 2 => .{ -s, -c },
277 },235 3 => .{ -c, s },
278 1 => {236 };
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 }
291}237}
292238
293pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.c) void {239pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.c) void {
294 switch (@typeInfo(c_longdouble).float.bits) {240 r_sin.*, r_cos.* = switch (@typeInfo(c_longdouble).float.bits) {
295 64 => return sincos(x, r_sin, r_cos),241 64 => sincos_f64(x),
296 80 => return sincosx(x, r_sin, r_cos),242 80 => sincos_f80(x),
297 128 => return sincosq(x, r_sin, r_cos),243 128 => sincos_f128(x),
298 else => @compileError("unreachable"),244 else => comptime unreachable,
299 }245 };
300}246}
301247
302fn testSincosSpecial(comptime T: type) !void {248fn testSincosSpecial(comptime T: type) !void {
303 const f = switch (T) {249 const f = switch (T) {
304 f32 => sincosf,250 f16 => sincos_f16,
305 f64 => sincos,251 f32 => sincos_f32,
306 f80 => sincosx,252 f64 => sincos_f64,
307 f128 => sincosq,253 f80 => sincos_f80,
254 f128 => sincos_f128,
308 else => @compileError("unimplemented"),255 else => @compileError("unimplemented"),
309 };256 };
310257
311 var s: T = undefined;258 var s: T = undefined;
312 var c: T = undefined;259 var c: T = undefined;
313260
314 f(0.0, &s, &c);261 s, c = f(0.0);
315 try expect(math.isPositiveZero(s));262 try expect(math.isPositiveZero(s));
316 try expect(c == 1.0);263 try expect(c == 1.0);
317264
318 f(-0.0, &s, &c);265 s, c = f(-0.0);
319 try expect(math.isNegativeZero(s));266 try expect(math.isNegativeZero(s));
320 try expect(c == 1.0);267 try expect(c == 1.0);
321268
322 f(math.inf(T), &s, &c);269 s, c = f(math.inf(T));
323 try expect(math.isNan(s));270 try expect(math.isNan(s));
324 try expect(math.isNan(c));271 try expect(math.isNan(c));
325272
326 f(-math.inf(T), &s, &c);273 s, c = f(-math.inf(T));
327 try expect(math.isNan(s));274 try expect(math.isNan(s));
328 try expect(math.isNan(c));275 try expect(math.isNan(c));
329276
330 f(math.nan(T), &s, &c);277 s, c = f(math.nan(T));
331 try expect(math.isNan(s));278 try expect(math.isNan(s));
332 try expect(math.isNan(c));279 try expect(math.isNan(c));
333}280}
...@@ -337,31 +284,31 @@ test "sincos32.normal" {...@@ -337,31 +284,31 @@ test "sincos32.normal" {
337 var s: f32 = undefined;284 var s: f32 = undefined;
338 var c: f32 = undefined;285 var c: f32 = undefined;
339286
340 sincosf(0.0, &s, &c);287 s, c = sincos_f32(0.0);
341 try expectApproxEqAbs(@as(f32, 0.0), s, epsilon);288 try expectApproxEqAbs(@as(f32, 0.0), s, epsilon);
342 try expectApproxEqAbs(@as(f32, 1.0), c, epsilon);289 try expectApproxEqAbs(@as(f32, 1.0), c, epsilon);
343290
344 sincosf(0.2, &s, &c);291 s, c = sincos_f32(0.2);
345 try expectApproxEqAbs(@as(f32, 0.19866933), s, epsilon);292 try expectApproxEqAbs(@as(f32, 0.19866933), s, epsilon);
346 try expectApproxEqAbs(@as(f32, 0.9800666), c, epsilon);293 try expectApproxEqAbs(@as(f32, 0.9800666), c, epsilon);
347294
348 sincosf(0.8923, &s, &c);295 s, c = sincos_f32(0.8923);
349 try expectApproxEqAbs(@as(f32, 0.77851737), s, epsilon);296 try expectApproxEqAbs(@as(f32, 0.77851737), s, epsilon);
350 try expectApproxEqAbs(@as(f32, 0.6276231), c, epsilon);297 try expectApproxEqAbs(@as(f32, 0.6276231), c, epsilon);
351298
352 sincosf(1.5, &s, &c);299 s, c = sincos_f32(1.5);
353 try expectApproxEqAbs(@as(f32, 0.997495), s, epsilon);300 try expectApproxEqAbs(@as(f32, 0.997495), s, epsilon);
354 try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon);301 try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon);
355302
356 sincosf(-1.5, &s, &c);303 s, c = sincos_f32(-1.5);
357 try expectApproxEqAbs(@as(f32, -0.997495), s, epsilon);304 try expectApproxEqAbs(@as(f32, -0.997495), s, epsilon);
358 try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon);305 try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon);
359306
360 sincosf(37.45, &s, &c);307 s, c = sincos_f32(37.45);
361 try expectApproxEqAbs(@as(f32, -0.24654257), s, epsilon);308 try expectApproxEqAbs(@as(f32, -0.24654257), s, epsilon);
362 try expectApproxEqAbs(@as(f32, 0.96913195), c, epsilon);309 try expectApproxEqAbs(@as(f32, 0.96913195), c, epsilon);
363310
364 sincosf(89.123, &s, &c);311 s, c = sincos_f32(89.123);
365 try expectApproxEqAbs(@as(f32, 0.9161657), s, epsilon);312 try expectApproxEqAbs(@as(f32, 0.9161657), s, epsilon);
366 try expectApproxEqAbs(@as(f32, 0.40079966), c, epsilon);313 try expectApproxEqAbs(@as(f32, 0.40079966), c, epsilon);
367}314}
...@@ -375,31 +322,31 @@ test "sincos64.normal" {...@@ -375,31 +322,31 @@ test "sincos64.normal" {
375 var s: f64 = undefined;322 var s: f64 = undefined;
376 var c: f64 = undefined;323 var c: f64 = undefined;
377324
378 sincos(0.0, &s, &c);325 s, c = sincos_f64(0.0);
379 try expectApproxEqAbs(@as(f64, 0.0), s, epsilon);326 try expectApproxEqAbs(@as(f64, 0.0), s, epsilon);
380 try expectApproxEqAbs(@as(f64, 1.0), c, epsilon);327 try expectApproxEqAbs(@as(f64, 1.0), c, epsilon);
381328
382 sincos(0.2, &s, &c);329 s, c = sincos_f64(0.2);
383 try expectApproxEqAbs(@as(f64, 0.19866933079506122), s, epsilon);330 try expectApproxEqAbs(@as(f64, 0.19866933079506122), s, epsilon);
384 try expectApproxEqAbs(@as(f64, 0.9800665778412416), c, epsilon);331 try expectApproxEqAbs(@as(f64, 0.9800665778412416), c, epsilon);
385332
386 sincos(0.8923, &s, &c);333 s, c = sincos_f64(0.8923);
387 try expectApproxEqAbs(@as(f64, 0.7785173385577349), s, epsilon);334 try expectApproxEqAbs(@as(f64, 0.7785173385577349), s, epsilon);
388 try expectApproxEqAbs(@as(f64, 0.6276230983360804), c, epsilon);335 try expectApproxEqAbs(@as(f64, 0.6276230983360804), c, epsilon);
389336
390 sincos(1.5, &s, &c);337 s, c = sincos_f64(1.5);
391 try expectApproxEqAbs(@as(f64, 0.9974949866040544), s, epsilon);338 try expectApproxEqAbs(@as(f64, 0.9974949866040544), s, epsilon);
392 try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon);339 try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon);
393340
394 sincos(-1.5, &s, &c);341 s, c = sincos_f64(-1.5);
395 try expectApproxEqAbs(@as(f64, -0.9974949866040544), s, epsilon);342 try expectApproxEqAbs(@as(f64, -0.9974949866040544), s, epsilon);
396 try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon);343 try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon);
397344
398 sincos(37.45, &s, &c);345 s, c = sincos_f64(37.45);
399 try expectApproxEqAbs(@as(f64, -0.24654331551411082), s, epsilon);346 try expectApproxEqAbs(@as(f64, -0.24654331551411082), s, epsilon);
400 try expectApproxEqAbs(@as(f64, 0.9691317730707778), c, epsilon);347 try expectApproxEqAbs(@as(f64, 0.9691317730707778), c, epsilon);
401348
402 sincos(89.123, &s, &c);349 s, c = sincos_f64(89.123);
403 try expectApproxEqAbs(@as(f64, 0.9161652766622714), s, epsilon);350 try expectApproxEqAbs(@as(f64, 0.9161652766622714), s, epsilon);
404 try expectApproxEqAbs(@as(f64, 0.4008006809354791), c, epsilon);351 try expectApproxEqAbs(@as(f64, 0.4008006809354791), c, epsilon);
405}352}
...@@ -413,31 +360,31 @@ test "sincos80.normal" {...@@ -413,31 +360,31 @@ test "sincos80.normal" {
413 var s: f80 = undefined;360 var s: f80 = undefined;
414 var c: f80 = undefined;361 var c: f80 = undefined;
415362
416 sincosx(0.0, &s, &c);363 s, c = sincos_f80(0.0);
417 try expectApproxEqAbs(@as(f80, 0.0), s, epsilon);364 try expectApproxEqAbs(@as(f80, 0.0), s, epsilon);
418 try expectApproxEqAbs(@as(f80, 1.0), c, epsilon);365 try expectApproxEqAbs(@as(f80, 1.0), c, epsilon);
419366
420 sincosx(0.2, &s, &c);367 s, c = sincos_f80(0.2);
421 try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), s, epsilon);368 try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), s, epsilon);
422 try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), c, epsilon);369 try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), c, epsilon);
423370
424 sincosx(0.8923, &s, &c);371 s, c = sincos_f80(0.8923);
425 try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), s, epsilon);372 try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), s, epsilon);
426 try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), c, epsilon);373 try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), c, epsilon);
427374
428 sincosx(1.5, &s, &c);375 s, c = sincos_f80(1.5);
429 try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), s, epsilon);376 try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), s, epsilon);
430 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon);377 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon);
431378
432 sincosx(-1.5, &s, &c);379 s, c = sincos_f80(-1.5);
433 try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), s, epsilon);380 try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), s, epsilon);
434 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon);381 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon);
435382
436 sincosx(37.45, &s, &c);383 s, c = sincos_f80(37.45);
437 try expectApproxEqAbs(@as(f80, -0.24654331551411356504), s, epsilon);384 try expectApproxEqAbs(@as(f80, -0.24654331551411356504), s, epsilon);
438 try expectApproxEqAbs(@as(f80, 0.9691317730707771246), c, epsilon);385 try expectApproxEqAbs(@as(f80, 0.9691317730707771246), c, epsilon);
439386
440 sincosx(89.123, &s, &c);387 s, c = sincos_f80(89.123);
441 try expectApproxEqAbs(@as(f80, 0.91616527666226951006), s, epsilon);388 try expectApproxEqAbs(@as(f80, 0.91616527666226951006), s, epsilon);
442 try expectApproxEqAbs(@as(f80, 0.4008006809354834001), c, epsilon);389 try expectApproxEqAbs(@as(f80, 0.4008006809354834001), c, epsilon);
443}390}
...@@ -451,31 +398,31 @@ test "sincos128.normal" {...@@ -451,31 +398,31 @@ test "sincos128.normal" {
451 var s: f128 = undefined;398 var s: f128 = undefined;
452 var c: f128 = undefined;399 var c: f128 = undefined;
453400
454 sincosq(0.0, &s, &c);401 s, c = sincos_f128(0.0);
455 try expectApproxEqAbs(@as(f128, 0.0), s, epsilon);402 try expectApproxEqAbs(@as(f128, 0.0), s, epsilon);
456 try expectApproxEqAbs(@as(f128, 1.0), c, epsilon);403 try expectApproxEqAbs(@as(f128, 1.0), c, epsilon);
457404
458 sincosq(0.2, &s, &c);405 s, c = sincos_f128(0.2);
459 try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), s, epsilon);406 try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), s, epsilon);
460 try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), c, epsilon);407 try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), c, epsilon);
461408
462 sincosq(0.8923, &s, &c);409 s, c = sincos_f128(0.8923);
463 try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), s, epsilon);410 try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), s, epsilon);
464 try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), c, epsilon);411 try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), c, epsilon);
465412
466 sincosq(1.5, &s, &c);413 s, c = sincos_f128(1.5);
467 try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), s, epsilon);414 try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), s, epsilon);
468 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon);415 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon);
469416
470 sincosq(-1.5, &s, &c);417 s, c = sincos_f128(-1.5);
471 try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), s, epsilon);418 try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), s, epsilon);
472 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon);419 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon);
473420
474 sincosq(37.45, &s, &c);421 s, c = sincos_f128(37.45);
475 try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), s, epsilon);422 try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), s, epsilon);
476 try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), c, epsilon);423 try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), c, epsilon);
477424
478 sincosq(89.123, &s, &c);425 s, c = sincos_f128(89.123);
479 try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), s, epsilon);426 try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), s, epsilon);
480 try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), c, epsilon);427 try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), c, epsilon);
481}428}
lib/compiler_rt/sqrt.zig+148-133
...@@ -28,7 +28,10 @@ comptime {...@@ -28,7 +28,10 @@ comptime {
28 symbol(&sqrtl, "sqrtl");28 symbol(&sqrtl, "sqrtl");
29}29}
3030
31pub fn __sqrth(x: f16) callconv(.c) f16 {31fn __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}
34pub fn sqrt_f16(x: f16) f16 {
32 var ix: u16 = @bitCast(x);35 var ix: u16 = @bitCast(x);
33 var top = ix >> 10;36 var top = ix >> 10;
3437
...@@ -93,7 +96,10 @@ pub fn __sqrth(x: f16) callconv(.c) f16 {...@@ -93,7 +96,10 @@ pub fn __sqrth(x: f16) callconv(.c) f16 {
93 return y;96 return y;
94}97}
9598
96pub fn sqrtf(x: f32) callconv(.c) f32 {99fn 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}
102pub fn sqrt_f32(x: f32) f32 {
97 var ix: u32 = @bitCast(x);103 var ix: u32 = @bitCast(x);
98104
99 if (ix < @as(u32, @bitCast(@as(f32, 0x1p-126))) or @as(u32, @bitCast(std.math.inf(f32))) <= ix) {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,7 +153,10 @@ pub fn sqrtf(x: f32) callconv(.c) f32 {
147 return y + t;153 return y + t;
148}154}
149155
150pub fn sqrt(x: f64) callconv(.c) f64 {156fn 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}
159pub fn sqrt_f64(x: f64) f64 {
151 var ix: u64 = @bitCast(x);160 var ix: u64 = @bitCast(x);
152 var top = ix >> 52;161 var top = ix >> 52;
153162
...@@ -284,7 +293,10 @@ pub fn sqrt(x: f64) callconv(.c) f64 {...@@ -284,7 +293,10 @@ pub fn sqrt(x: f64) callconv(.c) f64 {
284 return y;293 return y;
285}294}
286295
287pub fn __sqrtx(x: f80) callconv(.c) f80 {296fn __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}
299pub fn sqrt_f80(x: f80) f80 {
288 var ix: u80 = @bitCast(x);300 var ix: u80 = @bitCast(x);
289 var top = ix >> 64;301 var top = ix >> 64;
290302
...@@ -381,7 +393,10 @@ pub fn __sqrtx(x: f80) callconv(.c) f80 {...@@ -381,7 +393,10 @@ pub fn __sqrtx(x: f80) callconv(.c) f80 {
381 return y;393 return y;
382}394}
383395
384pub fn sqrtq(x: f128) callconv(.c) f128 {396fn 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}
399pub fn sqrt_f128(x: f128) f128 {
385 var ix: u128 = @bitCast(x);400 var ix: u128 = @bitCast(x);
386 var top = ix >> 112;401 var top = ix >> 112;
387402
...@@ -483,10 +498,10 @@ fn _Qp_sqrt(c: *f128, a: *f128) callconv(.c) void {...@@ -483,10 +498,10 @@ fn _Qp_sqrt(c: *f128, a: *f128) callconv(.c) void {
483498
484pub fn sqrtl(x: c_longdouble) callconv(.c) c_longdouble {499pub fn sqrtl(x: c_longdouble) callconv(.c) c_longdouble {
485 switch (@typeInfo(c_longdouble).float.bits) {500 switch (@typeInfo(c_longdouble).float.bits) {
486 64 => return sqrt(x),501 64 => return sqrt_f64(x),
487 80 => return __sqrtx(x),502 80 => return sqrt_f80(x),
488 128 => return sqrtq(x),503 128 => return sqrt_f128(x),
489 else => @compileError("unreachable"),504 else => comptime unreachable,
490 }505 }
491}506}
492507
...@@ -545,187 +560,187 @@ inline fn mul80_tail(a: u80, b: u80) u80 {...@@ -545,187 +560,187 @@ inline fn mul80_tail(a: u80, b: u80) u80 {
545 return alo * blo +% ((ahi * blo) << 40) +% ((alo * bhi) << 40);560 return alo * blo +% ((ahi * blo) << 40) +% ((alo * bhi) << 40);
546}561}
547562
548test "__sqrth" {563test "sqrt_f16" {
549 // sqrt(±0) is ±0564 // sqrt(±0) is ±0
550 try std.testing.expectEqual(__sqrth(0x0.0p0), 0x0.0p0);565 try std.testing.expectEqual(sqrt_f16(0x0.0p0), 0x0.0p0);
551 try std.testing.expectEqual(__sqrth(-0x0.0p0), -0x0.0p0);566 try std.testing.expectEqual(sqrt_f16(-0x0.0p0), -0x0.0p0);
552 // sqrt(+max) is finite567 // 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 // sqrt(4)=2569 // sqrt(4)=2
555 try std.testing.expectEqual(__sqrth(0x1p2), 0x1p1);570 try std.testing.expectEqual(sqrt_f16(0x1p2), 0x1p1);
556 // sqrt(x) for x=1, 1±ulp571 // sqrt(x) for x=1, 1±ulp
557 try std.testing.expectEqual(__sqrth(0x1p0), 0x1p0);572 try std.testing.expectEqual(sqrt_f16(0x1p0), 0x1p0);
558 try std.testing.expectEqual(__sqrth(0x1.004p0), 0x1p0);573 try std.testing.expectEqual(sqrt_f16(0x1.004p0), 0x1p0);
559 try std.testing.expectEqual(__sqrth(0x1.FF8p-1), 0x1.FFCp-1);574 try std.testing.expectEqual(sqrt_f16(0x1.FF8p-1), 0x1.FFCp-1);
560 // sqrt(+min) is non-zero575 // 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 // sqrt(min subnormal) is non-zero577 // 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 // sqrt(inf) is inf579 // 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 // sqrt(nan) is nan581 // 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 // sqrt(-ve) is nan583 // sqrt(-ve) is nan
569 try std.testing.expect(math.isNan(__sqrth(-0x1p-14)));584 try std.testing.expect(math.isNan(sqrt_f16(-0x1p-14)));
570 try std.testing.expect(math.isNan(__sqrth(-0x1p+0)));585 try std.testing.expect(math.isNan(sqrt_f16(-0x1p+0)));
571 try std.testing.expect(math.isNan(__sqrth(-math.inf(f16))));586 try std.testing.expect(math.isNan(sqrt_f16(-math.inf(f16))));
572 // random arguments587 // random arguments
573 try std.testing.expectEqual(__sqrth(0x1.1p14), 0x1.08p7);588 try std.testing.expectEqual(sqrt_f16(0x1.1p14), 0x1.08p7);
574 try std.testing.expectEqual(__sqrth(0x1.C9p-12), 0x1.56p-6);589 try std.testing.expectEqual(sqrt_f16(0x1.C9p-12), 0x1.56p-6);
575 try std.testing.expectEqual(__sqrth(0x1.CE8p-7), 0x1.E68p-4);590 try std.testing.expectEqual(sqrt_f16(0x1.CE8p-7), 0x1.E68p-4);
576 try std.testing.expectEqual(__sqrth(0x1.134p-7), 0x1.778p-4);591 try std.testing.expectEqual(sqrt_f16(0x1.134p-7), 0x1.778p-4);
577 try std.testing.expectEqual(__sqrth(0x1.E9Cp-10), 0x1.62p-5);592 try std.testing.expectEqual(sqrt_f16(0x1.E9Cp-10), 0x1.62p-5);
578 try std.testing.expectEqual(__sqrth(0x1.3Dp9), 0x1.92Cp4);593 try std.testing.expectEqual(sqrt_f16(0x1.3Dp9), 0x1.92Cp4);
579 try std.testing.expectEqual(__sqrth(0x1.AA4p8), 0x1.4A4p4);594 try std.testing.expectEqual(sqrt_f16(0x1.AA4p8), 0x1.4A4p4);
580 try std.testing.expectEqual(__sqrth(0x1.8A8p4), 0x1.3DCp2);595 try std.testing.expectEqual(sqrt_f16(0x1.8A8p4), 0x1.3DCp2);
581 try std.testing.expectEqual(__sqrth(0x1.8Fp-7), 0x1.C4p-4);596 try std.testing.expectEqual(sqrt_f16(0x1.8Fp-7), 0x1.C4p-4);
582 try std.testing.expectEqual(__sqrth(0x1.584p-11), 0x1.A3Cp-6);597 try std.testing.expectEqual(sqrt_f16(0x1.584p-11), 0x1.A3Cp-6);
583}598}
584599
585test "sqrtf" {600test "sqrt_f32" {
586 // sqrt(±0) is ±0601 // sqrt(±0) is ±0
587 try std.testing.expectEqual(sqrtf(0x0.0p0), 0x0.0p0);602 try std.testing.expectEqual(sqrt_f32(0x0.0p0), 0x0.0p0);
588 try std.testing.expectEqual(sqrtf(-0x0.0p0), -0x0.0p0);603 try std.testing.expectEqual(sqrt_f32(-0x0.0p0), -0x0.0p0);
589 // sqrt(+max) is finite604 // 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 // sqrt(4)=2606 // sqrt(4)=2
592 try std.testing.expectEqual(sqrtf(0x1p2), 0x1p1);607 try std.testing.expectEqual(sqrt_f32(0x1p2), 0x1p1);
593 // sqrt(x) for x=1, 1±ulp608 // sqrt(x) for x=1, 1±ulp
594 try std.testing.expectEqual(sqrtf(0x1p0), 0x1p0);609 try std.testing.expectEqual(sqrt_f32(0x1p0), 0x1p0);
595 try std.testing.expectEqual(sqrtf(0x1.000002p0), 0x1p0);610 try std.testing.expectEqual(sqrt_f32(0x1.000002p0), 0x1p0);
596 try std.testing.expectEqual(sqrtf(0x1.FFFFFEp-1), 0x1.FFFFFEp-1);611 try std.testing.expectEqual(sqrt_f32(0x1.FFFFFEp-1), 0x1.FFFFFEp-1);
597 // sqrt(+min) is non-zero612 // 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 // sqrt(min subnormal) is non-zero614 // 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 // sqrt(inf) is inf616 // 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 // sqrt(nan) is nan618 // 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 // sqrt(-ve) is nan620 // sqrt(-ve) is nan
606 try std.testing.expect(math.isNan(sqrtf(-0x1p-149)));621 try std.testing.expect(math.isNan(sqrt_f32(-0x1p-149)));
607 try std.testing.expect(math.isNan(sqrtf(-0x1p0)));622 try std.testing.expect(math.isNan(sqrt_f32(-0x1p0)));
608 try std.testing.expect(math.isNan(sqrtf(-math.inf(f32))));623 try std.testing.expect(math.isNan(sqrt_f32(-math.inf(f32))));
609 // random arguments624 // random arguments
610 try std.testing.expectEqual(sqrtf(0x1.4DD57Ep77), 0x1.9D6DA8p38);625 try std.testing.expectEqual(sqrt_f32(0x1.4DD57Ep77), 0x1.9D6DA8p38);
611 try std.testing.expectEqual(sqrtf(0x1.871848p102), 0x1.3C6AFAp51);626 try std.testing.expectEqual(sqrt_f32(0x1.871848p102), 0x1.3C6AFAp51);
612 try std.testing.expectEqual(sqrtf(0x1.A1D748p-112), 0x1.470EFCp-56);627 try std.testing.expectEqual(sqrt_f32(0x1.A1D748p-112), 0x1.470EFCp-56);
613 try std.testing.expectEqual(sqrtf(0x1.E626C2p18), 0x1.60C80Ep9);628 try std.testing.expectEqual(sqrt_f32(0x1.E626C2p18), 0x1.60C80Ep9);
614 try std.testing.expectEqual(sqrtf(0x1.E80E66p-29), 0x1.F3E282p-15);629 try std.testing.expectEqual(sqrt_f32(0x1.E80E66p-29), 0x1.F3E282p-15);
615 try std.testing.expectEqual(sqrtf(0x1.B47204p89), 0x1.D8B732p44);630 try std.testing.expectEqual(sqrt_f32(0x1.B47204p89), 0x1.D8B732p44);
616 try std.testing.expectEqual(sqrtf(0x1.77F45p15), 0x1.B6BC3Ap7);631 try std.testing.expectEqual(sqrt_f32(0x1.77F45p15), 0x1.B6BC3Ap7);
617 try std.testing.expectEqual(sqrtf(0x1.AD5F5p-48), 0x1.4B8A72p-24);632 try std.testing.expectEqual(sqrt_f32(0x1.AD5F5p-48), 0x1.4B8A72p-24);
618 try std.testing.expectEqual(sqrtf(0x1.91A39p-76), 0x1.40A7A8p-38);633 try std.testing.expectEqual(sqrt_f32(0x1.91A39p-76), 0x1.40A7A8p-38);
619 try std.testing.expectEqual(sqrtf(0x1.DAE088p79), 0x1.ED16DCp39);634 try std.testing.expectEqual(sqrt_f32(0x1.DAE088p79), 0x1.ED16DCp39);
620}635}
621636
622test "sqrt" {637test "sqrt_f64" {
623 // sqrt(±0) is ±0638 // sqrt(±0) is ±0
624 try std.testing.expectEqual(sqrt(0x0.0p0), 0x0.0p0);639 try std.testing.expectEqual(sqrt_f64(0x0.0p0), 0x0.0p0);
625 try std.testing.expectEqual(sqrt(-0x0.0p0), -0x0.0p0);640 try std.testing.expectEqual(sqrt_f64(-0x0.0p0), -0x0.0p0);
626 // sqrt(+max) is finite641 // 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 // sqrt(4)=2643 // sqrt(4)=2
629 try std.testing.expectEqual(sqrt(0x1p2), 0x1p1);644 try std.testing.expectEqual(sqrt_f64(0x1p2), 0x1p1);
630 // sqrt(x) for x=1, 1±ulp645 // sqrt(x) for x=1, 1±ulp
631 try std.testing.expectEqual(sqrt(0x1p0), 0x1p0);646 try std.testing.expectEqual(sqrt_f64(0x1p0), 0x1p0);
632 try std.testing.expectEqual(sqrt(0x1p0 + math.floatEps(f64)), 0x1p0);647 try std.testing.expectEqual(sqrt_f64(0x1p0 + math.floatEps(f64)), 0x1p0);
633 try std.testing.expectEqual(sqrt(0x1p0 - math.floatEps(f64)), 0x1.FFFFFFFFFFFFFp-1);648 try std.testing.expectEqual(sqrt_f64(0x1p0 - math.floatEps(f64)), 0x1.FFFFFFFFFFFFFp-1);
634 // sqrt(+min) is non-zero649 // 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 // sqrt(min subnormal) is non-zero651 // 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 // sqrt(inf) is inf653 // 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 // sqrt(nan) is nan655 // 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 // sqrt(-ve) is nan657 // sqrt(-ve) is nan
643 try std.testing.expect(math.isNan(sqrt(-0x1p-1074)));658 try std.testing.expect(math.isNan(sqrt_f64(-0x1p-1074)));
644 try std.testing.expect(math.isNan(sqrt(-0x1p0)));659 try std.testing.expect(math.isNan(sqrt_f64(-0x1p0)));
645 try std.testing.expect(math.isNan(sqrt(-math.inf(f64))));660 try std.testing.expect(math.isNan(sqrt_f64(-math.inf(f64))));
646 // random arguments661 // random arguments
647 try std.testing.expectEqual(sqrt(0x1.27D3510D4789Bp471), 0x1.852E97E58CFB7p235);662 try std.testing.expectEqual(sqrt_f64(0x1.27D3510D4789Bp471), 0x1.852E97E58CFB7p235);
648 try std.testing.expectEqual(sqrt(0x1.8C4FCD5A07846p791), 0x1.C27504E56D938p395);663 try std.testing.expectEqual(sqrt_f64(0x1.8C4FCD5A07846p791), 0x1.C27504E56D938p395);
649 try std.testing.expectEqual(sqrt(0x1.B1B69324F96E7p-137), 0x1.D73BD0414D8BFp-69);664 try std.testing.expectEqual(sqrt_f64(0x1.B1B69324F96E7p-137), 0x1.D73BD0414D8BFp-69);
650 try std.testing.expectEqual(sqrt(0x1.1CBD179A811FEp278), 0x1.0DFCB9A114A61p139);665 try std.testing.expectEqual(sqrt_f64(0x1.1CBD179A811FEp278), 0x1.0DFCB9A114A61p139);
651 try std.testing.expectEqual(sqrt(0x1.1D0C7EFB04A56p917), 0x1.7E0708A25DDCDp458);666 try std.testing.expectEqual(sqrt_f64(0x1.1D0C7EFB04A56p917), 0x1.7E0708A25DDCDp458);
652 try std.testing.expectEqual(sqrt(0x1.21B355DA8C94Bp-249), 0x1.8121CBE2608E3p-125);667 try std.testing.expectEqual(sqrt_f64(0x1.21B355DA8C94Bp-249), 0x1.8121CBE2608E3p-125);
653 try std.testing.expectEqual(sqrt(0x1.63024D4C5E987p487), 0x1.AA56AEA589DCDp243);668 try std.testing.expectEqual(sqrt_f64(0x1.63024D4C5E987p487), 0x1.AA56AEA589DCDp243);
654 try std.testing.expectEqual(sqrt(0x1.45AC3BE941F6Ep339), 0x1.9857F3F453E2Dp169);669 try std.testing.expectEqual(sqrt_f64(0x1.45AC3BE941F6Ep339), 0x1.9857F3F453E2Dp169);
655 try std.testing.expectEqual(sqrt(0x1.3B719C733AA24p267), 0x1.91E12E3AC8F71p133);670 try std.testing.expectEqual(sqrt_f64(0x1.3B719C733AA24p267), 0x1.91E12E3AC8F71p133);
656 try std.testing.expectEqual(sqrt(0x1.0B150433A2275p357), 0x1.71CAB87F8277Cp178);671 try std.testing.expectEqual(sqrt_f64(0x1.0B150433A2275p357), 0x1.71CAB87F8277Cp178);
657}672}
658673
659test "__sqrtx" {674test "__sqrtx" {
660 // sqrt(±0) is ±0675 // sqrt(±0) is ±0
661 try std.testing.expectEqual(__sqrtx(0x0.0p0), 0x0.0p0);676 try std.testing.expectEqual(sqrt_f80(0x0.0p0), 0x0.0p0);
662 try std.testing.expectEqual(__sqrtx(-0x0.0p0), -0x0.0p0);677 try std.testing.expectEqual(sqrt_f80(-0x0.0p0), -0x0.0p0);
663 // sqrt(+max) is finite678 // 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 // sqrt(4)=2680 // sqrt(4)=2
666 try std.testing.expectEqual(__sqrtx(0x1p2), 0x1p1);681 try std.testing.expectEqual(sqrt_f80(0x1p2), 0x1p1);
667 // sqrt(x) for x=1, 1±ulp682 // sqrt(x) for x=1, 1±ulp
668 try std.testing.expectEqual(__sqrtx(0x1p0), 0x1p0);683 try std.testing.expectEqual(sqrt_f80(0x1p0), 0x1p0);
669 try std.testing.expectEqual(__sqrtx(0x1p0 + math.floatEps(f80)), 0x1p0);684 try std.testing.expectEqual(sqrt_f80(0x1p0 + math.floatEps(f80)), 0x1p0);
670 try std.testing.expectEqual(__sqrtx(0x1p0 - math.floatEps(f80)), 0x1.FFFFFFFFFFFFFFFEp-1);685 try std.testing.expectEqual(sqrt_f80(0x1p0 - math.floatEps(f80)), 0x1.FFFFFFFFFFFFFFFEp-1);
671 // sqrt(+min) is non-zero686 // 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 // sqrt(min subnormal) is non-zero688 // 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 // sqrt(inf) is inf690 // 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 // sqrt(nan) is nan692 // 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 // sqrt(-ve) is nan694 // sqrt(-ve) is nan
680 try std.testing.expect(math.isNan(__sqrtx(-0x1p-16442)));695 try std.testing.expect(math.isNan(sqrt_f80(-0x1p-16442)));
681 try std.testing.expect(math.isNan(__sqrtx(-0x1p0)));696 try std.testing.expect(math.isNan(sqrt_f80(-0x1p0)));
682 try std.testing.expect(math.isNan(__sqrtx(-math.inf(f80))));697 try std.testing.expect(math.isNan(sqrt_f80(-math.inf(f80))));
683 // random arguments698 // random arguments
684 try std.testing.expectEqual(__sqrtx(0x1.087F3953486918A4p15482), 0x1.0436BBE03D02F32p7741);699 try std.testing.expectEqual(sqrt_f80(0x1.087F3953486918A4p15482), 0x1.0436BBE03D02F32p7741);
685 try std.testing.expectEqual(__sqrtx(0x1.530CF9E2AE84D8Fp-6330), 0x1.269CFEF51933BE58p-3165);700 try std.testing.expectEqual(sqrt_f80(0x1.530CF9E2AE84D8Fp-6330), 0x1.269CFEF51933BE58p-3165);
686 try std.testing.expectEqual(__sqrtx(0x1.3F971515EADD574Ap5713), 0x1.9483232AB780B006p2856);701 try std.testing.expectEqual(sqrt_f80(0x1.3F971515EADD574Ap5713), 0x1.9483232AB780B006p2856);
687 try std.testing.expectEqual(__sqrtx(0x1.4CC0DC7379222954p864), 0x1.23DD4D0A4758C2Cp432);702 try std.testing.expectEqual(sqrt_f80(0x1.4CC0DC7379222954p864), 0x1.23DD4D0A4758C2Cp432);
688 try std.testing.expectEqual(__sqrtx(0x1.920E5649559A839Ep-3181), 0x1.C5B5BC0F98DD83D2p-1591);703 try std.testing.expectEqual(sqrt_f80(0x1.920E5649559A839Ep-3181), 0x1.C5B5BC0F98DD83D2p-1591);
689 try std.testing.expectEqual(__sqrtx(0x1.2E59726F87CD1746p-629), 0x1.8973327E95CB350Cp-315);704 try std.testing.expectEqual(sqrt_f80(0x1.2E59726F87CD1746p-629), 0x1.8973327E95CB350Cp-315);
690 try std.testing.expectEqual(__sqrtx(0x1.D3A16391F57B4D64p-9034), 0x1.59FF08B7DEEF5DB2p-4517);705 try std.testing.expectEqual(sqrt_f80(0x1.D3A16391F57B4D64p-9034), 0x1.59FF08B7DEEF5DB2p-4517);
691 try std.testing.expectEqual(__sqrtx(0x1.E7053D8DAA49BCEEp-11411), 0x1.F35AA3EA5E18E344p-5706);706 try std.testing.expectEqual(sqrt_f80(0x1.E7053D8DAA49BCEEp-11411), 0x1.F35AA3EA5E18E344p-5706);
692 try std.testing.expectEqual(__sqrtx(0x1.797ED0B05DD4A984p7521), 0x1.B7A22E40C6A7867Ap3760);707 try std.testing.expectEqual(sqrt_f80(0x1.797ED0B05DD4A984p7521), 0x1.B7A22E40C6A7867Ap3760);
693 try std.testing.expectEqual(__sqrtx(0x1.FC50806445C7226Ap15371), 0x1.FE2766142653F5BEp7685);708 try std.testing.expectEqual(sqrt_f80(0x1.FC50806445C7226Ap15371), 0x1.FE2766142653F5BEp7685);
694}709}
695710
696test "sqrtq" {711test "sqrt_f128" {
697 // sqrt(±0) is ±0712 // sqrt(±0) is ±0
698 try std.testing.expectEqual(sqrtq(0x0.0p0), 0x0.0p0);713 try std.testing.expectEqual(sqrt_f128(0x0.0p0), 0x0.0p0);
699 try std.testing.expectEqual(sqrtq(-0x0.0p0), -0x0.0p0);714 try std.testing.expectEqual(sqrt_f128(-0x0.0p0), -0x0.0p0);
700 // sqrt(+max) is finite715 // 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 // sqrt(4)=2717 // sqrt(4)=2
703 try std.testing.expectEqual(sqrtq(0x1p2), 0x1p1);718 try std.testing.expectEqual(sqrt_f128(0x1p2), 0x1p1);
704 // sqrt(x) for x=1, 1±ulp719 // sqrt(x) for x=1, 1±ulp
705 try std.testing.expectEqual(sqrtq(0x1p0), 0x1p0);720 try std.testing.expectEqual(sqrt_f128(0x1p0), 0x1p0);
706 try std.testing.expectEqual(sqrtq(0x1p0 + math.floatEps(f128)), 0x1p0);721 try std.testing.expectEqual(sqrt_f128(0x1p0 + math.floatEps(f128)), 0x1p0);
707 try std.testing.expectEqual(sqrtq(0x1p0 - math.floatEps(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp-1);722 try std.testing.expectEqual(sqrt_f128(0x1p0 - math.floatEps(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp-1);
708 // sqrt(+min) is non-zero723 // 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 // sqrt(min subnormal) is non-zero725 // 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 // sqrt(inf) is inf727 // 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 // sqrt(nan) is nan729 // 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 // sqrt(-ve) is nan731 // sqrt(-ve) is nan
717 try std.testing.expect(math.isNan(sqrtq(-0x1p-16442)));732 try std.testing.expect(math.isNan(sqrt_f128(-0x1p-16442)));
718 try std.testing.expect(math.isNan(sqrtq(-0x1p0)));733 try std.testing.expect(math.isNan(sqrt_f128(-0x1p0)));
719 try std.testing.expect(math.isNan(sqrtq(-math.inf(f128))));734 try std.testing.expect(math.isNan(sqrt_f128(-math.inf(f128))));
720 // random arguments735 // random arguments
721 try std.testing.expectEqual(sqrtq(0x1.B6942D29A331751600C9F3AF7E5Fp3363), 0x1.D9DE9AFEF0F2D25586A50CA39D4Dp1681);736 try std.testing.expectEqual(sqrt_f128(0x1.B6942D29A331751600C9F3AF7E5Fp3363), 0x1.D9DE9AFEF0F2D25586A50CA39D4Dp1681);
722 try std.testing.expectEqual(sqrtq(0x1.5E65C405F84D471A8070ADD7A42Dp11765), 0x1.A78F7F9452B4D9EC2403C81D9D42p5882);737 try std.testing.expectEqual(sqrt_f128(0x1.5E65C405F84D471A8070ADD7A42Dp11765), 0x1.A78F7F9452B4D9EC2403C81D9D42p5882);
723 try std.testing.expectEqual(sqrtq(0x1.B42334D68F8016D8AE6F5E22B044p-5624), 0x1.4E247A7F2FF2A325E9377BB09C8p-2812);738 try std.testing.expectEqual(sqrt_f128(0x1.B42334D68F8016D8AE6F5E22B044p-5624), 0x1.4E247A7F2FF2A325E9377BB09C8p-2812);
724 try std.testing.expectEqual(sqrtq(0x1.E61715047F80F2E0B9382B38E06Bp10062), 0x1.60C25D9DFDC0116B78EF5AFDE0E9p5031);739 try std.testing.expectEqual(sqrt_f128(0x1.E61715047F80F2E0B9382B38E06Bp10062), 0x1.60C25D9DFDC0116B78EF5AFDE0E9p5031);
725 try std.testing.expectEqual(sqrtq(0x1.2ED0B53B494CB55A7B04E653D40Ep-1026), 0x1.166CE78D658D2453D700B04C5748p-513);740 try std.testing.expectEqual(sqrt_f128(0x1.2ED0B53B494CB55A7B04E653D40Ep-1026), 0x1.166CE78D658D2453D700B04C5748p-513);
726 try std.testing.expectEqual(sqrtq(0x1.1BA756B9790E78A4E6F0B083AA89p1835), 0x1.7D1767EA3303DB7A46940033988p917);741 try std.testing.expectEqual(sqrt_f128(0x1.1BA756B9790E78A4E6F0B083AA89p1835), 0x1.7D1767EA3303DB7A46940033988p917);
727 try std.testing.expectEqual(sqrtq(0x1.5B6C574319C1120335C8E1609704p4512), 0x1.2A3A8A415BB1648C548FBA2A4182p2256);742 try std.testing.expectEqual(sqrt_f128(0x1.5B6C574319C1120335C8E1609704p4512), 0x1.2A3A8A415BB1648C548FBA2A4182p2256);
728 try std.testing.expectEqual(sqrtq(0x1.FF91E8CDEE1552A2B74E77B602Ep14953), 0x1.FFC8F171267D4FE75CBE7AB4D851p7476);743 try std.testing.expectEqual(sqrt_f128(0x1.FF91E8CDEE1552A2B74E77B602Ep14953), 0x1.FFC8F171267D4FE75CBE7AB4D851p7476);
729 try std.testing.expectEqual(sqrtq(0x1.9B1837CFC629A1B6B1BB97099E7Dp2892), 0x1.4468511B909EAF8641BD59105A6Bp1446);744 try std.testing.expectEqual(sqrt_f128(0x1.9B1837CFC629A1B6B1BB97099E7Dp2892), 0x1.4468511B909EAF8641BD59105A6Bp1446);
730 try std.testing.expectEqual(sqrtq(0x1.0E2115475E64A92340914E7F7B37p-13951), 0x1.73E536F82F414134012F55BA5368p-6976);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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const addf3 = @import("./addf3.zig").addf3;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_dsub, "__aeabi_dsub");
8 } else {
9 symbol(&__subdf3, "__subdf3");
10 }
11}
12
13fn __subdf3(a: f64, b: f64) callconv(.c) f64 {
14 return sub(a, b);
15}
16
17fn __aeabi_dsub(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
18 return sub(a, b);
19}
20
21inline 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const addf3 = @import("./addf3.zig").addf3;
4
5comptime {
6 symbol(&__subhf3, "__subhf3");
7}
8
9fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const addf3 = @import("./addf3.zig").addf3;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_fsub, "__aeabi_fsub");
8 } else {
9 symbol(&__subsf3, "__subsf3");
10 }
11}
12
13fn __subsf3(a: f32, b: f32) callconv(.c) f32 {
14 return sub(a, b);
15}
16
17fn __aeabi_fsub(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
18 return sub(a, b);
19}
20
21inline 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const addf3 = @import("./addf3.zig").addf3;
4
5comptime {
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
16pub fn __subtf3(a: f128, b: f128) callconv(.c) f128 {
17 return sub(a, b);
18}
19
20fn _Qp_sub(c: *f128, a: *const f128, b: *const f128) callconv(.c) void {
21 c.* = sub(a.*, b.*);
22}
23
24inline 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,5 +1,6 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const testing = @import("std").testing;1const testing = @import("std").testing;
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
34
4comptime {5comptime {
5 symbol(&__subvdi3, "__subvdi3");6 symbol(&__subvdi3, "__subvdi3");
...@@ -9,7 +10,7 @@ pub fn __subvdi3(a: i64, b: i64) callconv(.c) i64 {...@@ -9,7 +10,7 @@ pub fn __subvdi3(a: i64, b: i64) callconv(.c) i64 {
9 const sum = a -% b;10 const sum = a -% b;
10 // Overflow occurred iff the operands have opposite signs, and the sign of the11 // Overflow occurred iff the operands have opposite signs, and the sign of the
11 // sum is the opposite of the lhs sign.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 return sum;14 return sum;
14}15}
1516
lib/compiler_rt/subvsi3.zig+1-1
...@@ -10,7 +10,7 @@ pub fn __subvsi3(a: i32, b: i32) callconv(.c) i32 {...@@ -10,7 +10,7 @@ pub fn __subvsi3(a: i32, b: i32) callconv(.c) i32 {
10 const sum = a -% b;10 const sum = a -% b;
11 // Overflow occurred iff the operands have opposite signs, and the sign of the11 // Overflow occurred iff the operands have opposite signs, and the sign of the
12 // sum is the opposite of the lhs sign.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 return sum;14 return sum;
15}15}
1616
lib/compiler_rt/subxf3.zig deleted-13
...@@ -1,13 +0,0 @@
1const std = @import("std");
2const symbol = @import("../compiler_rt.zig").symbol;
3
4comptime {
5 symbol(&__subxf3, "__subxf3");
6}
7
8fn __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,13 +21,13 @@ const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l;
2121
22const arch = builtin.cpu.arch;22const arch = builtin.cpu.arch;
23const compiler_rt = @import("../compiler_rt.zig");23const compiler_rt = @import("../compiler_rt.zig");
24const symbol = @import("../compiler_rt.zig").symbol;24const symbol = compiler_rt.symbol;
2525
26comptime {26comptime {
27 symbol(&tanh, "__tanh");27 symbol(&__tanh, "__tanh");
28 symbol(&tanf, "tanf");28 symbol(&tanf, "tanf");
29 symbol(&tan, "tan");29 symbol(&tan, "tan");
30 symbol(&tanx, "__tanx");30 symbol(&__tanx, "__tanx");
31 if (compiler_rt.want_ppc_abi) {31 if (compiler_rt.want_ppc_abi) {
32 symbol(&tanq, "tanf128");32 symbol(&tanq, "tanf128");
33 }33 }
...@@ -35,12 +35,18 @@ comptime {...@@ -35,12 +35,18 @@ comptime {
35 symbol(&tanl, "tanl");35 symbol(&tanl, "tanl");
36}36}
3737
38pub fn tanh(x: f16) callconv(.c) f16 {38fn __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}
41pub fn tan_f16(x: f16) f16 {
39 // TODO: more efficient implementation42 // TODO: more efficient implementation
40 return @floatCast(tanf(x));43 return @floatCast(tan_f32(x));
41}44}
4245
43pub fn tanf(x: f32) callconv(.c) f32 {46fn 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}
49pub fn tan_f32(x: f32) f32 {
44 // Small multiples of pi/2 rounded to double precision.50 // Small multiples of pi/2 rounded to double precision.
45 const t1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D1851 const t1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18
46 const t2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D1852 const t2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18
...@@ -90,7 +96,10 @@ pub fn tanf(x: f32) callconv(.c) f32 {...@@ -90,7 +96,10 @@ pub fn tanf(x: f32) callconv(.c) f32 {
90 return kernel.tandf(y, n & 1 != 0);96 return kernel.tandf(y, n & 1 != 0);
91}97}
9298
93pub fn tan(x: f64) callconv(.c) f64 {99fn 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}
102pub fn tan_f64(x: f64) f64 {
94 var ix = @as(u64, @bitCast(x)) >> 32;103 var ix = @as(u64, @bitCast(x)) >> 32;
95 ix &= 0x7fffffff;104 ix &= 0x7fffffff;
96105
...@@ -120,7 +129,10 @@ pub fn tan(x: f64) callconv(.c) f64 {...@@ -120,7 +129,10 @@ pub fn tan(x: f64) callconv(.c) f64 {
120 return kernel.tan(y[0], y[1], n & 1 != 0);129 return kernel.tan(y[0], y[1], n & 1 != 0);
121}130}
122131
123pub fn tanx(x: f80) callconv(.c) f80 {132fn __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}
135pub fn tan_f80(x: f80) f80 {
124 const se = ld.signExponent(x) & 0x7fff;136 const se = ld.signExponent(x) & 0x7fff;
125 if (se == 0x7fff) {137 if (se == 0x7fff) {
126 return x - x;138 return x - x;
...@@ -141,7 +153,10 @@ pub fn tanx(x: f80) callconv(.c) f80 {...@@ -141,7 +153,10 @@ pub fn tanx(x: f80) callconv(.c) f80 {
141 return kernel.tanx(y[0], y[1], n & 1);153 return kernel.tanx(y[0], y[1], n & 1);
142}154}
143155
144pub fn tanq(x: f128) callconv(.c) f128 {156fn 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}
159pub fn tan_f128(x: f128) f128 {
145 const se = ld.signExponent(x) & 0x7fff;160 const se = ld.signExponent(x) & 0x7fff;
146 if (se == 0x7fff) {161 if (se == 0x7fff) {
147 return x - x;162 return x - x;
...@@ -164,18 +179,21 @@ pub fn tanq(x: f128) callconv(.c) f128 {...@@ -164,18 +179,21 @@ pub fn tanq(x: f128) callconv(.c) f128 {
164179
165pub fn tanl(x: c_longdouble) callconv(.c) c_longdouble {180pub fn tanl(x: c_longdouble) callconv(.c) c_longdouble {
166 switch (@typeInfo(c_longdouble).float.bits) {181 switch (@typeInfo(c_longdouble).float.bits) {
167 64 => return tan(x),182 64 => return tan_f64(x),
168 80 => return tanx(x),183 80 => return tan_f80(x),
169 128 => return tanq(x),184 128 => return tan_f128(x),
170 else => @compileError("unreachable"),185 else => comptime unreachable,
171 }186 }
172}187}
173188
174fn testTanNormal(comptime T: type) !void {189fn testTanNormal(comptime T: type) !void {
175 const f = switch (T) {190 const f = switch (T) {
176 f32 => tanf,191 f16 => tan_f16,
177 f64 => tan,192 f32 => tan_f32,
178 else => @compileError("unimplemented"),193 f64 => tan_f64,
194 f80 => tan_f80,
195 f128 => tan_f128,
196 else => comptime unreachable,
179 };197 };
180 const epsilon = 0.00001;198 const epsilon = 0.00001;
181199
...@@ -189,11 +207,12 @@ fn testTanNormal(comptime T: type) !void {...@@ -189,11 +207,12 @@ fn testTanNormal(comptime T: type) !void {
189207
190fn testTanSpecial(comptime T: type) !void {208fn testTanSpecial(comptime T: type) !void {
191 const f = switch (T) {209 const f = switch (T) {
192 f32 => tanf,210 f16 => tan_f16,
193 f64 => tan,211 f32 => tan_f32,
194 f80 => tanx,212 f64 => tan_f64,
195 f128 => tanq,213 f80 => tan_f80,
196 else => @compileError("unimplemented"),214 f128 => tan_f128,
215 else => comptime unreachable,
197 };216 };
198217
199 try expect(math.isPositiveZero(f(0.0)));218 try expect(math.isPositiveZero(f(0.0)));
...@@ -214,23 +233,23 @@ test "tan64.normal" {...@@ -214,23 +233,23 @@ test "tan64.normal" {
214test "tan80.normal" {233test "tan80.normal" {
215 const epsilon = math.floatEps(f80);234 const epsilon = math.floatEps(f80);
216235
217 try expectApproxEqAbs(@as(f80, 0.0), tanx(0.0), epsilon);236 try expectApproxEqAbs(@as(f80, 0.0), tan_f80(0.0), epsilon);
218 try expectApproxEqAbs(@as(f80, 0.2027100355086724833213582716475345), tanx(0.2), epsilon);237 try expectApproxEqAbs(@as(f80, 0.2027100355086724833213582716475345), tan_f80(0.2), epsilon);
219 try expectApproxEqAbs(@as(f80, 1.2404217445497097995561220131857544), tanx(0.8923), epsilon);238 try expectApproxEqAbs(@as(f80, 1.2404217445497097995561220131857544), tan_f80(0.8923), epsilon);
220 try expectApproxEqAbs(@as(f80, 14.10141994717171938764), tanx(1.5), epsilon);239 try expectApproxEqAbs(@as(f80, 14.10141994717171938764), tan_f80(1.5), epsilon);
221 try expectApproxEqAbs(@as(f80, -0.25439607116885656232), tanx(37.45), epsilon);240 try expectApproxEqAbs(@as(f80, -0.25439607116885656232), tan_f80(37.45), epsilon);
222 try expectApproxEqAbs(@as(f80, 2.2858376251355320963), tanx(89.123), epsilon);241 try expectApproxEqAbs(@as(f80, 2.2858376251355320963), tan_f80(89.123), epsilon);
223}242}
224243
225test "tan128.normal" {244test "tan128.normal" {
226 const epsilon = math.floatEps(f128);245 const epsilon = math.floatEps(f128);
227246
228 try expectApproxEqAbs(@as(f128, 0.0), tanq(0.0), epsilon);247 try expectApproxEqAbs(@as(f128, 0.0), tan_f128(0.0), epsilon);
229 try expectApproxEqAbs(@as(f128, 0.2027100355086724833213582716475345), tanq(0.2), epsilon);248 try expectApproxEqAbs(@as(f128, 0.2027100355086724833213582716475345), tan_f128(0.2), epsilon);
230 try expectApproxEqAbs(@as(f128, 1.2404217445497097995561220131857544), tanq(0.8923), epsilon);249 try expectApproxEqAbs(@as(f128, 1.2404217445497097995561220131857544), tan_f128(0.8923), epsilon);
231 try expectApproxEqAbs(@as(f128, 14.101419947171719387646083651987755), tanq(1.5), epsilon);250 try expectApproxEqAbs(@as(f128, 14.101419947171719387646083651987755), tan_f128(1.5), epsilon);
232 try expectApproxEqAbs(@as(f128, -0.2543960711688565630469573224504774), tanq(37.45), epsilon);251 try expectApproxEqAbs(@as(f128, -0.2543960711688565630469573224504774), tan_f128(37.45), epsilon);
233 try expectApproxEqAbs(@as(f128, 2.2858376251355321074066028114094292), tanq(89.123), epsilon);252 try expectApproxEqAbs(@as(f128, 2.2858376251355321074066028114094292), tan_f128(89.123), epsilon);
234}253}
235254
236test "tan32.special" {255test "tan32.special" {
lib/compiler_rt/trunc.zig+76-43
...@@ -24,12 +24,18 @@ comptime {...@@ -24,12 +24,18 @@ comptime {
24 symbol(&truncl, "truncl");24 symbol(&truncl, "truncl");
25}25}
2626
27pub fn __trunch(x: f16) callconv(.c) f16 {27fn __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}
30pub fn trunc_f16(x: f16) f16 {
28 // TODO: more efficient implementation31 // TODO: more efficient implementation
29 return @floatCast(truncf(x));32 return @floatCast(trunc_f32(x));
30}33}
3134
32pub fn truncf(x: f32) callconv(.c) f32 {35fn 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}
38pub fn trunc_f32(x: f32) f32 {
33 const u: u32 = @bitCast(x);39 const u: u32 = @bitCast(x);
34 var e = @as(i32, @intCast(((u >> 23) & 0xFF))) - 0x7F + 9;40 var e = @as(i32, @intCast(((u >> 23) & 0xFF))) - 0x7F + 9;
35 var m: u32 = undefined;41 var m: u32 = undefined;
...@@ -50,7 +56,10 @@ pub fn truncf(x: f32) callconv(.c) f32 {...@@ -50,7 +56,10 @@ pub fn truncf(x: f32) callconv(.c) f32 {
50 }56 }
51}57}
5258
53pub fn trunc(x: f64) callconv(.c) f64 {59fn 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}
62pub fn trunc_f64(x: f64) f64 {
54 const u: u64 = @bitCast(x);63 const u: u64 = @bitCast(x);
55 var e = @as(i32, @intCast(((u >> 52) & 0x7FF))) - 0x3FF + 12;64 var e = @as(i32, @intCast(((u >> 52) & 0x7FF))) - 0x3FF + 12;
56 var m: u64 = undefined;65 var m: u64 = undefined;
...@@ -71,12 +80,18 @@ pub fn trunc(x: f64) callconv(.c) f64 {...@@ -71,12 +80,18 @@ pub fn trunc(x: f64) callconv(.c) f64 {
71 }80 }
72}81}
7382
74pub fn __truncx(x: f80) callconv(.c) f80 {83fn __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}
86pub fn trunc_f80(x: f80) f80 {
75 // TODO: more efficient implementation87 // TODO: more efficient implementation
76 return @floatCast(truncq(x));88 return @floatCast(trunc_f128(x));
77}89}
7890
79pub fn truncq(x: f128) callconv(.c) f128 {91fn 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}
94pub fn trunc_f128(x: f128) f128 {
80 const u: u128 = @bitCast(x);95 const u: u128 = @bitCast(x);
81 var e = @as(i32, @intCast(((u >> 112) & 0x7FFF))) - 0x3FFF + 16;96 var e = @as(i32, @intCast(((u >> 112) & 0x7FFF))) - 0x3FFF + 16;
82 var m: u128 = undefined;97 var m: u128 = undefined;
...@@ -99,51 +114,69 @@ pub fn truncq(x: f128) callconv(.c) f128 {...@@ -99,51 +114,69 @@ pub fn truncq(x: f128) callconv(.c) f128 {
99114
100pub fn truncl(x: c_longdouble) callconv(.c) c_longdouble {115pub fn truncl(x: c_longdouble) callconv(.c) c_longdouble {
101 switch (@typeInfo(c_longdouble).float.bits) {116 switch (@typeInfo(c_longdouble).float.bits) {
102 64 => return trunc(x),117 64 => return trunc_f64(x),
103 80 => return __truncx(x),118 80 => return trunc_f80(x),
104 128 => return truncq(x),119 128 => return trunc_f128(x),
105 else => @compileError("unreachable"),120 else => comptime unreachable,
106 }121 }
107}122}
108123
109test "trunc32" {124test trunc_f16 {
110 try expect(truncf(1.3) == 1.0);125 try expect(trunc_f16(1.3) == 1.0);
111 try expect(truncf(-1.3) == -1.0);126 try expect(trunc_f16(-1.3) == -1.0);
112 try expect(truncf(0.2) == 0.0);127 try expect(math.isPositiveZero(trunc_f16(0.2)));
113}128 try expect(math.isNegativeZero(trunc_f16(-0.2)));
114129 try expect(math.isPositiveZero(trunc_f16(0.0)));
115test "trunc64" {130 try expect(math.isNegativeZero(trunc_f16(-0.0)));
116 try expect(trunc(1.3) == 1.0);131 try expect(math.isPositiveInf(trunc_f16(math.inf(f32))));
117 try expect(trunc(-1.3) == -1.0);132 try expect(math.isNegativeInf(trunc_f16(-math.inf(f32))));
118 try expect(trunc(0.2) == 0.0);133 try expect(math.isNan(trunc_f16(math.nan(f32))));
119}134}
120135
121test "trunc128" {136test trunc_f32 {
122 try expect(truncq(1.3) == 1.0);137 try expect(trunc_f32(1.3) == 1.0);
123 try expect(truncq(-1.3) == -1.0);138 try expect(trunc_f32(-1.3) == -1.0);
124 try expect(truncq(0.2) == 0.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}
126147
127test "trunc32.special" {148test trunc_f64 {
128 try expect(truncf(0.0) == 0.0); // 0x3F800000149 try expect(trunc_f64(1.3) == 1.0);
129 try expect(truncf(-0.0) == -0.0);150 try expect(trunc_f64(-1.3) == -1.0);
130 try expect(math.isPositiveInf(truncf(math.inf(f32))));151 try expect(math.isPositiveZero(trunc_f64(0.2)));
131 try expect(math.isNegativeInf(truncf(-math.inf(f32))));152 try expect(math.isNegativeZero(trunc_f64(-0.2)));
132 try expect(math.isNan(truncf(math.nan(f32))));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}
134159
135test "trunc64.special" {160test trunc_f80 {
136 try expect(trunc(0.0) == 0.0);161 try expect(trunc_f80(1.3) == 1.0);
137 try expect(trunc(-0.0) == -0.0);162 try expect(trunc_f80(-1.3) == -1.0);
138 try expect(math.isPositiveInf(trunc(math.inf(f64))));163 try expect(math.isPositiveZero(trunc_f80(0.2)));
139 try expect(math.isNegativeInf(trunc(-math.inf(f64))));164 try expect(math.isNegativeZero(trunc_f80(-0.2)));
140 try expect(math.isNan(trunc(math.nan(f64))));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}
142171
143test "trunc128.special" {172test trunc_f128 {
144 try expect(truncq(0.0) == 0.0);173 try expect(trunc_f128(1.3) == 1.0);
145 try expect(truncq(-0.0) == -0.0);174 try expect(trunc_f128(-1.3) == -1.0);
146 try expect(math.isPositiveInf(truncq(math.inf(f128))));175 try expect(math.isPositiveZero(trunc_f128(0.2)));
147 try expect(math.isNegativeInf(truncq(-math.inf(f128))));176 try expect(math.isNegativeZero(trunc_f128(-0.2)));
148 try expect(math.isNan(truncq(math.nan(f128))));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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const truncf = @import("./truncf.zig").truncf;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_d2h, "__aeabi_d2h");
8 }
9 symbol(&__truncdfhf2, "__truncdfhf2");
10}
11
12pub fn __truncdfhf2(a: f64) callconv(.c) compiler_rt.F16T(f64) {
13 return @bitCast(truncf(f16, f64, a));
14}
15
16fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const truncf = @import("./truncf.zig").truncf;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_d2f, "__aeabi_d2f");
8 } else {
9 symbol(&__truncdfsf2, "__truncdfsf2");
10 }
11}
12
13pub fn __truncdfsf2(a: f64) callconv(.c) f32 {
14 return truncf(f32, f64, a);
15}
16
17fn __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,6 +1,204 @@
1const std = @import("std");1const std = @import("std");
22
3pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t {3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
5
6comptime {
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
61fn __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}
64fn __aeabi_f2h(a: u32) callconv(.{ .arm_aapcs = .{} }) u16 {
65 return @bitCast(f16_floatCast_f32(@bitCast(a)));
66}
67pub fn f16_floatCast_f32(a: f32) f16 {
68 return truncf(f16, f32, a);
69}
70
71fn __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}
74fn __aeabi_d2h(a: u64) callconv(.{ .arm_aapcs = .{} }) u16 {
75 return @bitCast(f16_floatCast_f64(@bitCast(a)));
76}
77pub fn f16_floatCast_f64(a: f64) f16 {
78 return truncf(f16, f64, a);
79}
80
81fn __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}
84pub fn f16_floatCast_f80(a: f80) f16 {
85 return trunc_f80(f16, a);
86}
87
88fn __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}
91pub fn f16_floatCast_f128(a: f128) f16 {
92 return truncf(f16, f128, a);
93}
94
95fn __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}
98fn __aeabi_d2f(a: f64) callconv(.{ .arm_aapcs = .{} }) f32 {
99 return f32_floatCast_f64(a);
100}
101pub fn f32_floatCast_f64(a: f64) f32 {
102 return truncf(f32, f64, a);
103}
104
105fn __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}
108pub fn f32_floatCast_f80(a: f80) f32 {
109 return trunc_f80(f32, a);
110}
111
112fn __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}
115fn _Qp_qtos(a: *const f128) callconv(.c) f32 {
116 return f32_floatCast_f128(a.*);
117}
118pub fn f32_floatCast_f128(a: f128) f32 {
119 return truncf(f32, f128, a);
120}
121
122fn __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}
125pub fn f64_floatCast_f80(a: f80) f64 {
126 return trunc_f80(f64, a);
127}
128
129fn __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}
132fn _Qp_qtod(a: *const f128) callconv(.c) f64 {
133 return f64_floatCast_f128(a.*);
134}
135pub fn f64_floatCast_f128(a: f128) f64 {
136 return truncf(f64, f128, a);
137}
138
139fn __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}
142pub 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
201inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t {
4 const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits);202 const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits);
5 const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits);203 const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits);
6 const srcSigBits = std.math.floatMantissaBits(src_t);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,7 +297,7 @@ pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t
99 return @bitCast(result);297 return @bitCast(result);
100}298}
101299
102pub inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t {300inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t {
103 const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits);301 const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits);
104 const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit302 const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit
105 const dst_sig_bits = std.math.floatMantissaBits(dst_t);303 const dst_sig_bits = std.math.floatMantissaBits(dst_t);
lib/compiler_rt/truncf_test.zig+160-174
...@@ -1,79 +1,82 @@...@@ -1,79 +1,82 @@
1const std = @import("std");1const std = @import("std");
2const testing = std.testing;2const testing = std.testing;
33
4const __truncsfhf2 = @import("truncsfhf2.zig").__truncsfhf2;4const impl = @import("truncf.zig");
5const __truncdfhf2 = @import("truncdfhf2.zig").__truncdfhf2;
6const __truncdfsf2 = @import("truncdfsf2.zig").__truncdfsf2;
7const __trunctfhf2 = @import("trunctfhf2.zig").__trunctfhf2;
8const __trunctfsf2 = @import("trunctfsf2.zig").__trunctfsf2;
9const __trunctfdf2 = @import("trunctfdf2.zig").__trunctfdf2;
10const __trunctfxf2 = @import("trunctfxf2.zig").__trunctfxf2;
11
12fn test__truncsfhf2(a: u32, expected: u16) !void {
13 const actual: u16 = @bitCast(__truncsfhf2(@bitCast(a)));
14
15 if (actual == expected) {
16 return;
17 }
185
19 return error.TestFailure;6const f16_floatCast_f32 = impl.f16_floatCast_f32;
7const f16_floatCast_f64 = impl.f16_floatCast_f64;
8const f16_floatCast_f80 = impl.f16_floatCast_f80;
9const f16_floatCast_f128 = impl.f16_floatCast_f128;
10
11const f32_floatCast_f64 = impl.f32_floatCast_f64;
12const f32_floatCast_f80 = impl.f32_floatCast_f80;
13const f32_floatCast_f128 = impl.f32_floatCast_f128;
14
15const f64_floatCast_f80 = impl.f64_floatCast_f80;
16const f64_floatCast_f128 = impl.f64_floatCast_f128;
17
18const f80_floatCast_f128 = impl.f80_floatCast_f128;
19
20fn 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}
2124
22test "truncsfhf2" {25test f16_floatCast_f32 {
23 try test__truncsfhf2(0x7fc00000, 0x7e00); // qNaN26 try test_f16_floatCast_f32(0x7fc00000, 0x7e00); // qNaN
24 try test__truncsfhf2(0x7fe00000, 0x7f00); // sNaN27 try test_f16_floatCast_f32(0x7fe00000, 0x7f00); // sNaN
2528
26 try test__truncsfhf2(0, 0); // 029 try test_f16_floatCast_f32(0, 0); // 0
27 try test__truncsfhf2(0x80000000, 0x8000); // -030 try test_f16_floatCast_f32(0x80000000, 0x8000); // -0
2831
29 try test__truncsfhf2(0x7f800000, 0x7c00); // inf32 try test_f16_floatCast_f32(0x7f800000, 0x7c00); // inf
30 try test__truncsfhf2(0xff800000, 0xfc00); // -inf33 try test_f16_floatCast_f32(0xff800000, 0xfc00); // -inf
3134
32 try test__truncsfhf2(0x477ff000, 0x7c00); // 65520 -> inf35 try test_f16_floatCast_f32(0x477ff000, 0x7c00); // 65520 -> inf
33 try test__truncsfhf2(0xc77ff000, 0xfc00); // -65520 -> -inf36 try test_f16_floatCast_f32(0xc77ff000, 0xfc00); // -65520 -> -inf
3437
35 try test__truncsfhf2(0x71cc3892, 0x7c00); // 0x1.987124876876324p+100 -> inf38 try test_f16_floatCast_f32(0x71cc3892, 0x7c00); // 0x1.987124876876324p+100 -> inf
36 try test__truncsfhf2(0xf1cc3892, 0xfc00); // -0x1.987124876876324p+100 -> -inf39 try test_f16_floatCast_f32(0xf1cc3892, 0xfc00); // -0x1.987124876876324p+100 -> -inf
3740
38 try test__truncsfhf2(0x38800000, 0x0400); // normal (min), 2**-1441 try test_f16_floatCast_f32(0x38800000, 0x0400); // normal (min), 2**-14
39 try test__truncsfhf2(0xb8800000, 0x8400); // normal (min), -2**-1442 try test_f16_floatCast_f32(0xb8800000, 0x8400); // normal (min), -2**-14
4043
41 try test__truncsfhf2(0x477fe000, 0x7bff); // normal (max), 6550444 try test_f16_floatCast_f32(0x477fe000, 0x7bff); // normal (max), 65504
42 try test__truncsfhf2(0xc77fe000, 0xfbff); // normal (max), -6550445 try test_f16_floatCast_f32(0xc77fe000, 0xfbff); // normal (max), -65504
4346
44 try test__truncsfhf2(0x477fe100, 0x7bff); // normal, 65505 -> 6550447 try test_f16_floatCast_f32(0x477fe100, 0x7bff); // normal, 65505 -> 65504
45 try test__truncsfhf2(0xc77fe100, 0xfbff); // normal, -65505 -> -6550448 try test_f16_floatCast_f32(0xc77fe100, 0xfbff); // normal, -65505 -> -65504
4649
47 try test__truncsfhf2(0x477fef00, 0x7bff); // normal, 65519 -> 6550450 try test_f16_floatCast_f32(0x477fef00, 0x7bff); // normal, 65519 -> 65504
48 try test__truncsfhf2(0xc77fef00, 0xfbff); // normal, -65519 -> -6550451 try test_f16_floatCast_f32(0xc77fef00, 0xfbff); // normal, -65519 -> -65504
4952
50 try test__truncsfhf2(0x3f802000, 0x3c01); // normal, 1 + 2**-1053 try test_f16_floatCast_f32(0x3f802000, 0x3c01); // normal, 1 + 2**-10
51 try test__truncsfhf2(0xbf802000, 0xbc01); // normal, -1 - 2**-1054 try test_f16_floatCast_f32(0xbf802000, 0xbc01); // normal, -1 - 2**-10
5255
53 try test__truncsfhf2(0x3eaaa000, 0x3555); // normal, approx. 1/356 try test_f16_floatCast_f32(0x3eaaa000, 0x3555); // normal, approx. 1/3
54 try test__truncsfhf2(0xbeaaa000, 0xb555); // normal, approx. -1/357 try test_f16_floatCast_f32(0xbeaaa000, 0xb555); // normal, approx. -1/3
5558
56 try test__truncsfhf2(0x40490fdb, 0x4248); // normal, 3.141592653559 try test_f16_floatCast_f32(0x40490fdb, 0x4248); // normal, 3.1415926535
57 try test__truncsfhf2(0xc0490fdb, 0xc248); // normal, -3.141592653560 try test_f16_floatCast_f32(0xc0490fdb, 0xc248); // normal, -3.1415926535
5861
59 try test__truncsfhf2(0x45cc3892, 0x6e62); // normal, 0x1.987124876876324p+1262 try test_f16_floatCast_f32(0x45cc3892, 0x6e62); // normal, 0x1.987124876876324p+12
6063
61 try test__truncsfhf2(0x3f800000, 0x3c00); // normal, 164 try test_f16_floatCast_f32(0x3f800000, 0x3c00); // normal, 1
62 try test__truncsfhf2(0x38800000, 0x0400); // normal, 0x1.0p-1465 try test_f16_floatCast_f32(0x38800000, 0x0400); // normal, 0x1.0p-14
6366
64 try test__truncsfhf2(0x33800000, 0x0001); // denormal (min), 2**-2467 try test_f16_floatCast_f32(0x33800000, 0x0001); // denormal (min), 2**-24
65 try test__truncsfhf2(0xb3800000, 0x8001); // denormal (min), -2**-2468 try test_f16_floatCast_f32(0xb3800000, 0x8001); // denormal (min), -2**-24
6669
67 try test__truncsfhf2(0x387fc000, 0x03ff); // denormal (max), 2**-14 - 2**-2470 try test_f16_floatCast_f32(0x387fc000, 0x03ff); // denormal (max), 2**-14 - 2**-24
68 try test__truncsfhf2(0xb87fc000, 0x83ff); // denormal (max), -2**-14 + 2**-2471 try test_f16_floatCast_f32(0xb87fc000, 0x83ff); // denormal (max), -2**-14 + 2**-24
6972
70 try test__truncsfhf2(0x35800000, 0x0010); // denormal, 0x1.0p-2073 try test_f16_floatCast_f32(0x35800000, 0x0010); // denormal, 0x1.0p-20
71 try test__truncsfhf2(0x33280000, 0x0001); // denormal, 0x1.5p-25 -> 0x1.0p-2474 try test_f16_floatCast_f32(0x33280000, 0x0001); // denormal, 0x1.5p-25 -> 0x1.0p-24
72 try test__truncsfhf2(0x33000000, 0x0000); // 0x1.0p-25 -> zero75 try test_f16_floatCast_f32(0x33000000, 0x0000); // 0x1.0p-25 -> zero
73}76}
7477
75fn test__truncdfhf2(a: f64, expected: u16) void {78fn test_f16_floatCast_f64(a: f64, expected: u16) !void {
76 const rep: u16 = @bitCast(__truncdfhf2(a));79 const rep: u16 = @bitCast(f16_floatCast_f64(a));
7780
78 if (rep == expected) {81 if (rep == expected) {
79 return;82 return;
...@@ -84,62 +87,56 @@ fn test__truncdfhf2(a: f64, expected: u16) void {...@@ -84,62 +87,56 @@ fn test__truncdfhf2(a: f64, expected: u16) void {
84 return;87 return;
85 }88 }
86 }89 }
8790 return error.TestFailure;
88 @panic("__truncdfhf2 test failure");
89}91}
9092
91fn test__truncdfhf2_raw(a: u64, expected: u16) void {93fn test_f16_floatCast_f64_raw(a: u64, expected: u16) !void {
92 const actual: u16 = @bitCast(__truncdfhf2(@bitCast(a)));94 const actual: u16 = @bitCast(f16_floatCast_f64(@bitCast(a)));
9395 try testing.expect(actual == expected);
94 if (actual == expected) {
95 return;
96 }
97
98 @panic("__truncdfhf2 test failure");
99}96}
10097
101test "truncdfhf2" {98test f16_floatCast_f64 {
102 test__truncdfhf2_raw(0x7ff8000000000000, 0x7e00); // qNaN99 try test_f16_floatCast_f64_raw(0x7ff8000000000000, 0x7e00); // qNaN
103 test__truncdfhf2_raw(0x7ff0000000008000, 0x7e00); // NaN100 try test_f16_floatCast_f64_raw(0x7ff0000000008000, 0x7e00); // NaN
104101
105 test__truncdfhf2_raw(0x7ff0000000000000, 0x7c00); //inf102 try test_f16_floatCast_f64_raw(0x7ff0000000000000, 0x7c00); //inf
106 test__truncdfhf2_raw(0xfff0000000000000, 0xfc00); // -inf103 try test_f16_floatCast_f64_raw(0xfff0000000000000, 0xfc00); // -inf
107104
108 test__truncdfhf2(0.0, 0x0); // zero105 try test_f16_floatCast_f64(0.0, 0x0); // zero
109 test__truncdfhf2_raw(0x80000000 << 32, 0x8000); // -zero106 try test_f16_floatCast_f64_raw(0x80000000 << 32, 0x8000); // -zero
110107
111 test__truncdfhf2(3.1415926535, 0x4248);108 try test_f16_floatCast_f64(3.1415926535, 0x4248);
112 test__truncdfhf2(-3.1415926535, 0xc248);109 try test_f16_floatCast_f64(-3.1415926535, 0xc248);
113110
114 test__truncdfhf2(0x1.987124876876324p+1000, 0x7c00);111 try test_f16_floatCast_f64(0x1.987124876876324p+1000, 0x7c00);
115 test__truncdfhf2(0x1.987124876876324p+12, 0x6e62);112 try test_f16_floatCast_f64(0x1.987124876876324p+12, 0x6e62);
116 test__truncdfhf2(0x1.0p+0, 0x3c00);113 try test_f16_floatCast_f64(0x1.0p+0, 0x3c00);
117 test__truncdfhf2(0x1.0p-14, 0x0400);114 try test_f16_floatCast_f64(0x1.0p-14, 0x0400);
118115
119 // denormal116 // denormal
120 test__truncdfhf2(0x1.0p-20, 0x0010);117 try test_f16_floatCast_f64(0x1.0p-20, 0x0010);
121 test__truncdfhf2(0x1.0p-24, 0x0001);118 try test_f16_floatCast_f64(0x1.0p-24, 0x0001);
122 test__truncdfhf2(-0x1.0p-24, 0x8001);119 try test_f16_floatCast_f64(-0x1.0p-24, 0x8001);
123 test__truncdfhf2(0x1.5p-25, 0x0001);120 try test_f16_floatCast_f64(0x1.5p-25, 0x0001);
124121
125 // and back to zero122 // and back to zero
126 test__truncdfhf2(0x1.0p-25, 0x0000);123 try test_f16_floatCast_f64(0x1.0p-25, 0x0000);
127 test__truncdfhf2(-0x1.0p-25, 0x8000);124 try test_f16_floatCast_f64(-0x1.0p-25, 0x8000);
128125
129 // max (precise)126 // max (precise)
130 test__truncdfhf2(65504.0, 0x7bff);127 try test_f16_floatCast_f64(65504.0, 0x7bff);
131128
132 // max (rounded)129 // max (rounded)
133 test__truncdfhf2(65519.0, 0x7bff);130 try test_f16_floatCast_f64(65519.0, 0x7bff);
134131
135 // max (to +inf)132 // max (to +inf)
136 test__truncdfhf2(65520.0, 0x7c00);133 try test_f16_floatCast_f64(65520.0, 0x7c00);
137 test__truncdfhf2(-65520.0, 0xfc00);134 try test_f16_floatCast_f64(-65520.0, 0xfc00);
138 test__truncdfhf2(65536.0, 0x7c00);135 try test_f16_floatCast_f64(65536.0, 0x7c00);
139}136}
140137
141fn test__trunctfsf2(a: f128, expected: u32) void {138fn test_f32_floatCast_f128(a: f128, expected: u32) !void {
142 const x = __trunctfsf2(a);139 const x = f32_floatCast_f128(a);
143140
144 const rep: u32 = @bitCast(x);141 const rep: u32 = @bitCast(x);
145 if (rep == expected) {142 if (rep == expected) {
...@@ -151,28 +148,27 @@ fn test__trunctfsf2(a: f128, expected: u32) void {...@@ -151,28 +148,27 @@ fn test__trunctfsf2(a: f128, expected: u32) void {
151 return;148 return;
152 }149 }
153 }150 }
154151 return error.TestFailure;
155 @panic("__trunctfsf2 test failure");
156}152}
157153
158test "trunctfsf2" {154test f32_floatCast_f128 {
159 // qnan155 // qnan
160 test__trunctfsf2(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7fc00000);156 try test_f32_floatCast_f128(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7fc00000);
161 // nan157 // 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 // inf159 // inf
164 test__trunctfsf2(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7f800000);160 try test_f32_floatCast_f128(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7f800000);
165 // zero161 // zero
166 test__trunctfsf2(0.0, 0x0);162 try test_f32_floatCast_f128(0.0, 0x0);
167163
168 test__trunctfsf2(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x4211d156);164 try test_f32_floatCast_f128(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x4211d156);
169 test__trunctfsf2(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x3b71e9e2);165 try test_f32_floatCast_f128(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x3b71e9e2);
170 test__trunctfsf2(0x1.234eebb5faa678f4488693abcdefp+4534, 0x7f800000);166 try test_f32_floatCast_f128(0x1.234eebb5faa678f4488693abcdefp+4534, 0x7f800000);
171 test__trunctfsf2(0x1.edcba9bb8c76a5a43dd21f334634p-435, 0x0);167 try test_f32_floatCast_f128(0x1.edcba9bb8c76a5a43dd21f334634p-435, 0x0);
172}168}
173169
174fn test__trunctfdf2(a: f128, expected: u64) void {170fn test_f64_floatCast_f128(a: f128, expected: u64) !void {
175 const x = __trunctfdf2(a);171 const x = f64_floatCast_f128(a);
176172
177 const rep: u64 = @bitCast(x);173 const rep: u64 = @bitCast(x);
178 if (rep == expected) {174 if (rep == expected) {
...@@ -184,28 +180,27 @@ fn test__trunctfdf2(a: f128, expected: u64) void {...@@ -184,28 +180,27 @@ fn test__trunctfdf2(a: f128, expected: u64) void {
184 return;180 return;
185 }181 }
186 }182 }
187183 return error.TestFailure;
188 @panic("__trunctfsf2 test failure");
189}184}
190185
191test "trunctfdf2" {186test f64_floatCast_f128 {
192 // qnan187 // qnan
193 test__trunctfdf2(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000);188 try test_f64_floatCast_f128(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000);
194 // nan189 // 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 // inf191 // inf
197 test__trunctfdf2(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7ff0000000000000);192 try test_f64_floatCast_f128(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7ff0000000000000);
198 // zero193 // zero
199 test__trunctfdf2(0.0, 0x0);194 try test_f64_floatCast_f128(0.0, 0x0);
200195
201 test__trunctfdf2(0x1.af23456789bbaaab347645365cdep+5, 0x404af23456789bbb);196 try test_f64_floatCast_f128(0x1.af23456789bbaaab347645365cdep+5, 0x404af23456789bbb);
202 test__trunctfdf2(0x1.dedafcff354b6ae9758763545432p-9, 0x3f6dedafcff354b7);197 try test_f64_floatCast_f128(0x1.dedafcff354b6ae9758763545432p-9, 0x3f6dedafcff354b7);
203 test__trunctfdf2(0x1.2f34dd5f437e849b4baab754cdefp+4534, 0x7ff0000000000000);198 try test_f64_floatCast_f128(0x1.2f34dd5f437e849b4baab754cdefp+4534, 0x7ff0000000000000);
204 test__trunctfdf2(0x1.edcbff8ad76ab5bf46463233214fp-435, 0x24cedcbff8ad76ab);199 try test_f64_floatCast_f128(0x1.edcbff8ad76ab5bf46463233214fp-435, 0x24cedcbff8ad76ab);
205}200}
206201
207fn test__truncdfsf2(a: f64, expected: u32) void {202fn test_f32_floatCast_f64(a: f64, expected: u32) !void {
208 const x = __truncdfsf2(a);203 const x = f32_floatCast_f64(a);
209204
210 const rep: u32 = @bitCast(x);205 const rep: u32 = @bitCast(x);
211 if (rep == expected) {206 if (rep == expected) {
...@@ -217,90 +212,81 @@ fn test__truncdfsf2(a: f64, expected: u32) void {...@@ -217,90 +212,81 @@ fn test__truncdfsf2(a: f64, expected: u32) void {
217 return;212 return;
218 }213 }
219 }214 }
220215 return error.TestFailure;
221 std.debug.print("got 0x{x} wanted 0x{x}\n", .{ rep, expected });
222
223 @panic("__trunctfsf2 test failure");
224}216}
225217
226test "truncdfsf2" {218test f32_floatCast_f64 {
227 // nan & qnan219 // nan & qnan
228 test__truncdfsf2(@bitCast(@as(u64, 0x7ff8000000000000)), 0x7fc00000);220 try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff8000000000000)), 0x7fc00000);
229 test__truncdfsf2(@bitCast(@as(u64, 0x7ff0000000000001)), 0x7fc00000);221 try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff0000000000001)), 0x7fc00000);
230 // inf222 // inf
231 test__truncdfsf2(@bitCast(@as(u64, 0x7ff0000000000000)), 0x7f800000);223 try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff0000000000000)), 0x7f800000);
232 test__truncdfsf2(@bitCast(@as(u64, 0xfff0000000000000)), 0xff800000);224 try test_f32_floatCast_f64(@bitCast(@as(u64, 0xfff0000000000000)), 0xff800000);
233225
234 test__truncdfsf2(0.0, 0x0);226 try test_f32_floatCast_f64(0.0, 0x0);
235 test__truncdfsf2(1.0, 0x3f800000);227 try test_f32_floatCast_f64(1.0, 0x3f800000);
236 test__truncdfsf2(-1.0, 0xbf800000);228 try test_f32_floatCast_f64(-1.0, 0xbf800000);
237229
238 // huge number becomes inf230 // huge number becomes inf
239 test__truncdfsf2(340282366920938463463374607431768211456.0, 0x7f800000);231 try test_f32_floatCast_f64(340282366920938463463374607431768211456.0, 0x7f800000);
240}232}
241233
242fn test__trunctfhf2(a: f128, expected: u16) void {234fn test_f16_floatCast_f128(a: f128, expected: u16) !void {
243 const x = __trunctfhf2(a);235 const x = f16_floatCast_f128(a);
244236
245 const rep: u16 = @bitCast(x);237 const rep: u16 = @bitCast(x);
246 if (rep == expected) {238 try testing.expect(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");
253}239}
254240
255test "trunctfhf2" {241test f16_floatCast_f128 {
256 // qNaN242 // qNaN
257 test__trunctfhf2(@bitCast(@as(u128, 0x7fff8000000000000000000000000000)), 0x7e00);243 try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff8000000000000000000000000000)), 0x7e00);
258 // NaN244 // NaN
259 test__trunctfhf2(@bitCast(@as(u128, 0x7fff0000000000000000000000000001)), 0x7e00);245 try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff0000000000000000000000000001)), 0x7e00);
260 // inf246 // inf
261 test__trunctfhf2(@bitCast(@as(u128, 0x7fff0000000000000000000000000000)), 0x7c00);247 try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff0000000000000000000000000000)), 0x7c00);
262 test__trunctfhf2(-@as(f128, @bitCast(@as(u128, 0x7fff0000000000000000000000000000))), 0xfc00);248 try test_f16_floatCast_f128(-@as(f128, @bitCast(@as(u128, 0x7fff0000000000000000000000000000))), 0xfc00);
263 // zero249 // zero
264 test__trunctfhf2(0.0, 0x0);250 try test_f16_floatCast_f128(0.0, 0x0);
265 test__trunctfhf2(-0.0, 0x8000);251 try test_f16_floatCast_f128(-0.0, 0x8000);
266252
267 test__trunctfhf2(3.1415926535, 0x4248);253 try test_f16_floatCast_f128(3.1415926535, 0x4248);
268 test__trunctfhf2(-3.1415926535, 0xc248);254 try test_f16_floatCast_f128(-3.1415926535, 0xc248);
269 test__trunctfhf2(0x1.987124876876324p+100, 0x7c00);255 try test_f16_floatCast_f128(0x1.987124876876324p+100, 0x7c00);
270 test__trunctfhf2(0x1.987124876876324p+12, 0x6e62);256 try test_f16_floatCast_f128(0x1.987124876876324p+12, 0x6e62);
271 test__trunctfhf2(0x1.0p+0, 0x3c00);257 try test_f16_floatCast_f128(0x1.0p+0, 0x3c00);
272 test__trunctfhf2(0x1.0p-14, 0x0400);258 try test_f16_floatCast_f128(0x1.0p-14, 0x0400);
273 // denormal259 // denormal
274 test__trunctfhf2(0x1.0p-20, 0x0010);260 try test_f16_floatCast_f128(0x1.0p-20, 0x0010);
275 test__trunctfhf2(0x1.0p-24, 0x0001);261 try test_f16_floatCast_f128(0x1.0p-24, 0x0001);
276 test__trunctfhf2(-0x1.0p-24, 0x8001);262 try test_f16_floatCast_f128(-0x1.0p-24, 0x8001);
277 test__trunctfhf2(0x1.5p-25, 0x0001);263 try test_f16_floatCast_f128(0x1.5p-25, 0x0001);
278 // and back to zero264 // and back to zero
279 test__trunctfhf2(0x1.0p-25, 0x0000);265 try test_f16_floatCast_f128(0x1.0p-25, 0x0000);
280 test__trunctfhf2(-0x1.0p-25, 0x8000);266 try test_f16_floatCast_f128(-0x1.0p-25, 0x8000);
281 // max (precise)267 // max (precise)
282 test__trunctfhf2(65504.0, 0x7bff);268 try test_f16_floatCast_f128(65504.0, 0x7bff);
283 // max (rounded)269 // max (rounded)
284 test__trunctfhf2(65519.0, 0x7bff);270 try test_f16_floatCast_f128(65519.0, 0x7bff);
285 // max (to +inf)271 // max (to +inf)
286 test__trunctfhf2(65520.0, 0x7c00);272 try test_f16_floatCast_f128(65520.0, 0x7c00);
287 test__trunctfhf2(65536.0, 0x7c00);273 try test_f16_floatCast_f128(65536.0, 0x7c00);
288 test__trunctfhf2(-65520.0, 0xfc00);274 try test_f16_floatCast_f128(-65520.0, 0xfc00);
289275
290 test__trunctfhf2(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x508f);276 try test_f16_floatCast_f128(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x508f);
291 test__trunctfhf2(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x1b8f);277 try test_f16_floatCast_f128(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x1b8f);
292 test__trunctfhf2(0x1.234eebb5faa678f4488693abcdefp+453, 0x7c00);278 try test_f16_floatCast_f128(0x1.234eebb5faa678f4488693abcdefp+453, 0x7c00);
293 test__trunctfhf2(0x1.edcba9bb8c76a5a43dd21f334634p-43, 0x0);279 try test_f16_floatCast_f128(0x1.edcba9bb8c76a5a43dd21f334634p-43, 0x0);
294}280}
295281
296test "trunctfxf2" {282fn test_f80_floatCast_f128(a: f128, expected: f80) !void {
297 try test__trunctfxf2(1.5, 1.5);283 const x = f80_floatCast_f128(a);
298 try test__trunctfxf2(2.5, 2.5);284 try testing.expect(x == expected);
299 try test__trunctfxf2(-2.5, -2.5);
300 try test__trunctfxf2(0.0, 0.0);
301}285}
302286
303fn test__trunctfxf2(a: f128, expected: f80) !void {287test f80_floatCast_f128 {
304 const x = __trunctfxf2(a);288 try test_f80_floatCast_f128(1.5, 1.5);
305 try testing.expect(x == expected);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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const truncf = @import("./truncf.zig").truncf;
4
5comptime {
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
14pub fn __truncsfhf2(a: f32) callconv(.c) compiler_rt.F16T(f32) {
15 return @bitCast(truncf(f16, f32, a));
16}
17
18fn __gnu_f2h_ieee(a: f32) callconv(.c) compiler_rt.F16T(f32) {
19 return @bitCast(truncf(f16, f32, a));
20}
21
22fn __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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const truncf = @import("./truncf.zig").truncf;
4
5comptime {
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
16pub fn __trunctfdf2(a: f128) callconv(.c) f64 {
17 return truncf(f64, f128, a);
18}
19
20fn _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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const truncf = @import("./truncf.zig").truncf;
4
5comptime {
6 symbol(&__trunctfhf2, "__trunctfhf2");
7 if (compiler_rt.want_ppc_abi) {
8 symbol(&__trunctfhf2, "__trunckfhf2");
9 }
10}
11
12pub 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 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const truncf = @import("./truncf.zig").truncf;
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
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
16pub fn __trunctfsf2(a: f128) callconv(.c) f32 {
17 return truncf(f32, f128, a);
18}
19
20fn _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 @@
1const math = @import("std").math;
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
4const trunc_f80 = @import("./truncf.zig").trunc_f80;
5
6comptime {
7 symbol(&__trunctfxf2, "__trunctfxf2");
8}
9
10pub 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 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const trunc_f80 = @import("./truncf.zig").trunc_f80;
3
4comptime {
5 symbol(&__truncxfdf2, "__truncxfdf2");
6}
7
8fn __truncxfdf2(a: f80) callconv(.c) f64 {
9 return trunc_f80(f64, a);
10}
lib/compiler_rt/truncxfhf2.zig deleted-11
...@@ -1,11 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = @import("../compiler_rt.zig").symbol;
3const trunc_f80 = @import("./truncf.zig").trunc_f80;
4
5comptime {
6 symbol(&__truncxfhf2, "__truncxfhf2");
7}
8
9fn __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 @@
1const trunc_f80 = @import("./truncf.zig").trunc_f80;
2const symbol = @import("../compiler_rt.zig").symbol;
3
4comptime {
5 symbol(&__truncxfsf2, "__truncxfsf2");
6}
7
8fn __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,7 +6,7 @@ const shr = std.math.shr;
6const shl = std.math.shl;6const shl = std.math.shl;
77
8const compiler_rt = @import("../compiler_rt.zig");8const compiler_rt = @import("../compiler_rt.zig");
9const symbol = @import("../compiler_rt.zig").symbol;9const symbol = compiler_rt.symbol;
1010
11const max_limbs = @divCeil(65535, 32); // max supported type is u6553511const max_limbs = @divCeil(65535, 32); // max supported type is u65535
1212
lib/compiler_rt/unorddf2.zig deleted-19
...@@ -1,19 +0,0 @@
1const compiler_rt = @import("../compiler_rt.zig");
2const comparef = @import("./comparef.zig");
3const symbol = @import("../compiler_rt.zig").symbol;
4
5comptime {
6 if (compiler_rt.want_aeabi) {
7 symbol(&__aeabi_dcmpun, "__aeabi_dcmpun");
8 } else {
9 symbol(&__unorddf2, "__unorddf2");
10 }
11}
12
13pub fn __unorddf2(a: f64, b: f64) callconv(.c) i32 {
14 return comparef.unordcmp(f64, a, b);
15}
16
17fn __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,7 +1211,7 @@ pub const rsa = struct {
1211 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,1211 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
1212 0x00, 0x04, 0x40,1212 0x00, 0x04, 0x40,
1213 },1213 },
1214 else => @compileError("unreachable"),1214 else => comptime unreachable,
1215 };1215 };
1216 em_index -= hash_der.len;1216 em_index -= hash_der.len;
1217 @memcpy(em[em_index..][0..hash_der.len], hash_der);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,7 +75,7 @@ pub const snan = float.snan;
75///75///
76/// NaN values are never considered equal to any value.76/// NaN values are never considered equal to any value.
77pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool {77pub 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 assert(tolerance >= 0);79 assert(tolerance >= 0);
8080
81 // Fast path for equal values (and signed zeros and infinites).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,7 +103,7 @@ pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool {
103///103///
104/// NaN values are never considered equal to any value.104/// NaN values are never considered equal to any value.
105pub fn approxEqRel(comptime T: type, x: T, y: T, tolerance: T) bool {105pub 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 assert(tolerance > 0);107 assert(tolerance > 0);
108108
109 // Fast path for equal values (and signed zeros and infinites).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,8 +252,8 @@ test "atan2_32.special" {
252252
253 try expect(math.isNan(atan2_32(1.0, math.nan(f32))));253 try expect(math.isNan(atan2_32(1.0, math.nan(f32))));
254 try expect(math.isNan(atan2_32(math.nan(f32), 1.0)));254 try expect(math.isNan(atan2_32(math.nan(f32), 1.0)));
255 try expect(atan2_32(0.0, 5.0) == 0.0);255 try expect(math.isPositiveZero(atan2_32(0.0, 5.0)));
256 try expect(atan2_32(-0.0, 5.0) == -0.0);256 try expect(math.isNegativeZero(atan2_32(-0.0, 5.0)));
257 try expect(math.approxEqAbs(f32, atan2_32(0.0, -5.0), math.pi, epsilon));257 try expect(math.approxEqAbs(f32, atan2_32(0.0, -5.0), math.pi, epsilon));
258 //expect(math.approxEqAbs(f32, atan2_32(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero?258 //expect(math.approxEqAbs(f32, atan2_32(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero?
259 try expect(math.approxEqAbs(f32, atan2_32(1.0, 0.0), math.pi / 2.0, epsilon));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,8 +276,8 @@ test "atan2_64.special" {
276276
277 try expect(math.isNan(atan2_64(1.0, math.nan(f64))));277 try expect(math.isNan(atan2_64(1.0, math.nan(f64))));
278 try expect(math.isNan(atan2_64(math.nan(f64), 1.0)));278 try expect(math.isNan(atan2_64(math.nan(f64), 1.0)));
279 try expect(atan2_64(0.0, 5.0) == 0.0);279 try expect(math.isPositiveZero(atan2_64(0.0, 5.0)));
280 try expect(atan2_64(-0.0, 5.0) == -0.0);280 try expect(math.isNegativeZero(atan2_64(-0.0, 5.0)));
281 try expect(math.approxEqAbs(f64, atan2_64(0.0, -5.0), math.pi, epsilon));281 try expect(math.approxEqAbs(f64, atan2_64(0.0, -5.0), math.pi, epsilon));
282 //expect(math.approxEqAbs(f64, atan2_64(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero?282 //expect(math.approxEqAbs(f64, atan2_64(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero?
283 try expect(math.approxEqAbs(f64, atan2_64(1.0, 0.0), math.pi / 2.0, epsilon));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,6 +527,20 @@ pub fn intAlignment(target: *const std.Target, bits: u16) u16 {
527 };527 };
528}528}
529529
530pub 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
530const std = @import("std");544const std = @import("std");
531const assert = std.debug.assert;545const assert = std.debug.assert;
532const Allocator = std.mem.Allocator;546const Allocator = std.mem.Allocator;
src/link.zig+1-1
...@@ -2127,7 +2127,7 @@ pub fn resolveInputs(...@@ -2127,7 +2127,7 @@ pub fn resolveInputs(
2127 continue;2127 continue;
2128 },2128 },
2129 }2129 }
2130 @compileError("unreachable");2130 comptime unreachable;
2131 }2131 }
21322132
2133 if (failed_libs.items.len > 0) {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,7 +1845,7 @@ test "coerce between pointers of compatible differently-named floats" {
1845 64 => f64,1845 64 => f64,
1846 80 => f80,1846 80 => f80,
1847 128 => f128,1847 128 => f128,
1848 else => @compileError("unreachable"),1848 else => comptime unreachable,
1849 };1849 };
1850 var f1: F = 12.34;1850 var f1: F = 12.34;
1851 const f2: *c_longdouble = &f1;1851 const f2: *c_longdouble = &f1;
test/behavior/floatop.zig+4-4
...@@ -431,9 +431,9 @@ fn testSqrt(comptime T: type) !void {...@@ -431,9 +431,9 @@ fn testSqrt(comptime T: type) !void {
431 var inf: T = math.inf(T);431 var inf: T = math.inf(T);
432 try expect(math.isPositiveInf(@sqrt(inf)));432 try expect(math.isPositiveInf(@sqrt(inf)));
433 var zero: T = 0.0;433 var zero: T = 0.0;
434 try expect(@sqrt(zero) == 0.0);434 try expect(math.isPositiveZero(@sqrt(zero)));
435 var neg_zero: T = -0.0;435 var neg_zero: T = -0.0;
436 try expect(@sqrt(neg_zero) == 0.0);436 try expect(math.isNegativeZero(@sqrt(neg_zero)));
437 var neg_one: T = -1.0;437 var neg_one: T = -1.0;
438 try expect(math.isNan(@sqrt(neg_one)));438 try expect(math.isNan(@sqrt(neg_one)));
439 var nan: T = math.nan(T);439 var nan: T = math.nan(T);
...@@ -1501,9 +1501,9 @@ fn testNeg(comptime T: type) !void {...@@ -1501,9 +1501,9 @@ fn testNeg(comptime T: type) !void {
15011501
1502 // subnormals1502 // subnormals
1503 var zero: T = 0.0;1503 var zero: T = 0.0;
1504 try expect(-zero == -0.0);1504 try expect(math.isNegativeZero(-zero));
1505 var neg_zero: T = -0.0;1505 var neg_zero: T = -0.0;
1506 try expect(-neg_zero == 0.0);1506 try expect(math.isPositiveZero(-neg_zero));
1507 var true_min: T = math.floatTrueMin(T);1507 var true_min: T = math.floatTrueMin(T);
1508 try expect(-true_min == -math.floatTrueMin(T));1508 try expect(-true_min == -math.floatTrueMin(T));
1509 var neg_true_min: T = -math.floatTrueMin(T);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,7 +1267,7 @@ test "switch with complex item expressions" {
1267test "switch evaluation order" {1267test "switch evaluation order" {
1268 const eu: anyerror!u32 = 0;1268 const eu: anyerror!u32 = 0;
1269 _ = eu catch |err| switch (err) {1269 _ = eu catch |err| switch (err) {
1270 if (true) @compileError("unreachable") => unreachable,1270 if (true) comptime unreachable => unreachable,
1271 else => unreachable,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,7 +243,7 @@ test "switch on error union catch capture" {
243 var a: error{}!u64 = 0;243 var a: error{}!u64 = 0;
244 _ = &a;244 _ = &a;
245 const b = a catch |err| switch (err) {245 const b = a catch |err| switch (err) {
246 undefined => @compileError("unreachable"),246 undefined => comptime unreachable,
247 };247 };
248 try expectEqual(@as(u64, 0), b);248 try expectEqual(@as(u64, 0), b);
249 }249 }
...@@ -829,7 +829,7 @@ test "switch on error union if else capture" {...@@ -829,7 +829,7 @@ test "switch on error union if else capture" {
829 var a: error{}!u64 = 0;829 var a: error{}!u64 = 0;
830 _ = &a;830 _ = &a;
831 const b = if (a) |x| x else |err| switch (err) {831 const b = if (a) |x| x else |err| switch (err) {
832 undefined => @compileError("unreachable"),832 undefined => comptime unreachable,
833 };833 };
834 try expectEqual(@as(u64, 0), b);834 try expectEqual(@as(u64, 0), b);
835 }835 }
...@@ -840,7 +840,7 @@ test "switch on error union if else capture" {...@@ -840,7 +840,7 @@ test "switch on error union if else capture" {
840 var a: error{}!u64 = 0;840 var a: error{}!u64 = 0;
841 _ = &a;841 _ = &a;
842 const b = if (a) |*x| x.* else |err| switch (err) {842 const b = if (a) |*x| x.* else |err| switch (err) {
843 undefined => @compileError("unreachable"),843 undefined => comptime unreachable,
844 };844 };
845 try expectEqual(@as(u64, 0), b);845 try expectEqual(@as(u64, 0), b);
846 }846 }