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 {
12771277 },
12781278 else => unreachable,
12791279 }
1280 @compileError("unreachable");
1280 comptime unreachable;
12811281 }
12821282
12831283 pub const OptionalParamParser = struct {
lib/compiler_rt.zig+120-168
......@@ -1,4 +1,5 @@
11const builtin = @import("builtin");
2const compiler_rt = @This();
23const ofmt_c = builtin.object_format == .c;
34const native_endian = builtin.cpu.arch.endian();
45
......@@ -84,144 +85,17 @@ comptime {
8485 // Float routines
8586 // conversion
8687 _ = @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
9888 _ = @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
11089 _ = @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
14990 _ = @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
19192 // comparison
19293 _ = @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
20395 // arithmetic
20496 _ = @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
21797 _ = @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");
22599 _ = @import("compiler_rt/divsf3.zig");
226100 _ = @import("compiler_rt/divdf3.zig");
227101 _ = @import("compiler_rt/divxf3.zig");
......@@ -235,25 +109,17 @@ comptime {
235109 symbol(&__negsf2, "__negsf2");
236110 symbol(&__negdf2, "__negdf2");
237111 }
238 if (want_ppc_abi) symbol(&__negtf2, "__negkf2");
239 symbol(&__negtf2, "__negtf2");
112 if (want_ppc_abi) {
113 symbol(&__negtf2, "__negkf2");
114 } else {
115 symbol(&__negtf2, "__negtf2");
116 }
240117 symbol(&__negxf2, "__negxf2");
241118
242119 // other
243120 _ = @import("compiler_rt/powiXf2.zig");
244121 _ = @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
251122 _ = @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
258124 // Math routines. Alphabetically sorted.
259125 _ = @import("compiler_rt/cos.zig");
......@@ -279,7 +145,7 @@ comptime {
279145 _ = @import("compiler_rt/divmodei4.zig");
280146 _ = @import("compiler_rt/udivmodei4.zig");
281147
282 _ = @import("compiler_rt/limb64.zig");
148 if (builtin.cpu.arch.isWasm()) _ = @import("compiler_rt/limb64.zig");
283149
284150 // extra
285151 _ = @import("compiler_rt/os_version_check.zig");
......@@ -290,7 +156,7 @@ comptime {
290156 _ = @import("compiler_rt/clear_cache.zig");
291157 _ = @import("compiler_rt/hexagon.zig");
292158
293 if (@import("builtin").object_format != .c) {
159 if (builtin.object_format != .c) {
294160 if (builtin.zig_backend != .stage2_aarch64) _ = @import("compiler_rt/atomics.zig");
295161 _ = @import("compiler_rt/stack_probe.zig");
296162
......@@ -366,10 +232,7 @@ pub const want_aeabi = switch (builtin.abi) {
366232 .gnueabihf,
367233 .android,
368234 .androideabi,
369 => switch (builtin.cpu.arch) {
370 .arm, .armeb, .thumb, .thumbeb => true,
371 else => false,
372 },
235 => builtin.cpu.arch.isArm(),
373236 else => false,
374237};
375238
......@@ -443,19 +306,108 @@ pub const gnu_f16_abi = switch (builtin.cpu.arch) {
443306pub const want_sparc64_abi = builtin.cpu.arch == .sparc64;
444307pub const want_sparc32_abi = builtin.cpu.arch == .sparc;
445308
446pub fn F16T(comptime OtherType: type) type {
447 return switch (builtin.cpu.arch) {
448 .x86, .x86_64 => if (builtin.target.os.tag.isDarwin()) switch (OtherType) {
449 // Starting with LLVM 16, Darwin uses different abi for f16
450 // depending on the type of the other return/argument..???
451 f32, f64 => u16,
452 f80, f128 => f16,
453 else => unreachable,
454 } else f16,
455 else => f16,
309/// For operations converting between `f16` and another floating point type.
310pub fn f16Conv(comptime OtherType: type) type {
311 switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 16)) {
312 .hard => {},
313 .soft => return softFloatAbi(f16),
314 }
315 if (builtin.cpu.arch.isX86() and builtin.os.tag.isDarwin()) switch (OtherType) {
316 else => unreachable,
317 // Starting with LLVM 16, Darwin uses different abi for f16
318 // depending on the type of the other return/argument..???
319 f32, f64 => return softFloatAbi(f16),
320 f80, f128 => {},
321 };
322 return hardFloatAbi(f16);
323}
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 }
456404 };
457405}
458406
407pub fn Complex(comptime Float: type) type {
408 return struct { real: Float, imag: Float };
409}
410
459411pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
460412 switch (Z) {
461413 u16 => {
......@@ -588,31 +540,31 @@ pub inline fn fneg(a: anytype) @TypeOf(a) {
588540 return @bitCast(negated);
589541}
590542
591fn __negxf2(a: f80) callconv(.c) f80 {
592 return fneg(a);
543fn __neghf2(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
544 return compiler_rt.f16.toAbi(fneg(compiler_rt.f16.fromAbi(a)));
593545}
594546
595fn __neghf2(a: f16) callconv(.c) f16 {
596 return fneg(a);
547fn __negsf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi {
548 return compiler_rt.f32.toAbi(fneg(compiler_rt.f32.fromAbi(a)));
597549}
598550
599fn __negdf2(a: f64) callconv(.c) f64 {
600 return fneg(a);
551fn __negdf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
552 return compiler_rt.f64.toAbi(fneg(compiler_rt.f64.fromAbi(a)));
601553}
602554
603fn __aeabi_dneg(a: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
604 return fneg(a);
555fn __negxf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi {
556 return compiler_rt.f80.toAbi(fneg(compiler_rt.f80.fromAbi(a)));
605557}
606558
607fn __negtf2(a: f128) callconv(.c) f128 {
608 return fneg(a);
559fn __negtf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
560 return compiler_rt.f128.toAbi(fneg(compiler_rt.f128.fromAbi(a)));
609561}
610562
611fn __negsf2(a: f32) callconv(.c) f32 {
563fn __aeabi_fneg(a: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
612564 return fneg(a);
613565}
614566
615fn __aeabi_fneg(a: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
567fn __aeabi_dneg(a: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
616568 return fneg(a);
617569}
618570
lib/compiler_rt/absv.zig+1-2
......@@ -14,8 +14,7 @@ pub inline fn absv(comptime ST: type, a: ST) ST {
1414 const sign: ST = a >> N - 1;
1515 x +%= sign;
1616 x ^= sign;
17 if (x < 0)
18 @panic("compiler_rt absv: overflow");
17 if (x < 0) @panic("integer overflow");
1918 return x;
2019}
2120
lib/compiler_rt/absvdi2.zig+3-2
......@@ -1,5 +1,6 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const absv = @import("./absv.zig").absv;
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const absv = @import("absv.zig").absv;
34
45comptime {
56 symbol(&__absvdi2, "__absvdi2");
lib/compiler_rt/absvsi2.zig+1-1
......@@ -1,6 +1,6 @@
11const compiler_rt = @import("../compiler_rt.zig");
22const symbol = compiler_rt.symbol;
3const absv = @import("./absv.zig").absv;
3const absv = @import("absv.zig").absv;
44
55comptime {
66 symbol(&__absvsi2, "__absvsi2");
lib/compiler_rt/absvti2.zig+3-2
......@@ -1,5 +1,6 @@
1const symbol = @import("../compiler_rt.zig").symbol;
2const absv = @import("./absv.zig").absv;
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
3const absv = @import("absv.zig").absv;
34
45comptime {
56 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 @@
11const std = @import("std");
22const math = std.math;
33const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
45const 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
6137/// Ported from:
7138///
8139/// 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 {
10141 const bits = @typeInfo(T).float.bits;
11142 const Z = @Int(.unsigned, bits);
12143
lib/compiler_rt/addf3_test.zig+7-6
......@@ -8,12 +8,13 @@ const builtin = @import("builtin");
88const math = std.math;
99const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64);
1010
11const __addtf3 = @import("addtf3.zig").__addtf3;
12const __addxf3 = @import("addxf3.zig").__addxf3;
13const __subtf3 = @import("subtf3.zig").__subtf3;
11const impl = @import("addf3.zig");
12const add_f128 = impl.add_f128;
13const add_f80 = impl.add_f80;
14const sub_f128 = impl.sub_f128;
1415
1516fn 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
1819 const rep: u128 = @bitCast(x);
1920 const hi: u64 = @intCast(rep >> 64);
......@@ -52,7 +53,7 @@ test "addtf3" {
5253}
5354
5455fn 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
5758 const rep: u128 = @bitCast(x);
5859 const hi: u64 = @intCast(rep >> 64);
......@@ -91,7 +92,7 @@ test "subtf3" {
9192const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1)));
9293
9394fn test__addxf3(a: f80, b: f80, expected: u80) !void {
94 const x = __addxf3(a, b);
95 const x = add_f80(a, b);
9596 const rep: u80 = @bitCast(x);
9697
9798 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 @@
1const symbol = @import("../compiler_rt.zig").symbol;
1const compiler_rt = @import("../compiler_rt.zig");
2const symbol = compiler_rt.symbol;
23const testing = @import("std").testing;
34
45comptime {
......@@ -9,7 +10,7 @@ pub fn __addvdi3(a: i64, b: i64) callconv(.c) i64 {
910 const sum = a +% b;
1011 // Overflow occurred iff both operands have the same sign, and the sign of the sum does
1112 // 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");
1314 return sum;
1415}
1516
lib/compiler_rt/addvsi3.zig+1-1
......@@ -10,7 +10,7 @@ pub fn __addvsi3(a: i32, b: i32) callconv(.c) i32 {
1010 const sum = a +% b;
1111 // Overflow occurred iff both operands have the same sign, and the sign of the sum does
1212 // 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");
1414 return sum;
1515}
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;
55const std = @import("std");
66
77const compiler_rt = @import("../compiler_rt.zig");
8const symbol = @import("../compiler_rt.zig").symbol;
8const symbol = compiler_rt.symbol;
99
1010// This parameter is true iff the target architecture supports the bare minimum
1111// to implement the atomic load/store intrinsics.
lib/compiler_rt/aulldiv.zig+1-1
......@@ -1,7 +1,7 @@
11const builtin = @import("builtin");
22
33const compiler_rt = @import("../compiler_rt.zig");
4const symbol = @import("../compiler_rt.zig").symbol;
4const symbol = compiler_rt.symbol;
55
66comptime {
77 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 @@
55const std = @import("std");
66const builtin = @import("builtin");
77
8const __eqdf2 = @import("./cmpdf2.zig").__eqdf2;
9const __ledf2 = @import("./cmpdf2.zig").__ledf2;
10const __ltdf2 = @import("./cmpdf2.zig").__ltdf2;
11const __nedf2 = @import("./cmpdf2.zig").__nedf2;
8const compiler_rt = @import("../compiler_rt.zig");
129
13const __gedf2 = @import("./gedf2.zig").__gedf2;
14const __gtdf2 = @import("./gedf2.zig").__gtdf2;
15
16const __unorddf2 = @import("./unorddf2.zig").__unorddf2;
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}
10const impl = @import("comparef.zig");
11const Order = impl.Order;
12const cmp_f64 = impl.cmp_f64;
13const unord_f64 = impl.unord_f64;
5414
5515const arguments = [_]f64{
5616 std.math.nan(f64),
......@@ -73,36 +33,20 @@ const arguments = [_]f64{
7333 std.math.inf(f64),
7434};
7535
76fn generateVector(comptime a: f64, comptime b: f64) TestVector {
77 const leResult = if (a < b) -1 else if (a == b) 0 else 1;
78 const geResult = if (a > b) 1 else if (a == b) 0 else -1;
79 const unResult = if (a != a or b != b) 1 else 0;
80 return TestVector{
81 .a = a,
82 .b = b,
83 .eqReference = leResult,
84 .geReference = geResult,
85 .gtReference = geResult,
86 .leReference = leResult,
87 .ltReference = leResult,
88 .neReference = leResult,
89 .unReference = unResult,
90 };
91}
92
93const test_vectors = init: {
94 @setEvalBranchQuota(10000);
95 var vectors: [arguments.len * arguments.len]TestVector = undefined;
36test "compare f64" {
9637 for (arguments[0..], 0..) |arg_i, i| {
9738 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));
9950 }
10051 }
101 break :init vectors;
102};
103
104test "compare f64" {
105 for (test_vectors) |vector| {
106 try std.testing.expect(test__cmpdf2(vector));
107 }
10852}
lib/compiler_rt/comparef.zig+274-167
......@@ -1,163 +1,309 @@
1const builtin = @import("builtin");
12const std = @import("std");
23
34const compiler_rt = @import("../compiler_rt.zig");
45const symbol = compiler_rt.symbol;
56
6comptime {
7 if (compiler_rt.want_aeabi) {
8 symbol(&__aeabi_fcmpun, "__aeabi_fcmpun");
9 } else {
10 symbol(&__unordsf2, "__unordsf2");
11 }
12
13 symbol(&__unordxf2, "__unordxf2");
7const Unordered = if (builtin.cpu.arch == .avr)
8 i8
9else if (builtin.cpu.arch.isAARCH64())
10 i32
11else if (builtin.target.cTypeBitSize(.long) >= builtin.target.ptrBitWidth())
12 c_long
13else
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");
16 symbol(&__nehf2, "__nehf2");
17 symbol(&__lehf2, "__lehf2");
18comptime {
1819 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
2128 if (compiler_rt.want_aeabi) {
2229 symbol(&__aeabi_fcmpeq, "__aeabi_fcmpeq");
2330 symbol(&__aeabi_fcmplt, "__aeabi_fcmplt");
2431 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");
2542 } else {
26 symbol(&__eqsf2, "__eqsf2");
27 symbol(&__nesf2, "__nesf2");
28 symbol(&__lesf2, "__lesf2");
2943 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");
3160 }
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
3371 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");
3478 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");
35104 }
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);
42105}
43106
44pub fn __unordtf2(a: f128, b: f128) callconv(.c) i32 {
45 return unordcmp(f128, a, b);
107fn __cmphf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Order {
108 return cmp_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)) orelse .gt;
46109}
47
48/// "These functions calculate a <=> b. That is, if a is less than b, they return -1;
49/// if a is greater than b, they return 1; and if a and b are equal they return 0.
50/// If either argument is NaN they return 1..."
51///
52/// Note that this matches the definition of `__lesf2`, `__eqsf2`, `__nesf2`, `__cmpsf2`,
53/// and `__ltsf2`.
54fn __cmpsf2(a: f32, b: f32) callconv(.c) i32 {
55 return @backingInt(cmpf2(f32, LE, a, b));
110fn __gehf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Order {
111 return cmp_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)) orelse .lt;
56112}
57
58/// "These functions return a value less than or equal to zero if neither argument is NaN,
59/// and a is less than or equal to b."
60pub fn __lesf2(a: f32, b: f32) callconv(.c) i32 {
61 return __cmpsf2(a, b);
113fn __unordhf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Unordered {
114 return @intFromBool(unord_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)));
62115}
63
64/// "These functions return zero if neither argument is NaN, and a and b are equal."
65/// Note that due to some kind of historical accident, __eqsf2 and __nesf2 are defined
66/// to have the same return value.
67pub fn __eqsf2(a: f32, b: f32) callconv(.c) i32 {
68 return __cmpsf2(a, b);
116pub fn cmp_f16(a: f16, b: f16) ?Order {
117 return cmpf2(f16, a, b);
69118}
70
71/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal."
72/// Note that due to some kind of historical accident, __eqsf2 and __nesf2 are defined
73/// to have the same return value.
74pub fn __nesf2(a: f32, b: f32) callconv(.c) i32 {
75 return __cmpsf2(a, b);
119pub fn unord_f16(a: f16, b: f16) bool {
120 return unord(f16, a, b);
76121}
77122
78/// "These functions return a value less than zero if neither argument is NaN, and a
79/// is strictly less than b."
80pub fn __ltsf2(a: f32, b: f32) callconv(.c) i32 {
81 return __cmpsf2(a, b);
123fn __cmpsf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Order {
124 return cmp_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)) orelse .gt;
82125}
83
84126fn __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);
86128}
87
88129fn __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);
90131}
91
92132fn __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);
94134}
95
96/// "These functions calculate a <=> b. That is, if a is less than b, they return -1;
97/// if a is greater than b, they return 1; and if a and b are equal they return 0.
98/// If either argument is NaN they return 1..."
99///
100/// Note that this matches the definition of `__lehf2`, `__eqhf2`, `__nehf2`, `__cmphf2`,
101/// and `__lthf2`.
102fn __cmphf2(a: f16, b: f16) callconv(.c) i32 {
103 return @backingInt(cmpf2(f16, LE, a, b));
135fn __gesf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Order {
136 return cmp_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)) orelse .lt;
104137}
105
106/// "These functions return a value less than or equal to zero if neither argument is NaN,
107/// and a is less than or equal to b."
108fn __lehf2(a: f16, b: f16) callconv(.c) i32 {
109 return __cmphf2(a, b);
138fn __aeabi_fcmpge(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
139 return @intFromBool(cmp_f32(a, b) orelse .lt != .lt);
110140}
111
112/// "These functions return zero if neither argument is NaN, and a and b are equal."
113/// Note that due to some kind of historical accident, __eqhf2 and __nehf2 are defined
114/// to have the same return value.
115fn __eqhf2(a: f16, b: f16) callconv(.c) i32 {
116 return __cmphf2(a, b);
141fn __aeabi_fcmpgt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
142 return @intFromBool(cmp_f32(a, b) == .gt);
117143}
118
119/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal."
120/// Note that due to some kind of historical accident, __eqhf2 and __nehf2 are defined
121/// to have the same return value.
122fn __nehf2(a: f16, b: f16) callconv(.c) i32 {
123 return __cmphf2(a, b);
144fn __unordsf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Unordered {
145 return @intFromBool(unord_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)));
124146}
125
126/// "These functions return a value less than zero if neither argument is NaN, and a
127/// is strictly less than b."
128fn __lthf2(a: f16, b: f16) callconv(.c) i32 {
129 return __cmphf2(a, b);
147fn __aeabi_fcmpun(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
148 return @intFromBool(unord_f32(a, b));
130149}
131
132fn __unordxf2(a: f80, b: f80) callconv(.c) i32 {
133 return unordcmp(f80, a, b);
150pub fn cmp_f32(a: f32, b: f32) ?Order {
151 return cmpf2(f32, a, b);
152}
153pub fn unord_f32(a: f32, b: f32) bool {
154 return unord(f32, a, b);
134155}
135156
136pub fn __unordsf2(a: f32, b: f32) callconv(.c) i32 {
137 return unordcmp(f32, a, b);
157fn __cmpdf2(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) Order {
158 return cmp_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)) orelse .gt;
159}
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);
138189}
139190
140fn __aeabi_fcmpun(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 {
141 return unordcmp(f32, a, b);
191fn __cmpxf2(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) Order {
192 return cmp_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b)) orelse .gt;
193}
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;
142196}
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) {
145 Less = -1,
146 Equal = 0,
147 Greater = 1,
208 // If either a or b is NaN, they are unordered.
209 if ((a_rep.exp & special_exp == special_exp and a_rep.fraction ^ int_bit != 0) or
210 (b_rep.exp & special_exp == special_exp and b_rep.fraction ^ int_bit != 0))
211 return null;
148212
149 const Unordered: LE = .Greater;
150};
213 // If a and b are both zeros, they are equal.
214 if ((a_rep.fraction | b_rep.fraction) | ((a_rep.exp | b_rep.exp) & special_exp) == 0)
215 return .eq;
151216
152pub const GE = enum(i32) {
153 Less = -1,
154 Equal = 0,
155 Greater = 1,
217 if (@intFromBool(a_rep.exp == b_rep.exp) & @intFromBool(a_rep.fraction == b_rep.fraction) != 0) {
218 return .eq;
219 } else if (a_rep.exp & sign_bit != b_rep.exp & sign_bit) {
220 // signs are different
221 if (@as(i16, @bitCast(a_rep.exp)) < @as(i16, @bitCast(b_rep.exp))) {
222 return .lt;
223 } else {
224 return .gt;
225 }
226 } else {
227 const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits);
228 const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits);
229 if ((a_fraction < b_fraction) == (a_rep.exp & sign_bit == 0)) {
230 return .lt;
231 } else {
232 return .gt;
233 }
234 }
235}
236pub fn unord_f80(a: f80, b: f80) bool {
237 return unord(f80, a, b);
238}
156239
157 const Unordered: GE = .Less;
158};
240fn __cmptf2(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) Order {
241 return cmp_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)) orelse .gt;
242}
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 {
161307 const bits = @typeInfo(T).float.bits;
162308 const srep_t = @Int(.signed, bits);
163309 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 {
175321 const bAbs = @as(rep_t, @bitCast(bInt)) & absMask;
176322
177323 // 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
180326 // 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
183329 // If at least one of a and b is positive, we get the same result comparing
184330 // a and b as signed integers as we would with a floating-point compare.
185331 if ((aInt & bInt) >= 0) {
186332 if (aInt < bInt) {
187 return .Less;
333 return .lt;
188334 } else if (aInt == bInt) {
189 return .Equal;
190 } else return .Greater;
335 return .eq;
336 } else return .gt;
191337 } else {
192338 // Otherwise, both are negative, so we need to flip the sense of the
193339 // comparison to get the correct result. (This assumes a twos- or ones-
194340 // complement integer representation; if integers are represented in a
195341 // sign-magnitude representation, then this flip is incorrect).
196342 if (aInt > bInt) {
197 return .Less;
343 return .lt;
198344 } else if (aInt == bInt) {
199 return .Equal;
200 } else return .Greater;
345 return .eq;
346 } else return .gt;
201347 }
202348}
203349
204pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT {
205 const a_rep = std.math.F80.fromFloat(a);
206 const b_rep = std.math.F80.fromFloat(b);
207 const sig_bits = std.math.floatMantissaBits(f80);
208 const int_bit = 0x8000000000000000;
209 const sign_bit = 0x8000;
210 const special_exp = 0x7FFF;
211
212 // If either a or b is NaN, they are unordered.
213 if ((a_rep.exp & special_exp == special_exp and a_rep.fraction ^ int_bit != 0) or
214 (b_rep.exp & special_exp == special_exp and b_rep.fraction ^ int_bit != 0))
215 return RT.Unordered;
216
217 // If a and b are both zeros, they are equal.
218 if ((a_rep.fraction | b_rep.fraction) | ((a_rep.exp | b_rep.exp) & special_exp) == 0)
219 return .Equal;
220
221 if (@intFromBool(a_rep.exp == b_rep.exp) & @intFromBool(a_rep.fraction == b_rep.fraction) != 0) {
222 return .Equal;
223 } else if (a_rep.exp & sign_bit != b_rep.exp & sign_bit) {
224 // signs are different
225 if (@as(i16, @bitCast(a_rep.exp)) < @as(i16, @bitCast(b_rep.exp))) {
226 return .Less;
227 } else {
228 return .Greater;
229 }
230 } else {
231 const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits);
232 const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits);
233 if ((a_fraction < b_fraction) == (a_rep.exp & sign_bit == 0)) {
234 return .Less;
235 } else {
236 return .Greater;
237 }
238 }
239}
240
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 }
350test cmp_f80 {
351 try std.testing.expect(cmp_f80(1.0, 1.0) == .eq);
352 try std.testing.expect(cmp_f80(0.0, -0.0) == .eq);
353 try std.testing.expect(cmp_f80(2.0, 4.0) == .lt);
354 try std.testing.expect(cmp_f80(2.0, -4.0) == .gt);
355 try std.testing.expect(cmp_f80(-2.0, -4.0) == .gt);
356 try std.testing.expect(cmp_f80(-2.0, 4.0) == .lt);
250357}
251358
252pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 {
359inline fn unord(comptime T: type, a: T, b: T) bool {
253360 const rep_t = @Int(.unsigned, @typeInfo(T).float.bits);
254361
255362 const significandBits = std.math.floatMantissaBits(T);
......@@ -261,7 +368,7 @@ pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 {
261368 const aAbs: rep_t = @as(rep_t, @bitCast(a)) & absMask;
262369 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;
265372}
266373
267374test {
lib/compiler_rt/comparesf2_test.zig+17-73
......@@ -5,52 +5,12 @@
55const std = @import("std");
66const builtin = @import("builtin");
77
8const __eqsf2 = @import("./comparef.zig").__eqsf2;
9const __lesf2 = @import("./comparef.zig").__lesf2;
10const __ltsf2 = @import("./comparef.zig").__ltsf2;
11const __nesf2 = @import("./comparef.zig").__nesf2;
8const compiler_rt = @import("../compiler_rt.zig");
129
13const __gesf2 = @import("./gesf2.zig").__gesf2;
14const __gtsf2 = @import("./gesf2.zig").__gtsf2;
15
16const __unordsf2 = @import("./comparef.zig").__unordsf2;
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}
10const impl = @import("comparef.zig");
11const Order = impl.Order;
12const cmp_f32 = impl.cmp_f32;
13const unord_f32 = impl.unord_f32;
5414
5515const arguments = [_]f32{
5616 std.math.nan(f32),
......@@ -73,36 +33,20 @@ const arguments = [_]f32{
7333 std.math.inf(f32),
7434};
7535
76fn generateVector(comptime a: f32, comptime b: f32) TestVector {
77 const leResult = if (a < b) -1 else if (a == b) 0 else 1;
78 const geResult = if (a > b) 1 else if (a == b) 0 else -1;
79 const unResult = if (a != a or b != b) 1 else 0;
80 return TestVector{
81 .a = a,
82 .b = b,
83 .eqReference = leResult,
84 .geReference = geResult,
85 .gtReference = geResult,
86 .leReference = leResult,
87 .ltReference = leResult,
88 .neReference = leResult,
89 .unReference = unResult,
90 };
91}
92
93const test_vectors = init: {
94 @setEvalBranchQuota(10000);
95 var vectors: [arguments.len * arguments.len]TestVector = undefined;
36test "compare f32" {
9637 for (arguments[0..], 0..) |arg_i, i| {
9738 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));
9950 }
10051 }
101 break :init vectors;
102};
103
104test "compare f32" {
105 for (test_vectors) |vector| {
106 try std.testing.expect(test__cmpsf2(vector));
107 }
10852}
lib/compiler_rt/cos.zig+64-50
......@@ -13,31 +13,35 @@ const expect = std.testing.expect;
1313const expectApproxEqAbs = std.testing.expectApproxEqAbs;
1414
1515const compiler_rt = @import("../compiler_rt.zig");
16const symbol = @import("../compiler_rt.zig").symbol;
16const symbol = compiler_rt.symbol;
1717const trig = @import("trig.zig");
1818const rem_pio2 = @import("rem_pio2.zig").rem_pio2;
1919const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;
2020const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l;
2121
2222comptime {
23 symbol(&cosh, "__cosh");
24 symbol(&cosl, "__cosl");
23 symbol(&__cosh, "__cosh");
2524 symbol(&cosf, "cosf");
2625 symbol(&cos, "cos");
27 symbol(&cosx, "__cosx");
28 if (compiler_rt.want_ppc_abi) {
29 symbol(&cosq, "cosf128");
30 }
26 symbol(&__cosx, "__cosx");
27 if (compiler_rt.want_ppc_abi) symbol(&cosq, "cosf128");
3128 symbol(&cosq, "cosq");
3229 symbol(&cosl, "cosl");
30 symbol(&cosl, "__cosl"); // required by musl
3331}
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 {
3637 // TODO: more efficient implementation
37 return @floatCast(cosf(a));
38 return @floatCast(cos_f32(x));
3839}
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 {
4145 // Small multiples of pi/2 rounded to double precision.
4246 const c1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18
4347 const c2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18
......@@ -94,7 +98,10 @@ pub fn cosf(x: f32) callconv(.c) f32 {
9498 };
9599}
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 {
98105 var ix = @as(u64, @bitCast(x)) >> 32;
99106 ix &= 0x7fffffff;
100107
......@@ -123,7 +130,10 @@ pub fn cos(x: f64) callconv(.c) f64 {
123130 };
124131}
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 {
127137 const se = ld.signExponent(x) & 0x7fff;
128138 if (se == 0x7fff) {
129139 return x - x;
......@@ -147,7 +157,10 @@ pub fn cosx(x: f80) callconv(.c) f80 {
147157 };
148158}
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 {
151164 const se = ld.signExponent(x) & 0x7fff;
152165 if (se == 0x7fff) {
153166 return x - x;
......@@ -173,20 +186,21 @@ pub fn cosq(x: f128) callconv(.c) f128 {
173186
174187pub fn cosl(x: c_longdouble) callconv(.c) c_longdouble {
175188 switch (@typeInfo(c_longdouble).float.bits) {
176 64 => return cos(x),
177 80 => return cosx(x),
178 128 => return cosq(x),
179 else => @compileError("unreachable"),
189 64 => return cos_f64(x),
190 80 => return cos_f80(x),
191 128 => return cos_f128(x),
192 else => comptime unreachable,
180193 }
181194}
182195
183196fn testCosSpecial(comptime T: type) !void {
184197 const f = switch (T) {
185 f32 => cosf,
186 f64 => cos,
187 f80 => cosx,
188 f128 => cosq,
189 else => @compileError("unimplemented"),
198 f16 => cos_f16,
199 f32 => cos_f32,
200 f64 => cos_f64,
201 f80 => cos_f80,
202 f128 => cos_f128,
203 else => comptime unreachable,
190204 };
191205
192206 try expect(f(0.0) == 1.0);
......@@ -198,13 +212,13 @@ fn testCosSpecial(comptime T: type) !void {
198212
199213test "cos32.normal" {
200214 const epsilon = math.floatEps(f32);
201 try expectApproxEqAbs(@as(f32, 1.0), cosf(0.0), epsilon);
202 try expectApproxEqAbs(@as(f32, 0.9800666), cosf(0.2), epsilon);
203 try expectApproxEqAbs(@as(f32, 0.6276231), cosf(0.8923), epsilon);
204 try expectApproxEqAbs(@as(f32, 0.0707372), cosf(1.5), epsilon);
205 try expectApproxEqAbs(@as(f32, 0.0707372), cosf(-1.5), epsilon);
206 try expectApproxEqAbs(@as(f32, 0.96913195), cosf(37.45), epsilon);
207 try expectApproxEqAbs(@as(f32, 0.40079966), cosf(89.123), epsilon);
215 try expectApproxEqAbs(@as(f32, 1.0), cos_f32(0.0), epsilon);
216 try expectApproxEqAbs(@as(f32, 0.9800666), cos_f32(0.2), epsilon);
217 try expectApproxEqAbs(@as(f32, 0.6276231), cos_f32(0.8923), epsilon);
218 try expectApproxEqAbs(@as(f32, 0.0707372), cos_f32(1.5), epsilon);
219 try expectApproxEqAbs(@as(f32, 0.0707372), cos_f32(-1.5), epsilon);
220 try expectApproxEqAbs(@as(f32, 0.96913195), cos_f32(37.45), epsilon);
221 try expectApproxEqAbs(@as(f32, 0.40079966), cos_f32(89.123), epsilon);
208222}
209223
210224test "cos32.special" {
......@@ -213,13 +227,13 @@ test "cos32.special" {
213227
214228test "cos64.normal" {
215229 const epsilon = math.floatEps(f64);
216 try expectApproxEqAbs(@as(f64, 1.0), cos(0.0), epsilon);
217 try expectApproxEqAbs(@as(f64, 0.9800665778412416), cos(0.2), epsilon);
218 try expectApproxEqAbs(@as(f64, 0.6276230983360804), cos(0.8923), epsilon);
219 try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos(1.5), epsilon);
220 try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos(-1.5), epsilon);
221 try expectApproxEqAbs(@as(f64, 0.9691317730707778), cos(37.45), epsilon);
222 try expectApproxEqAbs(@as(f64, 0.4008006809354791), cos(89.123), epsilon);
230 try expectApproxEqAbs(@as(f64, 1.0), cos_f64(0.0), epsilon);
231 try expectApproxEqAbs(@as(f64, 0.9800665778412416), cos_f64(0.2), epsilon);
232 try expectApproxEqAbs(@as(f64, 0.6276230983360804), cos_f64(0.8923), epsilon);
233 try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos_f64(1.5), epsilon);
234 try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos_f64(-1.5), epsilon);
235 try expectApproxEqAbs(@as(f64, 0.9691317730707778), cos_f64(37.45), epsilon);
236 try expectApproxEqAbs(@as(f64, 0.4008006809354791), cos_f64(89.123), epsilon);
223237}
224238
225239test "cos64.special" {
......@@ -228,13 +242,13 @@ test "cos64.special" {
228242
229243test "cos80.normal" {
230244 const epsilon = math.floatEps(f80);
231 try expectApproxEqAbs(@as(f80, 1.0), cosx(0.0), epsilon);
232 try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), cosx(0.2), epsilon);
233 try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), cosx(0.8923), epsilon);
234 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(1.5), epsilon);
235 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(-1.5), epsilon);
236 try expectApproxEqAbs(@as(f80, 0.9691317730707771246), cosx(37.45), epsilon);
237 try expectApproxEqAbs(@as(f80, 0.4008006809354834001), cosx(89.123), epsilon);
245 try expectApproxEqAbs(@as(f80, 1.0), cos_f80(0.0), epsilon);
246 try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), cos_f80(0.2), epsilon);
247 try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), cos_f80(0.8923), epsilon);
248 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cos_f80(1.5), epsilon);
249 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cos_f80(-1.5), epsilon);
250 try expectApproxEqAbs(@as(f80, 0.9691317730707771246), cos_f80(37.45), epsilon);
251 try expectApproxEqAbs(@as(f80, 0.4008006809354834001), cos_f80(89.123), epsilon);
238252}
239253
240254test "cos80.special" {
......@@ -243,13 +257,13 @@ test "cos80.special" {
243257
244258test "cos128.normal" {
245259 const epsilon = math.floatEps(f128);
246 try expectApproxEqAbs(@as(f128, 1.0), cosq(0.0), epsilon);
247 try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), cosq(0.2), epsilon);
248 try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), cosq(0.8923), epsilon);
249 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cosq(1.5), epsilon);
250 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cosq(-1.5), epsilon);
251 try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), cosq(37.45), epsilon);
252 try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), cosq(89.123), epsilon);
260 try expectApproxEqAbs(@as(f128, 1.0), cos_f128(0.0), epsilon);
261 try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), cos_f128(0.2), epsilon);
262 try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), cos_f128(0.8923), epsilon);
263 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cos_f128(1.5), epsilon);
264 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cos_f128(-1.5), epsilon);
265 try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), cos_f128(37.45), epsilon);
266 try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), cos_f128(89.123), epsilon);
253267}
254268
255269test "cos128.special" {
lib/compiler_rt/count0bits.zig+2-1
......@@ -1,6 +1,7 @@
11const builtin = @import("builtin");
22const std = @import("std");
3const symbol = @import("../compiler_rt.zig").symbol;
3const compiler_rt = @import("../compiler_rt.zig");
4const symbol = compiler_rt.symbol;
45
56comptime {
67 symbol(&__clzsi2, "__clzsi2");
lib/compiler_rt/divc3.zig+78-5
......@@ -7,12 +7,81 @@ const maxInt = std.math.maxInt;
77const minInt = std.math.minInt;
88const isFinite = std.math.isFinite;
99const 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
1279/// 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) {
14 var c = c_in;
15 var d = d_in;
80inline fn divc3(comptime T: type, lhs: Complex(T), rhs: Complex(T)) Complex(T) {
81 const a = lhs.real;
82 const b = lhs.imag;
83 var c = rhs.real;
84 var d = rhs.imag;
1685
1786 // logbw used to prevent under/over-flow
1887 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) {
2392 break :b logbw;
2493 } else 0;
2594 const denom = c * c + d * d;
26 const result = Complex(T){
95 const result: Complex(T) = .{
2796 .real = scalbn((a * c + b * d) / denom, -ilogbw),
2897 .imag = scalbn((b * c - a * d) / denom, -ilogbw),
2998 };
......@@ -58,3 +127,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) {
58127
59128 return result;
60129}
130
131test {
132 _ = @import("divc3_test.zig");
133}
lib/compiler_rt/divc3_test.zig+28-51
......@@ -2,76 +2,53 @@ const std = @import("std");
22const math = std.math;
33const expect = std.testing.expect;
44
5const Complex = @import("./mulc3.zig").Complex;
6const __divhc3 = @import("./divhc3.zig").__divhc3;
7const __divsc3 = @import("./divsc3.zig").__divsc3;
8const __divdc3 = @import("./divdc3.zig").__divdc3;
9const __divxc3 = @import("./divxc3.zig").__divxc3;
10const __divtc3 = @import("./divtc3.zig").__divtc3;
5const Complex = @import("../compiler_rt.zig").Complex;
6
7const impl = @import("divc3.zig");
8const div_cf16 = impl.div_cf16;
9const div_cf32 = impl.div_cf32;
10const div_cf64 = impl.div_cf64;
11const div_cf80 = impl.div_cf80;
12const div_cf128 = impl.div_cf128;
1113
1214test "divc3" {
13 try testDiv(f16, __divhc3);
14 try testDiv(f32, __divsc3);
15 try testDiv(f64, __divdc3);
16 try testDiv(f80, __divxc3);
17 try testDiv(f128, __divtc3);
15 try testDiv(f16, div_cf16);
16 try testDiv(f32, div_cf32);
17 try testDiv(f64, div_cf64);
18 try testDiv(f80, div_cf80);
19 try testDiv(f128, div_cf128);
1820}
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 {
2123 {
22 const a: T = 1.0;
23 const b: T = 0.0;
24 const c: T = -1.0;
25 const d: T = 0.0;
26
27 const result = f(a, b, c, d);
24 const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -1.0, .imag = 0.0 });
2825 try expect(result.real == -1.0);
29 try expect(result.imag == 0.0);
26 try expect(math.isNegativeZero(result.imag));
3027 }
3128 {
32 const a: T = 1.0;
33 const b: T = 0.0;
34 const c: T = -4.0;
35 const d: T = 0.0;
36
37 const result = f(a, b, c, d);
29 const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -4.0, .imag = 0.0 });
3830 try expect(result.real == -0.25);
39 try expect(result.imag == 0.0);
31 try expect(math.isNegativeZero(result.imag));
4032 }
4133 {
4234 // if the first operand is an infinity and the second operand is a finite number, then the
43 // result of the / operator is an infinity;
44 const a: T = -math.inf(T);
45 const b: T = 0.0;
46 const c: T = -4.0;
47 const d: T = 1.0;
48
49 const result = f(a, b, c, d);
50 try expect(result.real == math.inf(T));
51 try expect(result.imag == math.inf(T));
35 // resultult of the / operator is an infinity;
36 const result = f(.{ .real = -math.inf(T), .imag = 0.0 }, .{ .real = -4.0, .imag = 1.0 });
37 try expect(math.isPositiveInf(result.real));
38 try expect(math.isPositiveInf(result.imag));
5239 }
5340 {
5441 // if the first operand is a finite number and the second operand is an infinity, then the
5542 // result of the / operator is a zero;
56 const a: T = 17.2;
57 const b: T = 0.0;
58 const c: T = -math.inf(T);
59 const d: T = 0.0;
60
61 const result = f(a, b, c, d);
62 try expect(result.real == -0.0);
63 try expect(result.imag == 0.0);
43 const result = f(.{ .real = 17.2, .imag = 0.0 }, .{ .real = -math.inf(T), .imag = 0.0 });
44 try expect(math.isNegativeZero(result.real));
45 try expect(math.isNegativeZero(result.imag));
6446 }
6547 {
6648 // if the first operand is a nonzero finite number or an infinity and the second operand is
6749 // a zero, then the result of the / operator is an infinity
68 const a: T = 1.1;
69 const b: T = 0.1;
70 const c: T = 0.0;
71 const d: T = 0.0;
72
73 const result = f(a, b, c, d);
74 try expect(result.real == math.inf(T));
75 try expect(result.imag == math.inf(T));
50 const result = f(.{ .real = 1.1, .imag = 0.1 }, .{ .real = 0.0, .imag = 0.0 });
51 try expect(math.isPositiveInf(result.real));
52 try expect(math.isPositiveInf(result.imag));
7653 }
7754}
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 {
1717 }
1818}
1919
20pub fn __divdf3(a: f64, b: f64) callconv(.c) f64 {
21 return div(a, b);
20fn __divdf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi {
21 return compiler_rt.f64.toAbi(div_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)));
2222}
2323
2424fn __aeabi_ddiv(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 {
25 return div(a, b);
25 return div_f64(a, b);
2626}
2727
28inline fn div(a: f64, b: f64) f64 {
28pub fn div_f64(a: f64, b: f64) f64 {
2929 const Z = @Int(.unsigned, 64);
3030 const SignedZ = @Int(.signed, 64);
3131
lib/compiler_rt/divdf3_test.zig+2-2
......@@ -6,7 +6,7 @@ const std = @import("std");
66const math = std.math;
77const testing = std.testing;
88
9const __divdf3 = @import("divdf3.zig").__divdf3;
9const div_f64 = @import("divdf3.zig").div_f64;
1010
1111const nanRep: u64 = @as(u64, @bitCast(math.nan(f64)));
1212const infRep: u64 = @as(u64, @bitCast(math.inf(f64)));
......@@ -30,7 +30,7 @@ fn compareResultD(result: f64, expected: u64) bool {
3030}
3131
3232fn test__divdf3(a: f64, b: f64, expected: u64) !void {
33 const x = __divdf3(a, b);
33 const x = div_f64(a, b);
3434 const ret = compareResultD(x, expected);
3535 try testing.expect(ret == true);
3636}
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");
55
66const compiler_rt = @import("../compiler_rt.zig");
77const udivmod = @import("udivmodei4.zig").divmod;
8const symbol = @import("../compiler_rt.zig").symbol;
8const symbol = compiler_rt.symbol;
99
1010comptime {
1111 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;
99const normalize = compiler_rt.normalize;
1010
1111comptime {
12 symbol(&__divhf3, "__divhf3");
1213 if (compiler_rt.want_aeabi) {
1314 symbol(&__aeabi_fdiv, "__aeabi_fdiv");
1415 } else {
......@@ -16,15 +17,23 @@ comptime {
1617 }
1718}
1819
19pub fn __divsf3(a: f32, b: f32) callconv(.c) f32 {
20 return div(a, b);
20fn __divhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
21 return compiler_rt.f16.toAbi(div_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)));
22}
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)));
2130}
2231
2332fn __aeabi_fdiv(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 {
24 return div(a, b);
33 return div_f32(a, b);
2534}
2635
27inline fn div(a: f32, b: f32) f32 {
36pub fn div_f32(a: f32, b: f32) f32 {
2837 const Z = @Int(.unsigned, 32);
2938
3039 const significandBits = std.math.floatMantissaBits(f32);
lib/compiler_rt/divsf3_test.zig+2-2
......@@ -6,7 +6,7 @@ const std = @import("std");
66const math = std.math;
77const testing = std.testing;
88
9const __divsf3 = @import("divsf3.zig").__divsf3;
9const div_f32 = @import("divsf3.zig").div_f32;
1010
1111const nanRep: u32 = @as(u32, @bitCast(math.nan(f32)));
1212const infRep: u32 = @as(u32, @bitCast(math.inf(f32)));
......@@ -30,7 +30,7 @@ fn compareResultF(result: f32, expected: u32) bool {
3030}
3131
3232fn test__divsf3(a: f32, b: f32, expected: u32) !void {
33 const x = __divsf3(a, b);
33 const x = div_f32(a, b);
3434 const ret = compareResultF(x, expected);
3535 try testing.expect(ret == true);
3636}
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 {
1313 symbol(&_Qp_div, "_Qp_div");
1414 } else if (compiler_rt.want_sparc32_abi) {
1515 symbol(&__divtf3, "_Q_div");
16 } else {
17 symbol(&__divtf3, "__divtf3");
1618 }
17 symbol(&__divtf3, "__divtf3");
1819}
1920
20pub fn __divtf3(a: f128, b: f128) callconv(.c) f128 {
21 return div(a, b);
21fn __divtf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi {
22 return compiler_rt.f128.toAbi(div_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)));
2223}
2324
2425fn _Qp_div(c: *f128, a: *const f128, b: *const f128) callconv(.c) void {
25 c.* = div(a.*, b.*);
26 c.* = div_f128(a.*, b.*);
2627}
2728
28inline fn div(a: f128, b: f128) f128 {
29pub fn div_f128(a: f128, b: f128) f128 {
2930 const Z = @Int(.unsigned, 128);
3031
3132 const significandBits = std.math.floatMantissaBits(f128);
lib/compiler_rt/divtf3_test.zig+2-2
......@@ -2,7 +2,7 @@ const std = @import("std");
22const math = std.math;
33const testing = std.testing;
44
5const __divtf3 = @import("divtf3.zig").__divtf3;
5const div_f128 = @import("divtf3.zig").div_f128;
66
77fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {
88 const rep: u128 = @bitCast(result);
......@@ -24,7 +24,7 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {
2424}
2525
2626fn test__divtf3(a: f128, b: f128, expectedHi: u64, expectedLo: u64) !void {
27 const x = __divtf3(a, b);
27 const x = div_f128(a, b);
2828 const ret = compareResultLD(x, expectedHi, expectedLo);
2929 try testing.expect(ret == true);
3030}
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 {
1111 symbol(&__divxf3, "__divxf3");
1212}
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 {
1518 const T = f80;
1619 const Z = @Int(.unsigned, @bitSizeOf(T));
1720
lib/compiler_rt/divxf3_test.zig+3-3
......@@ -2,7 +2,7 @@ const std = @import("std");
22const math = std.math;
33const testing = std.testing;
44
5const __divxf3 = @import("divxf3.zig").__divxf3;
5const div_f80 = @import("divxf3.zig").div_f80;
66
77const nanRep: u80 = @as(u80, @bitCast(math.nan(f80)));
88const infRep: u80 = @as(u80, @bitCast(math.inf(f80)));
......@@ -19,14 +19,14 @@ fn compareResult(result: f80, expected: u80) bool {
1919}
2020
2121fn expect__divxf3_result(a: f80, b: f80, expected: u80) !void {
22 const x = __divxf3(a, b);
22 const x = div_f80(a, b);
2323 const ret = compareResult(x, expected);
2424 try testing.expect(ret == true);
2525}
2626
2727fn test__divxf3(a: f80, b: f80) !void {
2828 const integerBit = 1 << math.floatFractionalBits(f80);
29 const x = __divxf3(a, b);
29 const x = div_f80(a, b);
3030
3131 // Next float (assuming normal, non-zero result)
3232 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;
1414const expectEqual = std.testing.expectEqual;
1515
1616const compiler_rt = @import("../compiler_rt.zig");
17const symbol = @import("../compiler_rt.zig").symbol;
17const symbol = compiler_rt.symbol;
1818
1919comptime {
2020 symbol(&__exph, "__exph");
......@@ -28,12 +28,18 @@ comptime {
2828 symbol(&expl, "expl");
2929}
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 {
3235 // TODO: more efficient implementation
33 return @floatCast(expf(a));
36 return @floatCast(exp_f32(x));
3437}
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 {
3743 const half = [_]f32{ 0.5, -0.5 };
3844 const ln2hi = 6.9314575195e-1;
3945 const ln2lo = 1.4286067653e-6;
......@@ -108,7 +114,10 @@ pub fn expf(x_: f32) callconv(.c) f32 {
108114 }
109115}
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 {
112121 const half = [_]f64{ 0.5, -0.5 };
113122 const ln2hi: f64 = 6.93147180369123816490e-01;
114123 const ln2lo: f64 = 1.90821492927058770002e-10;
......@@ -189,116 +198,121 @@ pub fn exp(x_: f64) callconv(.c) f64 {
189198 }
190199}
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 {
193205 // TODO: more efficient implementation
194 return @floatCast(expq(a));
206 return @floatCast(exp_f128(x));
195207}
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
199214pub fn expl(x: c_longdouble) callconv(.c) c_longdouble {
200215 switch (@typeInfo(c_longdouble).float.bits) {
201 64 => return exp(x),
202 80 => return __expx(x),
203 128 => return expq(x),
204 else => @compileError("unreachable"),
216 64 => return exp_f64(x),
217 80 => return exp_f80(x),
218 128 => return exp_f128(x),
219 else => comptime unreachable,
205220 }
206221}
207222
208223test "expf() special" {
209 try expectEqual(expf(0.0), 1.0);
210 try expectEqual(expf(-0.0), 1.0);
211 try expectEqual(expf(1.0), math.e);
212 try expectEqual(expf(math.ln2), 2.0);
213 try expectEqual(expf(math.inf(f32)), math.inf(f32));
214 try expect(math.isPositiveZero(expf(-math.inf(f32))));
215 try expect(math.isNan(expf(math.nan(f32))));
216 try expect(math.isNan(expf(math.snan(f32))));
224 try expectEqual(exp_f32(0.0), 1.0);
225 try expectEqual(exp_f32(-0.0), 1.0);
226 try expectEqual(exp_f32(1.0), math.e);
227 try expectEqual(exp_f32(math.ln2), 2.0);
228 try expectEqual(exp_f32(math.inf(f32)), math.inf(f32));
229 try expect(math.isPositiveZero(exp_f32(-math.inf(f32))));
230 try expect(math.isNan(exp_f32(math.nan(f32))));
231 try expect(math.isNan(exp_f32(math.snan(f32))));
217232}
218233
219234test "expf() sanity" {
220 try expectEqual(expf(-0x1.0223a0p+3), 0x1.490320p-12);
221 try expectEqual(expf(0x1.161868p+2), 0x1.34712ap+6);
222 try expectEqual(expf(-0x1.0c34b4p+3), 0x1.e06b1ap-13);
223 try expectEqual(expf(-0x1.a206f0p+2), 0x1.7dd484p-10);
224 try expectEqual(expf(0x1.288bbcp+3), 0x1.4abc80p+13);
225 try expectEqual(expf(0x1.52efd0p-1), 0x1.f04a9cp+0);
226 try expectEqual(expf(-0x1.a05cc8p-2), 0x1.54f1e0p-1);
227 try expectEqual(expf(0x1.1f9efap-1), 0x1.c0f628p+0);
228 try expectEqual(expf(0x1.8c5db0p-1), 0x1.1599b2p+1);
229 try expectEqual(expf(-0x1.5b86eap-1), 0x1.03b572p-1);
230 try expectEqual(expf(-0x1.57f25cp+2), 0x1.2fbea2p-8);
231 try expectEqual(expf(0x1.c7d310p+3), 0x1.76eefp+20);
232 try expectEqual(expf(0x1.19be70p+4), 0x1.52d3dep+25);
233 try expectEqual(expf(-0x1.ab6d70p+3), 0x1.a88adep-20);
234 try expectEqual(expf(-0x1.5ac18ep+2), 0x1.22b328p-8);
235 try expectEqual(expf(-0x1.925982p-1), 0x1.d2acc0p-2);
236 try expectEqual(expf(0x1.7221cep+3), 0x1.9c2ceap+16);
237 try expectEqual(expf(0x1.11a0d4p+4), 0x1.980ee6p+24);
238 try expectEqual(expf(-0x1.ae41a2p+1), 0x1.1c28d0p-5);
239 try expectEqual(expf(-0x1.329154p+4), 0x1.47ef94p-28);
235 try expectEqual(exp_f32(-0x1.0223a0p+3), 0x1.490320p-12);
236 try expectEqual(exp_f32(0x1.161868p+2), 0x1.34712ap+6);
237 try expectEqual(exp_f32(-0x1.0c34b4p+3), 0x1.e06b1ap-13);
238 try expectEqual(exp_f32(-0x1.a206f0p+2), 0x1.7dd484p-10);
239 try expectEqual(exp_f32(0x1.288bbcp+3), 0x1.4abc80p+13);
240 try expectEqual(exp_f32(0x1.52efd0p-1), 0x1.f04a9cp+0);
241 try expectEqual(exp_f32(-0x1.a05cc8p-2), 0x1.54f1e0p-1);
242 try expectEqual(exp_f32(0x1.1f9efap-1), 0x1.c0f628p+0);
243 try expectEqual(exp_f32(0x1.8c5db0p-1), 0x1.1599b2p+1);
244 try expectEqual(exp_f32(-0x1.5b86eap-1), 0x1.03b572p-1);
245 try expectEqual(exp_f32(-0x1.57f25cp+2), 0x1.2fbea2p-8);
246 try expectEqual(exp_f32(0x1.c7d310p+3), 0x1.76eefp+20);
247 try expectEqual(exp_f32(0x1.19be70p+4), 0x1.52d3dep+25);
248 try expectEqual(exp_f32(-0x1.ab6d70p+3), 0x1.a88adep-20);
249 try expectEqual(exp_f32(-0x1.5ac18ep+2), 0x1.22b328p-8);
250 try expectEqual(exp_f32(-0x1.925982p-1), 0x1.d2acc0p-2);
251 try expectEqual(exp_f32(0x1.7221cep+3), 0x1.9c2ceap+16);
252 try expectEqual(exp_f32(0x1.11a0d4p+4), 0x1.980ee6p+24);
253 try expectEqual(exp_f32(-0x1.ae41a2p+1), 0x1.1c28d0p-5);
254 try expectEqual(exp_f32(-0x1.329154p+4), 0x1.47ef94p-28);
240255}
241256
242257test "expf() boundary" {
243 try expectEqual(expf(0x1.62e42ep+6), 0x1.ffff08p+127); // The last value before the result gets infinite
244 try expectEqual(expf(0x1.62e430p+6), math.inf(f32)); // The first value that gives inf
245 try expectEqual(expf(0x1.fffffep+127), math.inf(f32)); // Max input value
246 try expectEqual(expf(0x1p-149), 1.0); // Min positive input value
247 try expectEqual(expf(-0x1p-149), 1.0); // Min negative input value
248 try expectEqual(expf(0x1p-126), 1.0); // First positive subnormal input
249 try expectEqual(expf(-0x1p-126), 1.0); // First negative subnormal input
250 try expectEqual(expf(-0x1.9fe368p+6), 0x1p-149); // The last value before the result flushes to zero
251 try expectEqual(expf(-0x1.9fe36ap+6), 0.0); // The first value at which the result flushes to zero
252 try expectEqual(expf(-0x1.5d589ep+6), 0x1.00004cp-126); // The last value before the result flushes to subnormal
253 try expectEqual(expf(-0x1.5d58a0p+6), 0x1.ffff98p-127); // The first value for which the result flushes to subnormal
254
258 try expectEqual(exp_f32(0x1.62e42ep+6), 0x1.ffff08p+127); // The last value before the result gets infinite
259 try expectEqual(exp_f32(0x1.62e430p+6), math.inf(f32)); // The first value that gives inf
260 try expectEqual(exp_f32(0x1.fffffep+127), math.inf(f32)); // Max input value
261 try expectEqual(exp_f32(0x1p-149), 1.0); // Min positive input value
262 try expectEqual(exp_f32(-0x1p-149), 1.0); // Min negative input value
263 try expectEqual(exp_f32(0x1p-126), 1.0); // First positive subnormal input
264 try expectEqual(exp_f32(-0x1p-126), 1.0); // First negative subnormal input
265 try expectEqual(exp_f32(-0x1.9fe368p+6), 0x1p-149); // The last value before the result flushes to zero
266 try expectEqual(exp_f32(-0x1.9fe36ap+6), 0.0); // The first value at which the result flushes to zero
267 try expectEqual(exp_f32(-0x1.5d589ep+6), 0x1.00004cp-126); // The last value before the result flushes to subnormal
268 try expectEqual(exp_f32(-0x1.5d58a0p+6), 0x1.ffff98p-127); // The first value for which the result flushes to subnormal
255269}
256270
257271test "exp() special" {
258 try expectEqual(exp(0.0), 1.0);
259 try expectEqual(exp(-0.0), 1.0);
272 try expectEqual(exp_f64(0.0), 1.0);
273 try expectEqual(exp_f64(-0.0), 1.0);
260274 // TODO: Accuracy error - off in the last bit in 64-bit, disagreeing with GCC
261275 // try expectEqual(exp(1.0), math.e);
262 try expectEqual(exp(math.ln2), 2.0);
263 try expectEqual(exp(math.inf(f64)), math.inf(f64));
264 try expect(math.isPositiveZero(exp(-math.inf(f64))));
265 try expect(math.isNan(exp(math.nan(f64))));
266 try expect(math.isNan(exp(math.snan(f64))));
276 try expectEqual(exp_f64(math.ln2), 2.0);
277 try expectEqual(exp_f64(math.inf(f64)), math.inf(f64));
278 try expect(math.isPositiveZero(exp_f64(-math.inf(f64))));
279 try expect(math.isNan(exp_f64(math.nan(f64))));
280 try expect(math.isNan(exp_f64(math.snan(f64))));
267281}
268282
269283test "exp() sanity" {
270 try expectEqual(exp(-0x1.02239f3c6a8f1p+3), 0x1.490327ea61235p-12);
271 try expectEqual(exp(0x1.161868e18bc67p+2), 0x1.34712ed238c04p+6);
272 try expectEqual(exp(-0x1.0c34b3e01e6e7p+3), 0x1.e06b1b6c18e64p-13);
273 try expectEqual(exp(-0x1.a206f0a19dcc4p+2), 0x1.7dd47f810e68cp-10);
274 try expectEqual(exp(0x1.288bbb0d6a1e6p+3), 0x1.4abc77496e07ep+13);
275 try expectEqual(exp(0x1.52efd0cd80497p-1), 0x1.f04a9c1080500p+0);
276 try expectEqual(exp(-0x1.a05cc754481d1p-2), 0x1.54f1e0fd3ea0dp-1);
277 try expectEqual(exp(0x1.1f9ef934745cbp-1), 0x1.c0f6266a6a547p+0);
278 try expectEqual(exp(0x1.8c5db097f7442p-1), 0x1.1599b1d4a25fbp+1);
279 try expectEqual(exp(-0x1.5b86ea8118a0ep-1), 0x1.03b5728a00229p-1);
280 try expectEqual(exp(-0x1.57f25b2b5006dp+2), 0x1.2fbea6a01cab9p-8);
281 try expectEqual(exp(0x1.c7d30fb825911p+3), 0x1.76eeed45a0634p+20);
282 try expectEqual(exp(0x1.19be709de7505p+4), 0x1.52d3eb7be6844p+25);
283 try expectEqual(exp(-0x1.ab6d6fba96889p+3), 0x1.a88ae12f985d6p-20);
284 try expectEqual(exp(-0x1.5ac18e27084ddp+2), 0x1.22b327da9cca6p-8);
285 try expectEqual(exp(-0x1.925981b093c41p-1), 0x1.d2acc046b55f7p-2);
286 try expectEqual(exp(0x1.7221cd18455f5p+3), 0x1.9c2cde8699cfbp+16);
287 try expectEqual(exp(0x1.11a0d4a51b239p+4), 0x1.980ef612ff182p+24);
288 try expectEqual(exp(-0x1.ae41a1079de4dp+1), 0x1.1c28d16bb3222p-5);
289 try expectEqual(exp(-0x1.329153103b871p+4), 0x1.47efa6ddd0d22p-28);
284 try expectEqual(exp_f64(-0x1.02239f3c6a8f1p+3), 0x1.490327ea61235p-12);
285 try expectEqual(exp_f64(0x1.161868e18bc67p+2), 0x1.34712ed238c04p+6);
286 try expectEqual(exp_f64(-0x1.0c34b3e01e6e7p+3), 0x1.e06b1b6c18e64p-13);
287 try expectEqual(exp_f64(-0x1.a206f0a19dcc4p+2), 0x1.7dd47f810e68cp-10);
288 try expectEqual(exp_f64(0x1.288bbb0d6a1e6p+3), 0x1.4abc77496e07ep+13);
289 try expectEqual(exp_f64(0x1.52efd0cd80497p-1), 0x1.f04a9c1080500p+0);
290 try expectEqual(exp_f64(-0x1.a05cc754481d1p-2), 0x1.54f1e0fd3ea0dp-1);
291 try expectEqual(exp_f64(0x1.1f9ef934745cbp-1), 0x1.c0f6266a6a547p+0);
292 try expectEqual(exp_f64(0x1.8c5db097f7442p-1), 0x1.1599b1d4a25fbp+1);
293 try expectEqual(exp_f64(-0x1.5b86ea8118a0ep-1), 0x1.03b5728a00229p-1);
294 try expectEqual(exp_f64(-0x1.57f25b2b5006dp+2), 0x1.2fbea6a01cab9p-8);
295 try expectEqual(exp_f64(0x1.c7d30fb825911p+3), 0x1.76eeed45a0634p+20);
296 try expectEqual(exp_f64(0x1.19be709de7505p+4), 0x1.52d3eb7be6844p+25);
297 try expectEqual(exp_f64(-0x1.ab6d6fba96889p+3), 0x1.a88ae12f985d6p-20);
298 try expectEqual(exp_f64(-0x1.5ac18e27084ddp+2), 0x1.22b327da9cca6p-8);
299 try expectEqual(exp_f64(-0x1.925981b093c41p-1), 0x1.d2acc046b55f7p-2);
300 try expectEqual(exp_f64(0x1.7221cd18455f5p+3), 0x1.9c2cde8699cfbp+16);
301 try expectEqual(exp_f64(0x1.11a0d4a51b239p+4), 0x1.980ef612ff182p+24);
302 try expectEqual(exp_f64(-0x1.ae41a1079de4dp+1), 0x1.1c28d16bb3222p-5);
303 try expectEqual(exp_f64(-0x1.329153103b871p+4), 0x1.47efa6ddd0d22p-28);
290304}
291305
292306test "exp() boundary" {
293 try expectEqual(exp(0x1.62e42fefa39efp+9), 0x1.fffffffffff2ap+1023); // The last value before the result gets infinite
294 try expectEqual(exp(0x1.62e42fefa39f0p+9), math.inf(f64)); // The first value that gives inf
295 try expectEqual(exp(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value
296 try expectEqual(exp(0x1p-1074), 1.0); // Min positive input value
297 try expectEqual(exp(-0x1p-1074), 1.0); // Min negative input value
298 try expectEqual(exp(0x1p-1022), 1.0); // First positive subnormal input
299 try expectEqual(exp(-0x1p-1022), 1.0); // First negative subnormal input
300 try expectEqual(exp(-0x1.74910d52d3051p+9), 0x1p-1074); // The last value before the result flushes to zero
301 try expectEqual(exp(-0x1.74910d52d3052p+9), 0.0); // The first value at which the result flushes to zero
302 try expectEqual(exp(-0x1.6232bdd7abcd2p+9), 0x1.000000000007cp-1022); // The last value before the result flushes to subnormal
303 try expectEqual(exp(-0x1.6232bdd7abcd3p+9), 0x1.ffffffffffcf8p-1023); // The first value for which the result flushes to subnormal
307 try expectEqual(exp_f64(0x1.62e42fefa39efp+9), 0x1.fffffffffff2ap+1023); // The last value before the result gets infinite
308 try expectEqual(exp_f64(0x1.62e42fefa39f0p+9), math.inf(f64)); // The first value that gives inf
309 try expectEqual(exp_f64(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value
310 try expectEqual(exp_f64(0x1p-1074), 1.0); // Min positive input value
311 try expectEqual(exp_f64(-0x1p-1074), 1.0); // Min negative input value
312 try expectEqual(exp_f64(0x1p-1022), 1.0); // First positive subnormal input
313 try expectEqual(exp_f64(-0x1p-1022), 1.0); // First negative subnormal input
314 try expectEqual(exp_f64(-0x1.74910d52d3051p+9), 0x1p-1074); // The last value before the result flushes to zero
315 try expectEqual(exp_f64(-0x1.74910d52d3052p+9), 0.0); // The first value at which the result flushes to zero
316 try expectEqual(exp_f64(-0x1.6232bdd7abcd2p+9), 0x1.000000000007cp-1022); // The last value before the result flushes to subnormal
317 try expectEqual(exp_f64(-0x1.6232bdd7abcd3p+9), 0x1.ffffffffffcf8p-1023); // The first value for which the result flushes to subnormal
304318}
lib/compiler_rt/exp2.zig+84-69
......@@ -26,12 +26,18 @@ comptime {
2626 symbol(&exp2l, "exp2l");
2727}
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 {
3033 // TODO: more efficient implementation
31 return @floatCast(exp2f(x));
34 return @floatCast(exp2_f32(x));
3235}
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 {
3541 const tblsiz: u32 = @intCast(exp2ft.len);
3642 const redux: f32 = 0x1.8p23 / @as(f32, @floatFromInt(tblsiz));
3743 const P1: f32 = 0x1.62e430p-1;
......@@ -88,7 +94,10 @@ pub fn exp2f(x: f32) callconv(.c) f32 {
8894 return @floatCast(r * uk);
8995}
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 {
92101 const tblsiz: u32 = @intCast(exp2dt.len / 2);
93102 const redux: f64 = 0x1.8p52 / @as(f64, @floatFromInt(tblsiz));
94103 const P1: f64 = 0x1.62e42fefa39efp-1;
......@@ -156,19 +165,25 @@ pub fn exp2(x: f64) callconv(.c) f64 {
156165 return math.scalbn(r, ik);
157166}
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 {
160172 // TODO: more efficient implementation
161 return @floatCast(exp2q(x));
173 return @floatCast(exp2_f128(x));
162174}
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
166181pub fn exp2l(x: c_longdouble) callconv(.c) c_longdouble {
167182 switch (@typeInfo(c_longdouble).float.bits) {
168 64 => return exp2(x),
169 80 => return __exp2x(x),
170 128 => return exp2q(x),
171 else => @compileError("unreachable"),
183 64 => return exp2_f64(x),
184 80 => return exp2_f80(x),
185 128 => return exp2_f128(x),
186 else => comptime unreachable,
172187 }
173188}
174189
......@@ -452,77 +467,77 @@ const exp2dt = [_]f64{
452467};
453468
454469test "exp2f() special" {
455 try expectEqual(exp2f(0.0), 1.0);
456 try expectEqual(exp2f(-0.0), 1.0);
457 try expectEqual(exp2f(1.0), 2.0);
458 try expectEqual(exp2f(-1.0), 0.5);
459 try expectEqual(exp2f(math.inf(f32)), math.inf(f32));
460 try expect(math.isPositiveZero(exp2f(-math.inf(f32))));
461 try expect(math.isNan(exp2f(math.nan(f32))));
462 try expect(math.isNan(exp2f(math.snan(f32))));
470 try expectEqual(exp2_f32(0.0), 1.0);
471 try expectEqual(exp2_f32(-0.0), 1.0);
472 try expectEqual(exp2_f32(1.0), 2.0);
473 try expectEqual(exp2_f32(-1.0), 0.5);
474 try expectEqual(exp2_f32(math.inf(f32)), math.inf(f32));
475 try expect(math.isPositiveZero(exp2_f32(-math.inf(f32))));
476 try expect(math.isNan(exp2_f32(math.nan(f32))));
477 try expect(math.isNan(exp2_f32(math.snan(f32))));
463478}
464479
465480test "exp2f() sanity" {
466 try expectEqual(exp2f(-0x1.0223a0p+3), 0x1.e8d134p-9);
467 try expectEqual(exp2f(0x1.161868p+2), 0x1.453672p+4);
468 try expectEqual(exp2f(-0x1.0c34b4p+3), 0x1.890ca0p-9);
469 try expectEqual(exp2f(-0x1.a206f0p+2), 0x1.622d4ep-7);
470 try expectEqual(exp2f(0x1.288bbcp+3), 0x1.340ecep+9);
471 try expectEqual(exp2f(0x1.52efd0p-1), 0x1.950eeep+0);
472 try expectEqual(exp2f(-0x1.a05cc8p-2), 0x1.824056p-1);
473 try expectEqual(exp2f(0x1.1f9efap-1), 0x1.79dfa2p+0);
474 try expectEqual(exp2f(0x1.8c5db0p-1), 0x1.b5ceacp+0);
475 try expectEqual(exp2f(-0x1.5b86eap-1), 0x1.3fd8bap-1);
481 try expectEqual(exp2_f32(-0x1.0223a0p+3), 0x1.e8d134p-9);
482 try expectEqual(exp2_f32(0x1.161868p+2), 0x1.453672p+4);
483 try expectEqual(exp2_f32(-0x1.0c34b4p+3), 0x1.890ca0p-9);
484 try expectEqual(exp2_f32(-0x1.a206f0p+2), 0x1.622d4ep-7);
485 try expectEqual(exp2_f32(0x1.288bbcp+3), 0x1.340ecep+9);
486 try expectEqual(exp2_f32(0x1.52efd0p-1), 0x1.950eeep+0);
487 try expectEqual(exp2_f32(-0x1.a05cc8p-2), 0x1.824056p-1);
488 try expectEqual(exp2_f32(0x1.1f9efap-1), 0x1.79dfa2p+0);
489 try expectEqual(exp2_f32(0x1.8c5db0p-1), 0x1.b5ceacp+0);
490 try expectEqual(exp2_f32(-0x1.5b86eap-1), 0x1.3fd8bap-1);
476491}
477492
478493test "exp2f() boundary" {
479 try expectEqual(exp2f(0x1.fffffep+6), 0x1.ffff4ep+127); // The last value before the result gets infinite
480 try expectEqual(exp2f(0x1p+7), math.inf(f32)); // The first value that gives infinite result
481 try expectEqual(exp2f(-0x1.2bccccp+7), 0x1p-149); // The last value before the result flushes to zero
482 try expectEqual(exp2f(-0x1.2cp+7), 0); // The first value at which the result flushes to zero
483 try expectEqual(exp2f(-0x1.f8p+6), 0x1p-126); // The last value before the result flushes to subnormal
484 try expectEqual(exp2f(-0x1.f80002p+6), 0x1.ffff50p-127); // The first value for which the result flushes to subnormal
485 try expectEqual(exp2f(0x1.fffffep+127), math.inf(f32)); // Max input value
486 try expectEqual(exp2f(0x1p-149), 1); // Min positive input value
487 try expectEqual(exp2f(-0x1p-149), 1); // Min negative input value
488 try expectEqual(exp2f(0x1p-126), 1); // First positive subnormal input
489 try expectEqual(exp2f(-0x1p-126), 1); // First negative subnormal input
494 try expectEqual(exp2_f32(0x1.fffffep+6), 0x1.ffff4ep+127); // The last value before the result gets infinite
495 try expectEqual(exp2_f32(0x1p+7), math.inf(f32)); // The first value that gives infinite result
496 try expectEqual(exp2_f32(-0x1.2bccccp+7), 0x1p-149); // The last value before the result flushes to zero
497 try expectEqual(exp2_f32(-0x1.2cp+7), 0); // The first value at which the result flushes to zero
498 try expectEqual(exp2_f32(-0x1.f8p+6), 0x1p-126); // The last value before the result flushes to subnormal
499 try expectEqual(exp2_f32(-0x1.f80002p+6), 0x1.ffff50p-127); // The first value for which the result flushes to subnormal
500 try expectEqual(exp2_f32(0x1.fffffep+127), math.inf(f32)); // Max input value
501 try expectEqual(exp2_f32(0x1p-149), 1); // Min positive input value
502 try expectEqual(exp2_f32(-0x1p-149), 1); // Min negative input value
503 try expectEqual(exp2_f32(0x1p-126), 1); // First positive subnormal input
504 try expectEqual(exp2_f32(-0x1p-126), 1); // First negative subnormal input
490505}
491506
492507test "exp2() special" {
493 try expectEqual(exp2(0.0), 1.0);
494 try expectEqual(exp2(-0.0), 1.0);
495 try expectEqual(exp2(1.0), 2.0);
496 try expectEqual(exp2(-1.0), 0.5);
497 try expectEqual(exp2(math.inf(f64)), math.inf(f64));
498 try expect(math.isPositiveZero(exp2(-math.inf(f64))));
499 try expect(math.isNan(exp2(math.nan(f64))));
500 try expect(math.isNan(exp2(math.snan(f64))));
508 try expectEqual(exp2_f64(0.0), 1.0);
509 try expectEqual(exp2_f64(-0.0), 1.0);
510 try expectEqual(exp2_f64(1.0), 2.0);
511 try expectEqual(exp2_f64(-1.0), 0.5);
512 try expectEqual(exp2_f64(math.inf(f64)), math.inf(f64));
513 try expect(math.isPositiveZero(exp2_f64(-math.inf(f64))));
514 try expect(math.isNan(exp2_f64(math.nan(f64))));
515 try expect(math.isNan(exp2_f64(math.snan(f64))));
501516}
502517
503518test "exp2() sanity" {
504 try expectEqual(exp2(-0x1.02239f3c6a8f1p+3), 0x1.e8d13c396f452p-9);
505 try expectEqual(exp2(0x1.161868e18bc67p+2), 0x1.4536746bb6f12p+4);
506 try expectEqual(exp2(-0x1.0c34b3e01e6e7p+3), 0x1.890ca0c00b9a2p-9);
507 try expectEqual(exp2(-0x1.a206f0a19dcc4p+2), 0x1.622d4b0ebc6c1p-7);
508 try expectEqual(exp2(0x1.288bbb0d6a1e6p+3), 0x1.340ec7f3e607ep+9);
509 try expectEqual(exp2(0x1.52efd0cd80497p-1), 0x1.950eef4bc5451p+0);
510 try expectEqual(exp2(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1);
511 try expectEqual(exp2(0x1.1f9ef934745cbp-1), 0x1.79dfa14ab121ep+0);
512 try expectEqual(exp2(0x1.8c5db097f7442p-1), 0x1.b5cead2247372p+0);
513 try expectEqual(exp2(-0x1.5b86ea8118a0ep-1), 0x1.3fd8ba33216b9p-1);
519 try expectEqual(exp2_f64(-0x1.02239f3c6a8f1p+3), 0x1.e8d13c396f452p-9);
520 try expectEqual(exp2_f64(0x1.161868e18bc67p+2), 0x1.4536746bb6f12p+4);
521 try expectEqual(exp2_f64(-0x1.0c34b3e01e6e7p+3), 0x1.890ca0c00b9a2p-9);
522 try expectEqual(exp2_f64(-0x1.a206f0a19dcc4p+2), 0x1.622d4b0ebc6c1p-7);
523 try expectEqual(exp2_f64(0x1.288bbb0d6a1e6p+3), 0x1.340ec7f3e607ep+9);
524 try expectEqual(exp2_f64(0x1.52efd0cd80497p-1), 0x1.950eef4bc5451p+0);
525 try expectEqual(exp2_f64(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1);
526 try expectEqual(exp2_f64(0x1.1f9ef934745cbp-1), 0x1.79dfa14ab121ep+0);
527 try expectEqual(exp2_f64(0x1.8c5db097f7442p-1), 0x1.b5cead2247372p+0);
528 try expectEqual(exp2_f64(-0x1.5b86ea8118a0ep-1), 0x1.3fd8ba33216b9p-1);
514529}
515530
516531test "exp2() boundary" {
517 try expectEqual(exp2(0x1.fffffffffffffp+9), 0x1.ffffffffffd3ap+1023); // The last value before the result gets infinite
518 try expectEqual(exp2(0x1p+10), math.inf(f64)); // The first value that gives infinite result
519 try expectEqual(exp2(-0x1.0cbffffffffffp+10), 0x1p-1074); // The last value before the result flushes to zero
520 try expectEqual(exp2(-0x1.0ccp+10), 0); // The first value at which the result flushes to zero
521 try expectEqual(exp2(-0x1.ffp+9), 0x1p-1022); // The last value before the result flushes to subnormal
522 try expectEqual(exp2(-0x1.ff00000000001p+9), 0x1.ffffffffffd3ap-1023); // The first value for which the result flushes to subnormal
523 try expectEqual(exp2(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value
524 try expectEqual(exp2(0x1p-1074), 1); // Min positive input value
525 try expectEqual(exp2(-0x1p-1074), 1); // Min negative input value
526 try expectEqual(exp2(0x1p-1022), 1); // First positive subnormal input
527 try expectEqual(exp2(-0x1p-1022), 1); // First negative subnormal input
532 try expectEqual(exp2_f64(0x1.fffffffffffffp+9), 0x1.ffffffffffd3ap+1023); // The last value before the result gets infinite
533 try expectEqual(exp2_f64(0x1p+10), math.inf(f64)); // The first value that gives infinite result
534 try expectEqual(exp2_f64(-0x1.0cbffffffffffp+10), 0x1p-1074); // The last value before the result flushes to zero
535 try expectEqual(exp2_f64(-0x1.0ccp+10), 0); // The first value at which the result flushes to zero
536 try expectEqual(exp2_f64(-0x1.ffp+9), 0x1p-1022); // The last value before the result flushes to subnormal
537 try expectEqual(exp2_f64(-0x1.ff00000000001p+9), 0x1.ffffffffffd3ap-1023); // The first value for which the result flushes to subnormal
538 try expectEqual(exp2_f64(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value
539 try expectEqual(exp2_f64(0x1p-1074), 1); // Min positive input value
540 try expectEqual(exp2_f64(-0x1p-1074), 1); // Min negative input value
541 try expectEqual(exp2_f64(0x1p-1022), 1); // First positive subnormal input
542 try expectEqual(exp2_f64(-0x1p-1022), 1); // First negative subnormal input
528543}
lib/compiler_rt/exp_f128.zig+2-2
......@@ -26,7 +26,7 @@ const exp_f128 = @This();
2626const std = @import("std");
2727const math = std.math;
2828
29pub fn exp(x: f128) callconv(.c) f128 {
29pub fn exp(x: f128) f128 {
3030 if (!math.isFinite(x)) {
3131 if (math.isNan(x)) {
3232 if (math.isSignalNan(x)) math.raiseInvalid();
......@@ -91,7 +91,7 @@ fn expPoly(r_hi: f128, r_lo: f128) f128 {
9191}
9292
9393/// Computes 2^x
94pub fn exp2(x: f128) callconv(.c) f128 {
94pub fn exp2(x: f128) f128 {
9595 if (!math.isFinite(x)) {
9696 if (math.isNan(x)) {
9797 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 @@
11const std = @import("std");
22
3pub inline fn extendf(
4 comptime dst_t: type,
5 comptime src_t: type,
6 a: @Int(.unsigned, @typeInfo(src_t).float.bits),
7) dst_t {
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_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 {
8173 const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits);
9174 const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits);
10175 const srcSigBits = std.math.floatMantissaBits(src_t);
......@@ -31,6 +196,7 @@ pub inline fn extendf(
31196
32197 const dstMinNormal: dst_rep_t = @as(dst_rep_t, 1) << dstSigBits;
33198
199 const a: src_rep_t = @bitCast(f);
34200 // Break a into a sign and representation of the absolute value
35201 const aRep: src_rep_t = @bitCast(a);
36202 const aAbs: src_rep_t = aRep & srcAbsMask;
......@@ -66,11 +232,11 @@ pub inline fn extendf(
66232 }
67233
68234 // 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);
70236 return @bitCast(result);
71237}
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 {
74240 const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits);
75241 const src_sig_bits = std.math.floatMantissaBits(src_t);
76242 const dst_int_bit = 0x8000000000000000;
......@@ -92,6 +258,7 @@ pub inline fn extend_f80(comptime src_t: type, a: @Int(.unsigned, @typeInfo(src_
92258
93259 var dst: std.math.F80 = undefined;
94260
261 const a: src_rep_t = @bitCast(f);
95262 // Break a into a sign and representation of the absolute value
96263 const a_abs = a & src_abs_mask;
97264 const sign: u16 = if (a & src_sign_mask != 0) 0x8000 else 0;
lib/compiler_rt/extendf_test.zig+94-95
......@@ -1,31 +1,37 @@
11const builtin = @import("builtin");
2
32const 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;
7const __extendhftf2 = @import("extendhftf2.zig").__extendhftf2;
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;
16const f80_floatCast_f64 = impl.f80_floatCast_f64;
17const f128_floatCast_f64 = impl.f128_floatCast_f64;
1218
13fn test__extenddfxf2(a: f64, expected: u80) !void {
14 const x = __extenddfxf2(a);
19const f128_floatCast_f80 = impl.f128_floatCast_f80;
20
21fn test_f80_floatCast_f64(a: f64, expected: u80) !void {
22 const x = f80_floatCast_f64(a);
1523
1624 const rep: u80 = @bitCast(x);
1725 if (rep == expected)
1826 return;
19
2027 // 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))
2229 return;
23
24 @panic("__extenddfxf2 test failure");
30 return error.TestFailure;
2531}
2632
27fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void {
28 const x = __extenddftf2(a);
33fn test_f128_floatCast_f64(a: f64, expected_hi: u64, expected_lo: u64) !void {
34 const x = f128_floatCast_f64(a);
2935
3036 const rep: u128 = @bitCast(x);
3137 const hi: u64 = @intCast(rep >> 64);
......@@ -33,7 +39,6 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void {
3339
3440 if (hi == expected_hi and lo == expected_lo)
3541 return;
36
3742 // test other possible NaN representation(signal NaN)
3843 if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) {
3944 if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and
......@@ -42,12 +47,11 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void {
4247 return;
4348 }
4449 }
45
46 @panic("__extenddftf2 test failure");
50 return error.TestFailure;
4751}
4852
49fn test__extendhfsf2(a: u16, expected: u32) !void {
50 const x = __extendhfsf2(@as(F16T(f32), @bitCast(a)));
53fn test_f32_floatCast_f16(a: u16, expected: u32) !void {
54 const x = f32_floatCast_f16(@bitCast(a));
5155 const rep: u32 = @bitCast(x);
5256
5357 if (rep == expected) {
......@@ -58,12 +62,11 @@ fn test__extendhfsf2(a: u16, expected: u32) !void {
5862 return;
5963 }
6064 }
61
6265 return error.TestFailure;
6366}
6467
65fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void {
66 const x = __extendsftf2(a);
68fn test_f128_floatCast_f32(a: f32, expected_hi: u64, expected_lo: u64) !void {
69 const x = f128_floatCast_f32(a);
6770
6871 const rep: u128 = @bitCast(x);
6972 const hi: u64 = @intCast(rep >> 64);
......@@ -71,7 +74,6 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void {
7174
7275 if (hi == expected_hi and lo == expected_lo)
7376 return;
74
7577 // test other possible NaN representation(signal NaN)
7678 if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) {
7779 if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and
......@@ -80,111 +82,108 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void {
8082 return;
8183 }
8284 }
83
8485 return error.TestFailure;
8586}
8687
87test "extenddfxf2" {
88test f80_floatCast_f64 {
8889 // qNaN
89 try test__extenddfxf2(makeQNaN64(), 0x7fffc000000000000000);
90 try test_f80_floatCast_f64(makeQNaN64(), 0x7fffc000000000000000);
9091
9192 // NaN
92 try test__extenddfxf2(makeNaN64(0x7100000000000), 0x7fffe080000000000000);
93 try test_f80_floatCast_f64(makeNaN64(0x7100000000000), 0x7fffe080000000000000);
9394 // This is bad?
9495
9596 // inf
96 try test__extenddfxf2(makeInf64(), 0x7fff8000000000000000);
97 try test_f80_floatCast_f64(makeInf64(), 0x7fff8000000000000000);
9798
9899 // 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
109110 // subnormal
110 try test__extenddfxf2(0x1.8000000000001p-1022, 0x3c01c000000000000800);
111 try test__extenddfxf2(0x1.8000000000002p-1023, 0x3c00c000000000001000);
111 try test_f80_floatCast_f64(0x1.8000000000001p-1022, 0x3c01c000000000000800);
112 try test_f80_floatCast_f64(0x1.8000000000002p-1023, 0x3c00c000000000001000);
112113}
113114
114test "extenddftf2" {
115 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC()) return error.SkipZigTest;
116
115test f128_floatCast_f64 {
117116 // qNaN
118 try test__extenddftf2(makeQNaN64(), 0x7fff800000000000, 0x0);
117 try test_f128_floatCast_f64(makeQNaN64(), 0x7fff800000000000, 0x0);
119118
120119 // NaN
121 try test__extenddftf2(makeNaN64(0x7100000000000), 0x7fff710000000000, 0x0);
120 try test_f128_floatCast_f64(makeNaN64(0x7100000000000), 0x7fff710000000000, 0x0);
122121
123122 // inf
124 try test__extenddftf2(makeInf64(), 0x7fff000000000000, 0x0);
123 try test_f128_floatCast_f64(makeInf64(), 0x7fff000000000000, 0x0);
125124
126125 // 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
137136 // subnormal
138 try test__extenddftf2(0x1.8p-1022, 0x3c01800000000000, 0x0);
139 try test__extenddftf2(0x1.8p-1023, 0x3c00800000000000, 0x0);
137 try test_f128_floatCast_f64(0x1.8p-1022, 0x3c01800000000000, 0x0);
138 try test_f128_floatCast_f64(0x1.8p-1023, 0x3c00800000000000, 0x0);
140139}
141140
142test "extendhfsf2" {
143 try test__extendhfsf2(0x7e00, 0x7fc00000); // qNaN
144 try test__extendhfsf2(0x7f00, 0x7fe00000); // sNaN
141test f32_floatCast_f16 {
142 try test_f32_floatCast_f16(0x7e00, 0x7fc00000); // qNaN
143 try test_f32_floatCast_f16(0x7f00, 0x7fe00000); // sNaN
145144 // On x86 the NaN becomes quiet because the return is pushed on the x87
146145 // stack due to ABI requirements
147146 if (builtin.target.cpu.arch != .x86 and builtin.target.os.tag == .windows)
148 try test__extendhfsf2(0x7c01, 0x7f802000); // sNaN
147 try test_f32_floatCast_f16(0x7c01, 0x7f802000); // sNaN
149148
150 try test__extendhfsf2(0, 0); // 0
151 try test__extendhfsf2(0x8000, 0x80000000); // -0
149 try test_f32_floatCast_f16(0, 0); // 0
150 try test_f32_floatCast_f16(0x8000, 0x80000000); // -0
152151
153 try test__extendhfsf2(0x7c00, 0x7f800000); // inf
154 try test__extendhfsf2(0xfc00, 0xff800000); // -inf
152 try test_f32_floatCast_f16(0x7c00, 0x7f800000); // inf
153 try test_f32_floatCast_f16(0xfc00, 0xff800000); // -inf
155154
156 try test__extendhfsf2(0x0001, 0x33800000); // denormal (min), 2**-24
157 try test__extendhfsf2(0x8001, 0xb3800000); // denormal (min), -2**-24
155 try test_f32_floatCast_f16(0x0001, 0x33800000); // denormal (min), 2**-24
156 try test_f32_floatCast_f16(0x8001, 0xb3800000); // denormal (min), -2**-24
158157
159 try test__extendhfsf2(0x03ff, 0x387fc000); // denormal (max), 2**-14 - 2**-24
160 try test__extendhfsf2(0x83ff, 0xb87fc000); // denormal (max), -2**-14 + 2**-24
158 try test_f32_floatCast_f16(0x03ff, 0x387fc000); // denormal (max), 2**-14 - 2**-24
159 try test_f32_floatCast_f16(0x83ff, 0xb87fc000); // denormal (max), -2**-14 + 2**-24
161160
162 try test__extendhfsf2(0x0400, 0x38800000); // normal (min), 2**-14
163 try test__extendhfsf2(0x8400, 0xb8800000); // normal (min), -2**-14
161 try test_f32_floatCast_f16(0x0400, 0x38800000); // normal (min), 2**-14
162 try test_f32_floatCast_f16(0x8400, 0xb8800000); // normal (min), -2**-14
164163
165 try test__extendhfsf2(0x7bff, 0x477fe000); // normal (max), 65504
166 try test__extendhfsf2(0xfbff, 0xc77fe000); // normal (max), -65504
164 try test_f32_floatCast_f16(0x7bff, 0x477fe000); // normal (max), 65504
165 try test_f32_floatCast_f16(0xfbff, 0xc77fe000); // normal (max), -65504
167166
168 try test__extendhfsf2(0x3c01, 0x3f802000); // normal, 1 + 2**-10
169 try test__extendhfsf2(0xbc01, 0xbf802000); // normal, -1 - 2**-10
167 try test_f32_floatCast_f16(0x3c01, 0x3f802000); // normal, 1 + 2**-10
168 try test_f32_floatCast_f16(0xbc01, 0xbf802000); // normal, -1 - 2**-10
170169
171 try test__extendhfsf2(0x3555, 0x3eaaa000); // normal, approx. 1/3
172 try test__extendhfsf2(0xb555, 0xbeaaa000); // normal, approx. -1/3
170 try test_f32_floatCast_f16(0x3555, 0x3eaaa000); // normal, approx. 1/3
171 try test_f32_floatCast_f16(0xb555, 0xbeaaa000); // normal, approx. -1/3
173172}
174173
175test "extendsftf2" {
174test f128_floatCast_f32 {
176175 // qNaN
177 try test__extendsftf2(makeQNaN32(), 0x7fff800000000000, 0x0);
176 try test_f128_floatCast_f32(makeQNaN32(), 0x7fff800000000000, 0x0);
178177 // NaN
179 try test__extendsftf2(makeNaN32(0x410000), 0x7fff820000000000, 0x0);
178 try test_f128_floatCast_f32(makeNaN32(0x410000), 0x7fff820000000000, 0x0);
180179 // inf
181 try test__extendsftf2(makeInf32(), 0x7fff000000000000, 0x0);
180 try test_f128_floatCast_f32(makeInf32(), 0x7fff000000000000, 0x0);
182181 // zero
183 try test__extendsftf2(0.0, 0x0, 0x0);
184 try test__extendsftf2(0x1.23456p+5, 0x4004234560000000, 0x0);
185 try test__extendsftf2(0x1.edcbap-9, 0x3ff6edcba0000000, 0x0);
186 try test__extendsftf2(0x1.23456p+45, 0x402c234560000000, 0x0);
187 try test__extendsftf2(0x1.edcbap-45, 0x3fd2edcba0000000, 0x0);
182 try test_f128_floatCast_f32(0.0, 0x0, 0x0);
183 try test_f128_floatCast_f32(0x1.23456p+5, 0x4004234560000000, 0x0);
184 try test_f128_floatCast_f32(0x1.edcbap-9, 0x3ff6edcba0000000, 0x0);
185 try test_f128_floatCast_f32(0x1.23456p+45, 0x402c234560000000, 0x0);
186 try test_f128_floatCast_f32(0x1.edcbap-45, 0x3fd2edcba0000000, 0x0);
188187}
189188
190189fn makeQNaN64() f64 {
......@@ -211,8 +210,8 @@ fn makeInf32() f32 {
211210 return @bitCast(@as(u32, 0x7f800000));
212211}
213212
214fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void {
215 const x = __extendhftf2(@as(F16T(f128), @bitCast(a)));
213fn test_f128_floatCast_f16(a: u16, expected_hi: u64, expected_lo: u64) !void {
214 const x = f128_floatCast_f16(@bitCast(a));
216215
217216 const rep: u128 = @bitCast(x);
218217 const hi: u64 = @intCast(rep >> 64);
......@@ -233,26 +232,26 @@ fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void {
233232 return error.TestFailure;
234233}
235234
236test "extendhftf2" {
235test f128_floatCast_f16 {
237236 // qNaN
238 try test__extendhftf2(0x7e00, 0x7fff800000000000, 0x0);
237 try test_f128_floatCast_f16(0x7e00, 0x7fff800000000000, 0x0);
239238 // NaN
240 try test__extendhftf2(0x7d00, 0x7fff400000000000, 0x0);
239 try test_f128_floatCast_f16(0x7d00, 0x7fff400000000000, 0x0);
241240 // inf
242 try test__extendhftf2(0x7c00, 0x7fff000000000000, 0x0);
243 try test__extendhftf2(0xfc00, 0xffff000000000000, 0x0);
241 try test_f128_floatCast_f16(0x7c00, 0x7fff000000000000, 0x0);
242 try test_f128_floatCast_f16(0xfc00, 0xffff000000000000, 0x0);
244243 // zero
245 try test__extendhftf2(0x0000, 0x0000000000000000, 0x0);
246 try test__extendhftf2(0x8000, 0x8000000000000000, 0x0);
244 try test_f128_floatCast_f16(0x0000, 0x0000000000000000, 0x0);
245 try test_f128_floatCast_f16(0x8000, 0x8000000000000000, 0x0);
247246 // denormal
248 try test__extendhftf2(0x0010, 0x3feb000000000000, 0x0);
249 try test__extendhftf2(0x0001, 0x3fe7000000000000, 0x0);
250 try test__extendhftf2(0x8001, 0xbfe7000000000000, 0x0);
247 try test_f128_floatCast_f16(0x0010, 0x3feb000000000000, 0x0);
248 try test_f128_floatCast_f16(0x0001, 0x3fe7000000000000, 0x0);
249 try test_f128_floatCast_f16(0x8001, 0xbfe7000000000000, 0x0);
251250
252251 // pi
253 try test__extendhftf2(0x4248, 0x4000920000000000, 0x0);
254 try test__extendhftf2(0xc248, 0xc000920000000000, 0x0);
252 try test_f128_floatCast_f16(0x4248, 0x4000920000000000, 0x0);
253 try test_f128_floatCast_f16(0xc248, 0xc000920000000000, 0x0);
255254
256 try test__extendhftf2(0x508c, 0x4004230000000000, 0x0);
257 try test__extendhftf2(0x1bb7, 0x3ff6edc000000000, 0x0);
255 try test_f128_floatCast_f16(0x508c, 0x4004230000000000, 0x0);
256 try test_f128_floatCast_f16(0x1bb7, 0x3ff6edc000000000, 0x0);
258257}
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 {
1616 symbol(&fabsl, "fabsl");
1717}
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 {
2023 return generic_fabs(a);
2124}
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 {
2430 return generic_fabs(a);
2531}
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 {
2837 return generic_fabs(a);
2938}
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 {
3244 return generic_fabs(a);
3345}
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 {
3651 return generic_fabs(a);
3752}
3853
3954pub fn fabsl(x: c_longdouble) callconv(.c) c_longdouble {
4055 switch (@typeInfo(c_longdouble).float.bits) {
41 64 => return fabs(x),
42 80 => return __fabsx(x),
43 128 => return fabsq(x),
44 else => @compileError("unreachable"),
56 64 => return fabs_f64(x),
57 80 => return fabs_f80(x),
58 128 => return fabs_f128(x),
59 else => comptime unreachable,
4560 }
4661}
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 @@
1const builtin = @import("builtin");
12const std = @import("std");
23const 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 {
5473 if (x == 0) return 0;
6474
7475 // Various constants whose values follow from the type parameters.
......@@ -53,7 +521,7 @@ pub fn floatFromInt(comptime T: type, x: anytype) T {
53521 return @bitCast(sign_bit | result);
54522}
55523
56const endian = @import("builtin").cpu.arch.endian();
524const endian = builtin.cpu.arch.endian();
57525inline fn limb(limbs: []const u32, index: usize) u32 {
58526 return switch (endian) {
59527 .little => limbs[index],
......@@ -61,11 +529,11 @@ inline fn limb(limbs: []const u32, index: usize) u32 {
61529 };
62530}
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 {
65533 switch (x.len) {
66534 0 => return 0,
67535 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) {
69537 .little => x[0..limbs_len].*,
70538 .big => switch (limbs_len) {
71539 1 => .{x[0]},
lib/compiler_rt/float_from_int_test.zig+757-733
......@@ -2,571 +2,593 @@ const std = @import("std");
22const testing = std.testing;
33const math = std.math;
44
5const __floatunsihf = @import("floatunsihf.zig").__floatunsihf;
6
7// Conversion to f32
8const __floatsisf = @import("floatsisf.zig").__floatsisf;
9const __floatunsisf = @import("floatunsisf.zig").__floatunsisf;
10const __floatdisf = @import("floatdisf.zig").__floatdisf;
11const __floatundisf = @import("floatundisf.zig").__floatundisf;
12const __floattisf = @import("floattisf.zig").__floattisf;
13const __floatuntisf = @import("floatuntisf.zig").__floatuntisf;
14const __floateisf = @import("floateisf.zig").__floateisf;
15const __floatuneisf = @import("floatuneisf.zig").__floatuneisf;
16
17// Conversion to f64
18const __floatsidf = @import("floatsidf.zig").__floatsidf;
19const __floatunsidf = @import("floatunsidf.zig").__floatunsidf;
20const __floatdidf = @import("floatdidf.zig").__floatdidf;
21const __floatundidf = @import("floatundidf.zig").__floatundidf;
22const __floattidf = @import("floattidf.zig").__floattidf;
23const __floatuntidf = @import("floatuntidf.zig").__floatuntidf;
24
25// Conversion to f128
26const __floatsitf = @import("floatsitf.zig").__floatsitf;
27const __floatunsitf = @import("floatunsitf.zig").__floatunsitf;
28const __floatditf = @import("floatditf.zig").__floatditf;
29const __floatunditf = @import("floatunditf.zig").__floatunditf;
30const __floattitf = @import("floattitf.zig").__floattitf;
31const __floatuntitf = @import("floatuntitf.zig").__floatuntitf;
32
33fn test__floatsisf(a: i32, expected: u32) !void {
34 const r = __floatsisf(a);
5const impl = @import("float_from_int.zig");
6
7const f16_floatFromInt_i32 = impl.f16_floatFromInt_i32;
8const f16_floatFromInt_u32 = impl.f16_floatFromInt_u32;
9const f16_floatFromInt_i64 = impl.f16_floatFromInt_i64;
10const f16_floatFromInt_u64 = impl.f16_floatFromInt_u64;
11const f16_floatFromInt_i128 = impl.f16_floatFromInt_i128;
12const f16_floatFromInt_u128 = impl.f16_floatFromInt_u128;
13const f16_floatFromInt_signed = impl.f16_floatFromInt_signed;
14const f16_floatFromInt_unsigned = impl.f16_floatFromInt_unsigned;
15
16const f32_floatFromInt_i32 = impl.f32_floatFromInt_i32;
17const f32_floatFromInt_u32 = impl.f32_floatFromInt_u32;
18const f32_floatFromInt_i64 = impl.f32_floatFromInt_i64;
19const f32_floatFromInt_u64 = impl.f32_floatFromInt_u64;
20const f32_floatFromInt_i128 = impl.f32_floatFromInt_i128;
21const f32_floatFromInt_u128 = impl.f32_floatFromInt_u128;
22const f32_floatFromInt_signed = impl.f32_floatFromInt_signed;
23const f32_floatFromInt_unsigned = impl.f32_floatFromInt_unsigned;
24
25const f64_floatFromInt_i32 = impl.f64_floatFromInt_i32;
26const f64_floatFromInt_u32 = impl.f64_floatFromInt_u32;
27const f64_floatFromInt_i64 = impl.f64_floatFromInt_i64;
28const f64_floatFromInt_u64 = impl.f64_floatFromInt_u64;
29const f64_floatFromInt_i128 = impl.f64_floatFromInt_i128;
30const f64_floatFromInt_u128 = impl.f64_floatFromInt_u128;
31const f64_floatFromInt_signed = impl.f64_floatFromInt_signed;
32const f64_floatFromInt_unsigned = impl.f64_floatFromInt_unsigned;
33
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);
3554 try std.testing.expect(@as(u32, @bitCast(r)) == expected);
3655}
3756
38fn test_one_floatunsisf(a: u32, expected: u32) !void {
39 const r = __floatunsisf(a);
57fn test_f32_floatFromInt_u32(a: u32, expected: u32) !void {
58 const r = f32_floatFromInt_u32(a);
4059 try std.testing.expect(@as(u32, @bitCast(r)) == expected);
4160}
4261
43test "floatsisf" {
44 try test__floatsisf(0, 0x00000000);
45 try test__floatsisf(1, 0x3f800000);
46 try test__floatsisf(-1, 0xbf800000);
47 try test__floatsisf(0x7FFFFFFF, 0x4f000000);
48 try test__floatsisf(@bitCast(@as(u32, @intCast(0x80000000))), 0xcf000000);
62test f32_floatFromInt_i32 {
63 try test_f32_floatFromInt_i32(0, 0x00000000);
64 try test_f32_floatFromInt_i32(1, 0x3f800000);
65 try test_f32_floatFromInt_i32(-1, 0xbf800000);
66 try test_f32_floatFromInt_i32(0x7FFFFFFF, 0x4f000000);
67 try test_f32_floatFromInt_i32(@bitCast(@as(u32, @intCast(0x80000000))), 0xcf000000);
68
69 try testing.expect(f32_floatFromInt_i32(math.minInt(i32)) == math.minInt(i32));
4970}
5071
51test "floatunsisf" {
72test f32_floatFromInt_u32 {
5273 // Test the produced bit pattern
53 try test_one_floatunsisf(0, 0);
54 try test_one_floatunsisf(1, 0x3f800000);
55 try test_one_floatunsisf(0x7FFFFFFF, 0x4f000000);
56 try test_one_floatunsisf(0x80000000, 0x4f000000);
57 try test_one_floatunsisf(0xFFFFFFFF, 0x4f800000);
74 try test_f32_floatFromInt_u32(0, 0);
75 try test_f32_floatFromInt_u32(1, 0x3f800000);
76 try test_f32_floatFromInt_u32(0x7FFFFFFF, 0x4f000000);
77 try test_f32_floatFromInt_u32(0x80000000, 0x4f000000);
78 try test_f32_floatFromInt_u32(0xFFFFFFFF, 0x4f800000);
79
80 try testing.expect(f32_floatFromInt_u32(0) == 0.0);
81 try testing.expect(f32_floatFromInt_u32(math.maxInt(u24)) == math.maxInt(u24));
82 try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 1) == math.maxInt(u24) + 1); // 0x100_0000 - Exact
83 try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 2) == math.maxInt(u24) + 1); // 0x100_0001 - Tie: Rounds down to even
84 try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 3) == math.maxInt(u24) + 3); // 0x100_0002 - Exact
85 try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 4) == math.maxInt(u24) + 5); // 0x100_0003 - Tie: Rounds up to even
86 try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 5) == math.maxInt(u24) + 5); // 0x100_0004 - Exact
87 try testing.expect(f32_floatFromInt_u32(math.maxInt(u32)) == math.maxInt(u32) + 1);
88}
89
90fn test_f32_floatFromInt_i64(a: i64, expected: f32) !void {
91 const x = f32_floatFromInt_i64(a);
92 try testing.expect(x == expected);
5893}
5994
60fn test__floatdisf(a: i64, expected: f32) !void {
61 const x = __floatdisf(a);
95fn test_f32_floatFromInt_u64(a: u64, expected: f32) !void {
96 const x = f32_floatFromInt_u64(a);
6297 try testing.expect(x == expected);
6398}
6499
65fn test__floatundisf(a: u64, expected: f32) !void {
66 try std.testing.expectEqual(expected, __floatundisf(a));
67}
68
69test "floatdisf" {
70 try test__floatdisf(0, 0.0);
71 try test__floatdisf(1, 1.0);
72 try test__floatdisf(2, 2.0);
73 try test__floatdisf(-1, -1.0);
74 try test__floatdisf(-2, -2.0);
75 try test__floatdisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
76 try test__floatdisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
77 try test__floatdisf(@bitCast(@as(u64, 0x8000008000000000)), -0x1.FFFFFEp+62);
78 try test__floatdisf(@bitCast(@as(u64, 0x8000010000000000)), -0x1.FFFFFCp+62);
79 try test__floatdisf(@bitCast(@as(u64, 0x8000000000000000)), -0x1.000000p+63);
80 try test__floatdisf(@bitCast(@as(u64, 0x8000000000000001)), -0x1.000000p+63);
81 try test__floatdisf(0x0007FB72E8000000, 0x1.FEDCBAp+50);
82 try test__floatdisf(0x0007FB72EA000000, 0x1.FEDCBAp+50);
83 try test__floatdisf(0x0007FB72EB000000, 0x1.FEDCBAp+50);
84 try test__floatdisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
85 try test__floatdisf(0x0007FB72EC000000, 0x1.FEDCBCp+50);
86 try test__floatdisf(0x0007FB72E8000001, 0x1.FEDCBAp+50);
87 try test__floatdisf(0x0007FB72E6000000, 0x1.FEDCBAp+50);
88 try test__floatdisf(0x0007FB72E7000000, 0x1.FEDCBAp+50);
89 try test__floatdisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
90 try test__floatdisf(0x0007FB72E4000001, 0x1.FEDCBAp+50);
91 try test__floatdisf(0x0007FB72E4000000, 0x1.FEDCB8p+50);
92}
93
94test "floatundisf" {
95 try test__floatundisf(0, 0.0);
96 try test__floatundisf(1, 1.0);
97 try test__floatundisf(2, 2.0);
98 try test__floatundisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
99 try test__floatundisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
100 try test__floatundisf(0x8000008000000000, 0x1p+63);
101 try test__floatundisf(0x8000010000000000, 0x1.000002p+63);
102 try test__floatundisf(0x8000000000000000, 0x1p+63);
103 try test__floatundisf(0x8000000000000001, 0x1p+63);
104 try test__floatundisf(0xFFFFFFFFFFFFFFFE, 0x1p+64);
105 try test__floatundisf(0xFFFFFFFFFFFFFFFF, 0x1p+64);
106 try test__floatundisf(0x0007FB72E8000000, 0x1.FEDCBAp+50);
107 try test__floatundisf(0x0007FB72EA000000, 0x1.FEDCBAp+50);
108 try test__floatundisf(0x0007FB72EB000000, 0x1.FEDCBAp+50);
109 try test__floatundisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
110 try test__floatundisf(0x0007FB72EC000000, 0x1.FEDCBCp+50);
111 try test__floatundisf(0x0007FB72E8000001, 0x1.FEDCBAp+50);
112 try test__floatundisf(0x0007FB72E6000000, 0x1.FEDCBAp+50);
113 try test__floatundisf(0x0007FB72E7000000, 0x1.FEDCBAp+50);
114 try test__floatundisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
115 try test__floatundisf(0x0007FB72E4000001, 0x1.FEDCBAp+50);
116 try test__floatundisf(0x0007FB72E4000000, 0x1.FEDCB8p+50);
117}
118
119fn test__floattisf(a: i128, expected: f32) !void {
120 const x = __floattisf(a);
100test f32_floatFromInt_i64 {
101 try test_f32_floatFromInt_i64(0, 0.0);
102 try test_f32_floatFromInt_i64(1, 1.0);
103 try test_f32_floatFromInt_i64(2, 2.0);
104 try test_f32_floatFromInt_i64(-1, -1.0);
105 try test_f32_floatFromInt_i64(-2, -2.0);
106 try test_f32_floatFromInt_i64(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
107 try test_f32_floatFromInt_i64(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
108 try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000008000000000)), -0x1.FFFFFEp+62);
109 try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000010000000000)), -0x1.FFFFFCp+62);
110 try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000000)), -0x1.000000p+63);
111 try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000001)), -0x1.000000p+63);
112 try test_f32_floatFromInt_i64(0x0007FB72E8000000, 0x1.FEDCBAp+50);
113 try test_f32_floatFromInt_i64(0x0007FB72EA000000, 0x1.FEDCBAp+50);
114 try test_f32_floatFromInt_i64(0x0007FB72EB000000, 0x1.FEDCBAp+50);
115 try test_f32_floatFromInt_i64(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
116 try test_f32_floatFromInt_i64(0x0007FB72EC000000, 0x1.FEDCBCp+50);
117 try test_f32_floatFromInt_i64(0x0007FB72E8000001, 0x1.FEDCBAp+50);
118 try test_f32_floatFromInt_i64(0x0007FB72E6000000, 0x1.FEDCBAp+50);
119 try test_f32_floatFromInt_i64(0x0007FB72E7000000, 0x1.FEDCBAp+50);
120 try test_f32_floatFromInt_i64(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
121 try test_f32_floatFromInt_i64(0x0007FB72E4000001, 0x1.FEDCBAp+50);
122 try test_f32_floatFromInt_i64(0x0007FB72E4000000, 0x1.FEDCB8p+50);
123}
124
125test f32_floatFromInt_u64 {
126 try test_f32_floatFromInt_u64(0, 0.0);
127 try test_f32_floatFromInt_u64(1, 1.0);
128 try test_f32_floatFromInt_u64(2, 2.0);
129 try test_f32_floatFromInt_u64(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
130 try test_f32_floatFromInt_u64(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
131 try test_f32_floatFromInt_u64(0x8000008000000000, 0x1p+63);
132 try test_f32_floatFromInt_u64(0x8000010000000000, 0x1.000002p+63);
133 try test_f32_floatFromInt_u64(0x8000000000000000, 0x1p+63);
134 try test_f32_floatFromInt_u64(0x8000000000000001, 0x1p+63);
135 try test_f32_floatFromInt_u64(0xFFFFFFFFFFFFFFFE, 0x1p+64);
136 try test_f32_floatFromInt_u64(0xFFFFFFFFFFFFFFFF, 0x1p+64);
137 try test_f32_floatFromInt_u64(0x0007FB72E8000000, 0x1.FEDCBAp+50);
138 try test_f32_floatFromInt_u64(0x0007FB72EA000000, 0x1.FEDCBAp+50);
139 try test_f32_floatFromInt_u64(0x0007FB72EB000000, 0x1.FEDCBAp+50);
140 try test_f32_floatFromInt_u64(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
141 try test_f32_floatFromInt_u64(0x0007FB72EC000000, 0x1.FEDCBCp+50);
142 try test_f32_floatFromInt_u64(0x0007FB72E8000001, 0x1.FEDCBAp+50);
143 try test_f32_floatFromInt_u64(0x0007FB72E6000000, 0x1.FEDCBAp+50);
144 try test_f32_floatFromInt_u64(0x0007FB72E7000000, 0x1.FEDCBAp+50);
145 try test_f32_floatFromInt_u64(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
146 try test_f32_floatFromInt_u64(0x0007FB72E4000001, 0x1.FEDCBAp+50);
147 try test_f32_floatFromInt_u64(0x0007FB72E4000000, 0x1.FEDCB8p+50);
148}
149
150fn test_f32_floatFromInt_i128(a: i128, expected: f32) !void {
151 const x = f32_floatFromInt_i128(a);
121152 try testing.expect(x == expected);
122153}
123154
124fn test__floatuntisf(a: u128, expected: f32) !void {
125 const x = __floatuntisf(a);
155fn test_f32_floatFromInt_u128(a: u128, expected: f32) !void {
156 const x = f32_floatFromInt_u128(a);
126157 try testing.expect(x == expected);
127158}
128159
129test "floattisf" {
130 try test__floattisf(0, 0.0);
160test f32_floatFromInt_i128 {
161 try test_f32_floatFromInt_i128(0, 0.0);
131162
132 try test__floattisf(1, 1.0);
133 try test__floattisf(2, 2.0);
134 try test__floattisf(-1, -1.0);
135 try test__floattisf(-2, -2.0);
163 try test_f32_floatFromInt_i128(1, 1.0);
164 try test_f32_floatFromInt_i128(2, 2.0);
165 try test_f32_floatFromInt_i128(-1, -1.0);
166 try test_f32_floatFromInt_i128(-2, -2.0);
136167
137 try test__floattisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
138 try test__floattisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
168 try test_f32_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
169 try test_f32_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
139170
140 try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000008000000000), -0x1.FFFFFEp+62);
141 try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000010000000000), -0x1.FFFFFCp+62);
171 try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000008000000000), -0x1.FFFFFEp+62);
172 try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000010000000000), -0x1.FFFFFCp+62);
142173
143 try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000000), -0x1.000000p+63);
144 try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000001), -0x1.000000p+63);
174 try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000000), -0x1.000000p+63);
175 try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000001), -0x1.000000p+63);
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);
149 try test__floattisf(0x0007FB72EB000000, 0x1.FEDCBAp+50);
150 try test__floattisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
151 try test__floattisf(0x0007FB72EC000000, 0x1.FEDCBCp+50);
152 try test__floattisf(0x0007FB72E8000001, 0x1.FEDCBAp+50);
179 try test_f32_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBAp+50);
180 try test_f32_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBAp+50);
181 try test_f32_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
182 try test_f32_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBCp+50);
183 try test_f32_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBAp+50);
153184
154 try test__floattisf(0x0007FB72E6000000, 0x1.FEDCBAp+50);
155 try test__floattisf(0x0007FB72E7000000, 0x1.FEDCBAp+50);
156 try test__floattisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
157 try test__floattisf(0x0007FB72E4000001, 0x1.FEDCBAp+50);
158 try test__floattisf(0x0007FB72E4000000, 0x1.FEDCB8p+50);
185 try test_f32_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCBAp+50);
186 try test_f32_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCBAp+50);
187 try test_f32_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
188 try test_f32_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCBAp+50);
189 try test_f32_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB8p+50);
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);
163 try test__floattisf(make_ti(0x0007FB72EB000000, 0), 0x1.FEDCBAp+114);
164 try test__floattisf(make_ti(0x0007FB72EBFFFFFF, 0), 0x1.FEDCBAp+114);
165 try test__floattisf(make_ti(0x0007FB72EC000000, 0), 0x1.FEDCBCp+114);
166 try test__floattisf(make_ti(0x0007FB72E8000001, 0), 0x1.FEDCBAp+114);
193 try test_f32_floatFromInt_i128(make_ti(0x0007FB72EA000000, 0), 0x1.FEDCBAp+114);
194 try test_f32_floatFromInt_i128(make_ti(0x0007FB72EB000000, 0), 0x1.FEDCBAp+114);
195 try test_f32_floatFromInt_i128(make_ti(0x0007FB72EBFFFFFF, 0), 0x1.FEDCBAp+114);
196 try test_f32_floatFromInt_i128(make_ti(0x0007FB72EC000000, 0), 0x1.FEDCBCp+114);
197 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E8000001, 0), 0x1.FEDCBAp+114);
167198
168 try test__floattisf(make_ti(0x0007FB72E6000000, 0), 0x1.FEDCBAp+114);
169 try test__floattisf(make_ti(0x0007FB72E7000000, 0), 0x1.FEDCBAp+114);
170 try test__floattisf(make_ti(0x0007FB72E7FFFFFF, 0), 0x1.FEDCBAp+114);
171 try test__floattisf(make_ti(0x0007FB72E4000001, 0), 0x1.FEDCBAp+114);
172 try test__floattisf(make_ti(0x0007FB72E4000000, 0), 0x1.FEDCB8p+114);
199 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E6000000, 0), 0x1.FEDCBAp+114);
200 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E7000000, 0), 0x1.FEDCBAp+114);
201 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E7FFFFFF, 0), 0x1.FEDCBAp+114);
202 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E4000001, 0), 0x1.FEDCBAp+114);
203 try test_f32_floatFromInt_i128(make_ti(0x0007FB72E4000000, 0), 0x1.FEDCB8p+114);
173204}
174205
175test "floatuntisf" {
176 try test__floatuntisf(0, 0.0);
206test f32_floatFromInt_u128 {
207 try test_f32_floatFromInt_u128(0, 0.0);
177208
178 try test__floatuntisf(1, 1.0);
179 try test__floatuntisf(2, 2.0);
180 try test__floatuntisf(20, 20.0);
209 try test_f32_floatFromInt_u128(1, 1.0);
210 try test_f32_floatFromInt_u128(2, 2.0);
211 try test_f32_floatFromInt_u128(20, 20.0);
181212
182 try test__floatuntisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
183 try test__floatuntisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
213 try test_f32_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
214 try test_f32_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
184215
185 try test__floatuntisf(make_uti(0x8000008000000000, 0), 0x1.000001p+127);
186 try test__floatuntisf(make_uti(0x8000000000000800, 0), 0x1.0p+127);
187 try test__floatuntisf(make_uti(0x8000010000000000, 0), 0x1.000002p+127);
216 try test_f32_floatFromInt_u128(make_uti(0x8000008000000000, 0), 0x1.000001p+127);
217 try test_f32_floatFromInt_u128(make_uti(0x8000000000000800, 0), 0x1.0p+127);
218 try test_f32_floatFromInt_u128(make_uti(0x8000010000000000, 0), 0x1.000002p+127);
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);
194 try test__floatuntisf(0x0007FB72EB000000, 0x1.FEDCBACp+50);
224 try test_f32_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
225 try test_f32_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50);
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);
199 try test__floatuntisf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
200 try test__floatuntisf(0x0007FB72E4000000, 0x1.FEDCB9p+50);
229 try test_f32_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50);
230 try test_f32_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
231 try test_f32_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50);
201232
202 try test__floatuntisf(0xFFFFFFFFFFFFFFFE, 0x1p+64);
203 try test__floatuntisf(0xFFFFFFFFFFFFFFFF, 0x1p+64);
233 try test_f32_floatFromInt_u128(0xFFFFFFFFFFFFFFFE, 0x1p+64);
234 try test_f32_floatFromInt_u128(0xFFFFFFFFFFFFFFFF, 0x1p+64);
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);
208 try test__floatuntisf(0x0007FB72EB000000, 0x1.FEDCBAp+50);
209 try test__floatuntisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
210 try test__floatuntisf(0x0007FB72EC000000, 0x1.FEDCBCp+50);
211 try test__floatuntisf(0x0007FB72E8000001, 0x1.FEDCBAp+50);
238 try test_f32_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBAp+50);
239 try test_f32_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBAp+50);
240 try test_f32_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50);
241 try test_f32_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBCp+50);
242 try test_f32_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBAp+50);
212243
213 try test__floatuntisf(0x0007FB72E6000000, 0x1.FEDCBAp+50);
214 try test__floatuntisf(0x0007FB72E7000000, 0x1.FEDCBAp+50);
215 try test__floatuntisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
216 try test__floatuntisf(0x0007FB72E4000001, 0x1.FEDCBAp+50);
217 try test__floatuntisf(0x0007FB72E4000000, 0x1.FEDCB8p+50);
244 try test_f32_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCBAp+50);
245 try test_f32_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCBAp+50);
246 try test_f32_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50);
247 try test_f32_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCBAp+50);
248 try test_f32_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB8p+50);
218249
219 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCB90000000000001), 0x1.FEDCBAp+76);
220 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBA0000000000000), 0x1.FEDCBAp+76);
221 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBAFFFFFFFFFFFFF), 0x1.FEDCBAp+76);
222 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBB0000000000000), 0x1.FEDCBCp+76);
223 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBB0000000000001), 0x1.FEDCBCp+76);
224 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBBFFFFFFFFFFFFF), 0x1.FEDCBCp+76);
225 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBC0000000000000), 0x1.FEDCBCp+76);
226 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBC0000000000001), 0x1.FEDCBCp+76);
227 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBD0000000000000), 0x1.FEDCBCp+76);
228 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBD0000000000001), 0x1.FEDCBEp+76);
229 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBDFFFFFFFFFFFFF), 0x1.FEDCBEp+76);
230 try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBE0000000000000), 0x1.FEDCBEp+76);
250 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCB90000000000001), 0x1.FEDCBAp+76);
251 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBA0000000000000), 0x1.FEDCBAp+76);
252 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBAFFFFFFFFFFFFF), 0x1.FEDCBAp+76);
253 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBB0000000000000), 0x1.FEDCBCp+76);
254 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBB0000000000001), 0x1.FEDCBCp+76);
255 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBBFFFFFFFFFFFFF), 0x1.FEDCBCp+76);
256 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBC0000000000000), 0x1.FEDCBCp+76);
257 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBC0000000000001), 0x1.FEDCBCp+76);
258 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBD0000000000000), 0x1.FEDCBCp+76);
259 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBD0000000000001), 0x1.FEDCBEp+76);
260 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBDFFFFFFFFFFFFF), 0x1.FEDCBEp+76);
261 try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBE0000000000000), 0x1.FEDCBEp+76);
231262
232263 // 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)));
234265}
235266
236fn test_floateisf(expected: u32, comptime T: type, a: T) !void {
267fn test_f32_floatFromInt(expected: u32, comptime T: type, a: T) !void {
237268 const int = @typeInfo(T).int;
238269 const r = switch (int.signedness) {
239 .signed => __floateisf,
240 .unsigned => __floatuneisf,
241 }(@ptrCast(&a), int.bits);
270 .signed => f32_floatFromInt_signed,
271 .unsigned => f32_floatFromInt_unsigned,
272 }(@ptrCast(&a));
242273 try testing.expect(expected == @as(u32, @bitCast(r)));
243274}
244275
245test "floateisf" {
246 try test_floateisf(0xFF000000, i256, -1 << 127);
247 try test_floateisf(0xFF000000, i256, -math.maxInt(u127));
248 try test_floateisf(0xDF012347, i256, -0x8123468100000000);
249 try test_floateisf(0xDF012347, i256, -0x8123468000000001);
250 try test_floateisf(0xDF012346, i256, -0x8123468000000000);
251 try test_floateisf(0xDF012346, i256, -0x8123458100000000);
252 try test_floateisf(0xDF012346, i256, -0x8123458000000001);
253 try test_floateisf(0xDF012346, i256, -0x8123458000000000);
254 try test_floateisf(0xDF012345, i256, -0x8123456789ABCDEF);
255 try test_floateisf(0xBF800000, i256, -1);
256 try test_floateisf(0x00000000, i256, 0);
257 try test_floateisf(0x5F012345, i256, 0x8123456789ABCDEF);
258 try test_floateisf(0x5F012346, i256, 0x8123458000000000);
259 try test_floateisf(0x5F012346, i256, 0x8123458000000001);
260 try test_floateisf(0x5F012346, i256, 0x8123458100000000);
261 try test_floateisf(0x5F012346, i256, 0x8123468000000000);
262 try test_floateisf(0x5F012347, i256, 0x8123468000000001);
263 try test_floateisf(0x5F012347, i256, 0x8123468100000000);
264 try test_floateisf(0x7F000000, i256, math.maxInt(u127));
265 try test_floateisf(0x7F000000, i256, 1 << 127);
266}
267
268test "floatuneisf" {
269 try test_floateisf(0x00000000, u256, 0);
270 try test_floateisf(0x5F012345, u256, 0x8123456789ABCDEF);
271 try test_floateisf(0x5F012346, u256, 0x8123458000000000);
272 try test_floateisf(0x5F012346, u256, 0x8123458000000001);
273 try test_floateisf(0x5F012346, u256, 0x8123458080000000);
274 try test_floateisf(0x5F012346, u256, 0x8123468000000000);
275 try test_floateisf(0x5F012347, u256, 0x8123468000000001);
276 try test_floateisf(0x5F012347, u256, 0x8123468080000000);
277 try test_floateisf(0x7F000000, u256, math.maxInt(u127));
278 try test_floateisf(0x7F000000, u256, 1 << 127);
279 try test_floateisf(0x7F800000, u256, math.maxInt(u256));
280}
281
282fn test_one_floatsidf(a: i32, expected: u64) !void {
283 const r = __floatsidf(a);
276test f32_floatFromInt_signed {
277 try test_f32_floatFromInt(0xFF000000, i256, -1 << 127);
278 try test_f32_floatFromInt(0xFF000000, i256, -math.maxInt(u127));
279 try test_f32_floatFromInt(0xDF012347, i256, -0x8123468100000000);
280 try test_f32_floatFromInt(0xDF012347, i256, -0x8123468000000001);
281 try test_f32_floatFromInt(0xDF012346, i256, -0x8123468000000000);
282 try test_f32_floatFromInt(0xDF012346, i256, -0x8123458100000000);
283 try test_f32_floatFromInt(0xDF012346, i256, -0x8123458000000001);
284 try test_f32_floatFromInt(0xDF012346, i256, -0x8123458000000000);
285 try test_f32_floatFromInt(0xDF012345, i256, -0x8123456789ABCDEF);
286 try test_f32_floatFromInt(0xBF800000, i256, -1);
287 try test_f32_floatFromInt(0x00000000, i256, 0);
288 try test_f32_floatFromInt(0x5F012345, i256, 0x8123456789ABCDEF);
289 try test_f32_floatFromInt(0x5F012346, i256, 0x8123458000000000);
290 try test_f32_floatFromInt(0x5F012346, i256, 0x8123458000000001);
291 try test_f32_floatFromInt(0x5F012346, i256, 0x8123458100000000);
292 try test_f32_floatFromInt(0x5F012346, i256, 0x8123468000000000);
293 try test_f32_floatFromInt(0x5F012347, i256, 0x8123468000000001);
294 try test_f32_floatFromInt(0x5F012347, i256, 0x8123468100000000);
295 try test_f32_floatFromInt(0x7F000000, i256, math.maxInt(u127));
296 try test_f32_floatFromInt(0x7F000000, i256, 1 << 127);
297}
298
299test f32_floatFromInt_unsigned {
300 try test_f32_floatFromInt(0x00000000, u256, 0);
301 try test_f32_floatFromInt(0x5F012345, u256, 0x8123456789ABCDEF);
302 try test_f32_floatFromInt(0x5F012346, u256, 0x8123458000000000);
303 try test_f32_floatFromInt(0x5F012346, u256, 0x8123458000000001);
304 try test_f32_floatFromInt(0x5F012346, u256, 0x8123458080000000);
305 try test_f32_floatFromInt(0x5F012346, u256, 0x8123468000000000);
306 try test_f32_floatFromInt(0x5F012347, u256, 0x8123468000000001);
307 try test_f32_floatFromInt(0x5F012347, u256, 0x8123468080000000);
308 try test_f32_floatFromInt(0x7F000000, u256, math.maxInt(u127));
309 try test_f32_floatFromInt(0x7F000000, u256, 1 << 127);
310 try test_f32_floatFromInt(0x7F800000, u256, math.maxInt(u256));
311}
312
313fn test_f64_floatFromInt_i32(a: i32, expected: u64) !void {
314 const r = f64_floatFromInt_i32(a);
284315 try std.testing.expect(@as(u64, @bitCast(r)) == expected);
285316}
286317
287fn test_one_floatunsidf(a: u32, expected: u64) !void {
288 const r = __floatunsidf(a);
318fn test_f64_floatFromInt_u32(a: u32, expected: u64) !void {
319 const r = f64_floatFromInt_u32(a);
289320 try std.testing.expect(@as(u64, @bitCast(r)) == expected);
290321}
291322
292test "floatsidf" {
293 try test_one_floatsidf(0, 0x0000000000000000);
294 try test_one_floatsidf(1, 0x3ff0000000000000);
295 try test_one_floatsidf(-1, 0xbff0000000000000);
296 try test_one_floatsidf(0x7FFFFFFF, 0x41dfffffffc00000);
297 try test_one_floatsidf(@bitCast(@as(u32, @intCast(0x80000000))), 0xc1e0000000000000);
323test f64_floatFromInt_i32 {
324 try test_f64_floatFromInt_i32(0, 0x0000000000000000);
325 try test_f64_floatFromInt_i32(1, 0x3ff0000000000000);
326 try test_f64_floatFromInt_i32(-1, 0xbff0000000000000);
327 try test_f64_floatFromInt_i32(0x7FFFFFFF, 0x41dfffffffc00000);
328 try test_f64_floatFromInt_i32(@bitCast(@as(u32, @intCast(0x80000000))), 0xc1e0000000000000);
298329}
299330
300test "floatunsidf" {
301 try test_one_floatunsidf(0, 0x0000000000000000);
302 try test_one_floatunsidf(1, 0x3ff0000000000000);
303 try test_one_floatunsidf(0x7FFFFFFF, 0x41dfffffffc00000);
304 try test_one_floatunsidf(@intCast(0x80000000), 0x41e0000000000000);
305 try test_one_floatunsidf(@intCast(0xFFFFFFFF), 0x41efffffffe00000);
331test f64_floatFromInt_u32 {
332 try test_f64_floatFromInt_u32(0, 0x0000000000000000);
333 try test_f64_floatFromInt_u32(1, 0x3ff0000000000000);
334 try test_f64_floatFromInt_u32(0x7FFFFFFF, 0x41dfffffffc00000);
335 try test_f64_floatFromInt_u32(@intCast(0x80000000), 0x41e0000000000000);
336 try test_f64_floatFromInt_u32(@intCast(0xFFFFFFFF), 0x41efffffffe00000);
306337}
307338
308fn test__floatdidf(a: i64, expected: f64) !void {
309 const r = __floatdidf(a);
339fn test_f64_floatFromInt_i64(a: i64, expected: f64) !void {
340 const r = f64_floatFromInt_i64(a);
310341 try testing.expect(r == expected);
311342}
312343
313fn test__floatundidf(a: u64, expected: f64) !void {
314 const r = __floatundidf(a);
344fn test_f64_floatFromInt_u64(a: u64, expected: f64) !void {
345 const r = f64_floatFromInt_u64(a);
315346 try testing.expect(r == expected);
316347}
317348
318test "floatdidf" {
319 try test__floatdidf(0, 0.0);
320 try test__floatdidf(1, 1.0);
321 try test__floatdidf(2, 2.0);
322 try test__floatdidf(20, 20.0);
323 try test__floatdidf(-1, -1.0);
324 try test__floatdidf(-2, -2.0);
325 try test__floatdidf(-20, -20.0);
326 try test__floatdidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
327 try test__floatdidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
328 try test__floatdidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
329 try test__floatdidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
330 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000008000000000))), -0x1.FFFFFEp+62);
331 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000800))), -0x1.FFFFFFFFFFFFEp+62);
332 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000010000000000))), -0x1.FFFFFCp+62);
333 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000001000))), -0x1.FFFFFFFFFFFFCp+62);
334 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000000))), -0x1.000000p+63);
335 try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000001))), -0x1.000000p+63); // 0x8000000000000001
336 try test__floatdidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);
337 try test__floatdidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
338 try test__floatdidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);
339 try test__floatdidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
340 try test__floatdidf(0x0007FB72EC000000, 0x1.FEDCBBp+50);
341 try test__floatdidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
342 try test__floatdidf(0x0007FB72E6000000, 0x1.FEDCB98p+50);
343 try test__floatdidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
344 try test__floatdidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
345 try test__floatdidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
346 try test__floatdidf(0x0007FB72E4000000, 0x1.FEDCB9p+50);
347 try test__floatdidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
348 try test__floatdidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
349 try test__floatdidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
350 try test__floatdidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
351 try test__floatdidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
352 try test__floatdidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
353 try test__floatdidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
354 try test__floatdidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
355 try test__floatdidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
356 try test__floatdidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
357 try test__floatdidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
358 try test__floatdidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
359 try test__floatdidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
360 try test__floatdidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
361 try test__floatdidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
362}
363
364test "floatundidf" {
365 try test__floatundidf(0, 0.0);
366 try test__floatundidf(1, 1.0);
367 try test__floatundidf(2, 2.0);
368 try test__floatundidf(20, 20.0);
369 try test__floatundidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
370 try test__floatundidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
371 try test__floatundidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
372 try test__floatundidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
373 try test__floatundidf(0x8000008000000000, 0x1.000001p+63);
374 try test__floatundidf(0x8000000000000800, 0x1.0000000000001p+63);
375 try test__floatundidf(0x8000010000000000, 0x1.000002p+63);
376 try test__floatundidf(0x8000000000001000, 0x1.0000000000002p+63);
377 try test__floatundidf(0x8000000000000000, 0x1p+63);
378 try test__floatundidf(0x8000000000000001, 0x1p+63);
379 try test__floatundidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);
380 try test__floatundidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
381 try test__floatundidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);
382 try test__floatundidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
383 try test__floatundidf(0x0007FB72EC000000, 0x1.FEDCBBp+50);
384 try test__floatundidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
385 try test__floatundidf(0x0007FB72E6000000, 0x1.FEDCB98p+50);
386 try test__floatundidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
387 try test__floatundidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
388 try test__floatundidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
389 try test__floatundidf(0x0007FB72E4000000, 0x1.FEDCB9p+50);
390 try test__floatundidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
391 try test__floatundidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
392 try test__floatundidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
393 try test__floatundidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
394 try test__floatundidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
395 try test__floatundidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
396 try test__floatundidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
397 try test__floatundidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
398 try test__floatundidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
399 try test__floatundidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
400 try test__floatundidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
401 try test__floatundidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
402 try test__floatundidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
403 try test__floatundidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
404 try test__floatundidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
405}
406
407fn test__floattidf(a: i128, expected: f64) !void {
408 const x = __floattidf(a);
349test f64_floatFromInt_i64 {
350 try test_f64_floatFromInt_i64(0, 0.0);
351 try test_f64_floatFromInt_i64(1, 1.0);
352 try test_f64_floatFromInt_i64(2, 2.0);
353 try test_f64_floatFromInt_i64(20, 20.0);
354 try test_f64_floatFromInt_i64(-1, -1.0);
355 try test_f64_floatFromInt_i64(-2, -2.0);
356 try test_f64_floatFromInt_i64(-20, -20.0);
357 try test_f64_floatFromInt_i64(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
358 try test_f64_floatFromInt_i64(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
359 try test_f64_floatFromInt_i64(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
360 try test_f64_floatFromInt_i64(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
361 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000008000000000))), -0x1.FFFFFEp+62);
362 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000800))), -0x1.FFFFFFFFFFFFEp+62);
363 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000010000000000))), -0x1.FFFFFCp+62);
364 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000001000))), -0x1.FFFFFFFFFFFFCp+62);
365 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000000))), -0x1.000000p+63);
366 try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000001))), -0x1.000000p+63); // 0x8000000000000001
367 try test_f64_floatFromInt_i64(0x0007FB72E8000000, 0x1.FEDCBAp+50);
368 try test_f64_floatFromInt_i64(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
369 try test_f64_floatFromInt_i64(0x0007FB72EB000000, 0x1.FEDCBACp+50);
370 try test_f64_floatFromInt_i64(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
371 try test_f64_floatFromInt_i64(0x0007FB72EC000000, 0x1.FEDCBBp+50);
372 try test_f64_floatFromInt_i64(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
373 try test_f64_floatFromInt_i64(0x0007FB72E6000000, 0x1.FEDCB98p+50);
374 try test_f64_floatFromInt_i64(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
375 try test_f64_floatFromInt_i64(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
376 try test_f64_floatFromInt_i64(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
377 try test_f64_floatFromInt_i64(0x0007FB72E4000000, 0x1.FEDCB9p+50);
378 try test_f64_floatFromInt_i64(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
379 try test_f64_floatFromInt_i64(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
380 try test_f64_floatFromInt_i64(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
381 try test_f64_floatFromInt_i64(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
382 try test_f64_floatFromInt_i64(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
383 try test_f64_floatFromInt_i64(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
384 try test_f64_floatFromInt_i64(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
385 try test_f64_floatFromInt_i64(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
386 try test_f64_floatFromInt_i64(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
387 try test_f64_floatFromInt_i64(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
388 try test_f64_floatFromInt_i64(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
389 try test_f64_floatFromInt_i64(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
390 try test_f64_floatFromInt_i64(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
391 try test_f64_floatFromInt_i64(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
392 try test_f64_floatFromInt_i64(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
393}
394
395test f64_floatFromInt_u64 {
396 try test_f64_floatFromInt_u64(0, 0.0);
397 try test_f64_floatFromInt_u64(1, 1.0);
398 try test_f64_floatFromInt_u64(2, 2.0);
399 try test_f64_floatFromInt_u64(20, 20.0);
400 try test_f64_floatFromInt_u64(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
401 try test_f64_floatFromInt_u64(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
402 try test_f64_floatFromInt_u64(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
403 try test_f64_floatFromInt_u64(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
404 try test_f64_floatFromInt_u64(0x8000008000000000, 0x1.000001p+63);
405 try test_f64_floatFromInt_u64(0x8000000000000800, 0x1.0000000000001p+63);
406 try test_f64_floatFromInt_u64(0x8000010000000000, 0x1.000002p+63);
407 try test_f64_floatFromInt_u64(0x8000000000001000, 0x1.0000000000002p+63);
408 try test_f64_floatFromInt_u64(0x8000000000000000, 0x1p+63);
409 try test_f64_floatFromInt_u64(0x8000000000000001, 0x1p+63);
410 try test_f64_floatFromInt_u64(0x0007FB72E8000000, 0x1.FEDCBAp+50);
411 try test_f64_floatFromInt_u64(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
412 try test_f64_floatFromInt_u64(0x0007FB72EB000000, 0x1.FEDCBACp+50);
413 try test_f64_floatFromInt_u64(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
414 try test_f64_floatFromInt_u64(0x0007FB72EC000000, 0x1.FEDCBBp+50);
415 try test_f64_floatFromInt_u64(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
416 try test_f64_floatFromInt_u64(0x0007FB72E6000000, 0x1.FEDCB98p+50);
417 try test_f64_floatFromInt_u64(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
418 try test_f64_floatFromInt_u64(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
419 try test_f64_floatFromInt_u64(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
420 try test_f64_floatFromInt_u64(0x0007FB72E4000000, 0x1.FEDCB9p+50);
421 try test_f64_floatFromInt_u64(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
422 try test_f64_floatFromInt_u64(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
423 try test_f64_floatFromInt_u64(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
424 try test_f64_floatFromInt_u64(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
425 try test_f64_floatFromInt_u64(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
426 try test_f64_floatFromInt_u64(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
427 try test_f64_floatFromInt_u64(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
428 try test_f64_floatFromInt_u64(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
429 try test_f64_floatFromInt_u64(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
430 try test_f64_floatFromInt_u64(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
431 try test_f64_floatFromInt_u64(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
432 try test_f64_floatFromInt_u64(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
433 try test_f64_floatFromInt_u64(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
434 try test_f64_floatFromInt_u64(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
435 try test_f64_floatFromInt_u64(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
436}
437
438fn test_f64_floatFromInt_i128(a: i128, expected: f64) !void {
439 const x = f64_floatFromInt_i128(a);
409440 try testing.expect(x == expected);
410441}
411442
412fn test__floatuntidf(a: u128, expected: f64) !void {
413 const x = __floatuntidf(a);
443fn test_f64_floatFromInt_u128(a: u128, expected: f64) !void {
444 const x = f64_floatFromInt_u128(a);
414445 try testing.expect(x == expected);
415446}
416447
417test "floattidf" {
418 try test__floattidf(0, 0.0);
419
420 try test__floattidf(1, 1.0);
421 try test__floattidf(2, 2.0);
422 try test__floattidf(20, 20.0);
423 try test__floattidf(-1, -1.0);
424 try test__floattidf(-2, -2.0);
425 try test__floattidf(-20, -20.0);
426
427 try test__floattidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
428 try test__floattidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
429 try test__floattidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
430 try test__floattidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
431
432 try test__floattidf(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126);
433 try test__floattidf(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126);
434 try test__floattidf(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126);
435 try test__floattidf(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126);
436
437 try test__floattidf(make_ti(0x8000000000000000, 0), -0x1.000000p+127);
438 try test__floattidf(make_ti(0x8000000000000001, 0), -0x1.000000p+127);
439
440 try test__floattidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);
441
442 try test__floattidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
443 try test__floattidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);
444 try test__floattidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
445 try test__floattidf(0x0007FB72EC000000, 0x1.FEDCBBp+50);
446 try test__floattidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
447
448 try test__floattidf(0x0007FB72E6000000, 0x1.FEDCB98p+50);
449 try test__floattidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
450 try test__floattidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
451 try test__floattidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
452 try test__floattidf(0x0007FB72E4000000, 0x1.FEDCB9p+50);
453
454 try test__floattidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
455 try test__floattidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
456 try test__floattidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
457 try test__floattidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
458 try test__floattidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
459 try test__floattidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
460 try test__floattidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
461 try test__floattidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
462 try test__floattidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
463 try test__floattidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
464 try test__floattidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
465 try test__floattidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
466 try test__floattidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
467 try test__floattidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
468 try test__floattidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
469
470 try test__floattidf(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
471 try test__floattidf(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121);
472 try test__floattidf(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121);
473 try test__floattidf(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121);
474 try test__floattidf(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121);
475 try test__floattidf(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121);
476 try test__floattidf(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121);
477 try test__floattidf(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121);
478 try test__floattidf(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121);
479 try test__floattidf(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121);
480 try test__floattidf(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121);
481 try test__floattidf(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121);
482 try test__floattidf(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121);
483 try test__floattidf(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121);
484 try test__floattidf(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
485}
486
487test "floatuntidf" {
488 try test__floatuntidf(0, 0.0);
489
490 try test__floatuntidf(1, 1.0);
491 try test__floatuntidf(2, 2.0);
492 try test__floatuntidf(20, 20.0);
493
494 try test__floatuntidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
495 try test__floatuntidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
496 try test__floatuntidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
497 try test__floatuntidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
498
499 try test__floatuntidf(make_uti(0x8000008000000000, 0), 0x1.000001p+127);
500 try test__floatuntidf(make_uti(0x8000000000000800, 0), 0x1.0000000000001p+127);
501 try test__floatuntidf(make_uti(0x8000010000000000, 0), 0x1.000002p+127);
502 try test__floatuntidf(make_uti(0x8000000000001000, 0), 0x1.0000000000002p+127);
503
504 try test__floatuntidf(make_uti(0x8000000000000000, 0), 0x1.000000p+127);
505 try test__floatuntidf(make_uti(0x8000000000000001, 0), 0x1.0000000000000002p+127);
506
507 try test__floatuntidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);
508
509 try test__floatuntidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
510 try test__floatuntidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);
511 try test__floatuntidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
512 try test__floatuntidf(0x0007FB72EC000000, 0x1.FEDCBBp+50);
513 try test__floatuntidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
514
515 try test__floatuntidf(0x0007FB72E6000000, 0x1.FEDCB98p+50);
516 try test__floatuntidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
517 try test__floatuntidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
518 try test__floatuntidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
519 try test__floatuntidf(0x0007FB72E4000000, 0x1.FEDCB9p+50);
520
521 try test__floatuntidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
522 try test__floatuntidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
523 try test__floatuntidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
524 try test__floatuntidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
525 try test__floatuntidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
526 try test__floatuntidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
527 try test__floatuntidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
528 try test__floatuntidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
529 try test__floatuntidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
530 try test__floatuntidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
531 try test__floatuntidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
532 try test__floatuntidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
533 try test__floatuntidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
534 try test__floatuntidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
535 try test__floatuntidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
536
537 try test__floatuntidf(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
538 try test__floatuntidf(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121);
539 try test__floatuntidf(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121);
540 try test__floatuntidf(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121);
541 try test__floatuntidf(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121);
542 try test__floatuntidf(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121);
543 try test__floatuntidf(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121);
544 try test__floatuntidf(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121);
545 try test__floatuntidf(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121);
546 try test__floatuntidf(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121);
547 try test__floatuntidf(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121);
548 try test__floatuntidf(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121);
549 try test__floatuntidf(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121);
550 try test__floatuntidf(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121);
551 try test__floatuntidf(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
552}
553
554fn test__floatsitf(a: i32, expected: u128) !void {
555 const r = __floatsitf(a);
448test f64_floatFromInt_i128 {
449 try test_f64_floatFromInt_i128(0, 0.0);
450
451 try test_f64_floatFromInt_i128(1, 1.0);
452 try test_f64_floatFromInt_i128(2, 2.0);
453 try test_f64_floatFromInt_i128(20, 20.0);
454 try test_f64_floatFromInt_i128(-1, -1.0);
455 try test_f64_floatFromInt_i128(-2, -2.0);
456 try test_f64_floatFromInt_i128(-20, -20.0);
457
458 try test_f64_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
459 try test_f64_floatFromInt_i128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
460 try test_f64_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
461 try test_f64_floatFromInt_i128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
462
463 try test_f64_floatFromInt_i128(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126);
464 try test_f64_floatFromInt_i128(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126);
465 try test_f64_floatFromInt_i128(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126);
466 try test_f64_floatFromInt_i128(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126);
467
468 try test_f64_floatFromInt_i128(make_ti(0x8000000000000000, 0), -0x1.000000p+127);
469 try test_f64_floatFromInt_i128(make_ti(0x8000000000000001, 0), -0x1.000000p+127);
470
471 try test_f64_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
472
473 try test_f64_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
474 try test_f64_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBACp+50);
475 try test_f64_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
476 try test_f64_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBBp+50);
477 try test_f64_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
478
479 try test_f64_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCB98p+50);
480 try test_f64_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
481 try test_f64_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
482 try test_f64_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
483 try test_f64_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB9p+50);
484
485 try test_f64_floatFromInt_i128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
486 try test_f64_floatFromInt_i128(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
487 try test_f64_floatFromInt_i128(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
488 try test_f64_floatFromInt_i128(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
489 try test_f64_floatFromInt_i128(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
490 try test_f64_floatFromInt_i128(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
491 try test_f64_floatFromInt_i128(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
492 try test_f64_floatFromInt_i128(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
493 try test_f64_floatFromInt_i128(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
494 try test_f64_floatFromInt_i128(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
495 try test_f64_floatFromInt_i128(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
496 try test_f64_floatFromInt_i128(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
497 try test_f64_floatFromInt_i128(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
498 try test_f64_floatFromInt_i128(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
499 try test_f64_floatFromInt_i128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
500
501 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
502 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121);
503 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121);
504 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121);
505 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121);
506 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121);
507 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121);
508 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121);
509 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121);
510 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121);
511 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121);
512 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121);
513 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121);
514 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121);
515 try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
516}
517
518test f64_floatFromInt_u128 {
519 try test_f64_floatFromInt_u128(0, 0.0);
520
521 try test_f64_floatFromInt_u128(1, 1.0);
522 try test_f64_floatFromInt_u128(2, 2.0);
523 try test_f64_floatFromInt_u128(20, 20.0);
524
525 try test_f64_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
526 try test_f64_floatFromInt_u128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
527 try test_f64_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
528 try test_f64_floatFromInt_u128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
529
530 try test_f64_floatFromInt_u128(make_uti(0x8000008000000000, 0), 0x1.000001p+127);
531 try test_f64_floatFromInt_u128(make_uti(0x8000000000000800, 0), 0x1.0000000000001p+127);
532 try test_f64_floatFromInt_u128(make_uti(0x8000010000000000, 0), 0x1.000002p+127);
533 try test_f64_floatFromInt_u128(make_uti(0x8000000000001000, 0), 0x1.0000000000002p+127);
534
535 try test_f64_floatFromInt_u128(make_uti(0x8000000000000000, 0), 0x1.000000p+127);
536 try test_f64_floatFromInt_u128(make_uti(0x8000000000000001, 0), 0x1.0000000000000002p+127);
537
538 try test_f64_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
539
540 try test_f64_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
541 try test_f64_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50);
542 try test_f64_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
543 try test_f64_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50);
544 try test_f64_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
545
546 try test_f64_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50);
547 try test_f64_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
548 try test_f64_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
549 try test_f64_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
550 try test_f64_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50);
551
552 try test_f64_floatFromInt_u128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
553 try test_f64_floatFromInt_u128(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
554 try test_f64_floatFromInt_u128(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
555 try test_f64_floatFromInt_u128(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
556 try test_f64_floatFromInt_u128(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
557 try test_f64_floatFromInt_u128(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
558 try test_f64_floatFromInt_u128(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
559 try test_f64_floatFromInt_u128(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
560 try test_f64_floatFromInt_u128(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
561 try test_f64_floatFromInt_u128(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
562 try test_f64_floatFromInt_u128(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
563 try test_f64_floatFromInt_u128(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
564 try test_f64_floatFromInt_u128(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
565 try test_f64_floatFromInt_u128(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
566 try test_f64_floatFromInt_u128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
567
568 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
569 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121);
570 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121);
571 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121);
572 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121);
573 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121);
574 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121);
575 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121);
576 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121);
577 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121);
578 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121);
579 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121);
580 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121);
581 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121);
582 try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
583}
584
585fn test_f128_floatFromInt_i32(a: i32, expected: u128) !void {
586 const r = f128_floatFromInt_i32(a);
556587 try std.testing.expect(@as(u128, @bitCast(r)) == expected);
557588}
558589
559test "floatsitf" {
560 try test__floatsitf(0, 0);
561 try test__floatsitf(0x7FFFFFFF, 0x401dfffffffc00000000000000000000);
562 try test__floatsitf(0x12345678, 0x401b2345678000000000000000000000);
563 try test__floatsitf(-0x12345678, 0xc01b2345678000000000000000000000);
564 try test__floatsitf(@bitCast(@as(u32, @intCast(0xffffffff))), 0xbfff0000000000000000000000000000);
565 try test__floatsitf(@bitCast(@as(u32, @intCast(0x80000000))), 0xc01e0000000000000000000000000000);
566}
567
568fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void {
569 const x = __floatunsitf(a);
590fn test_f128_floatFromInt_u32(a: u32, expected_hi: u64, expected_lo: u64) !void {
591 const x = f128_floatFromInt_u32(a);
570592
571593 const x_repr: u128 = @bitCast(x);
572594 const x_hi: u64 = @intCast(x_repr >> 64);
......@@ -581,24 +603,32 @@ fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void {
581603 return;
582604 }
583605 }
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);
586616}
587617
588test "floatunsitf" {
589 try test__floatunsitf(0x7fffffff, 0x401dfffffffc0000, 0x0);
590 try test__floatunsitf(0, 0x0, 0x0);
591 try test__floatunsitf(0xffffffff, 0x401efffffffe0000, 0x0);
592 try test__floatunsitf(0x12345678, 0x401b234567800000, 0x0);
618test f128_floatFromInt_u32 {
619 try test_f128_floatFromInt_u32(0x7fffffff, 0x401dfffffffc0000, 0x0);
620 try test_f128_floatFromInt_u32(0, 0x0, 0x0);
621 try test_f128_floatFromInt_u32(0xffffffff, 0x401efffffffe0000, 0x0);
622 try test_f128_floatFromInt_u32(0x12345678, 0x401b234567800000, 0x0);
593623}
594624
595fn test__floatditf(a: i64, expected: f128) !void {
596 const x = __floatditf(a);
625fn test_f128_floatFromInt_i64(a: i64, expected: f128) !void {
626 const x = f128_floatFromInt_i64(a);
597627 try testing.expect(x == expected);
598628}
599629
600fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void {
601 const x = __floatunditf(a);
630fn test_f128_floatFromInt_u64(a: u64, expected_hi: u64, expected_lo: u64) !void {
631 const x = f128_floatFromInt_u64(a);
602632
603633 const x_repr: u128 = @bitCast(x);
604634 const x_hi: u64 = @intCast(x_repr >> 64);
......@@ -613,208 +643,207 @@ fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void {
613643 return;
614644 }
615645 }
616
617 @panic("__floatunditf test failure");
618}
619
620test "floatditf" {
621 try test__floatditf(0x7fffffffffffffff, make_tf(0x403dffffffffffff, 0xfffc000000000000));
622 try test__floatditf(0x123456789abcdef1, make_tf(0x403b23456789abcd, 0xef10000000000000));
623 try test__floatditf(0x2, make_tf(0x4000000000000000, 0x0));
624 try test__floatditf(0x1, make_tf(0x3fff000000000000, 0x0));
625 try test__floatditf(0x0, make_tf(0x0, 0x0));
626 try test__floatditf(@bitCast(@as(u64, 0xffffffffffffffff)), make_tf(0xbfff000000000000, 0x0));
627 try test__floatditf(@bitCast(@as(u64, 0xfffffffffffffffe)), make_tf(0xc000000000000000, 0x0));
628 try test__floatditf(-0x123456789abcdef1, make_tf(0xc03b23456789abcd, 0xef10000000000000));
629 try test__floatditf(@bitCast(@as(u64, 0x8000000000000000)), make_tf(0xc03e000000000000, 0x0));
630}
631
632test "floatunditf" {
633 try test__floatunditf(0xffffffffffffffff, 0x403effffffffffff, 0xfffe000000000000);
634 try test__floatunditf(0xfffffffffffffffe, 0x403effffffffffff, 0xfffc000000000000);
635 try test__floatunditf(0x8000000000000000, 0x403e000000000000, 0x0);
636 try test__floatunditf(0x7fffffffffffffff, 0x403dffffffffffff, 0xfffc000000000000);
637 try test__floatunditf(0x123456789abcdef1, 0x403b23456789abcd, 0xef10000000000000);
638 try test__floatunditf(0x2, 0x4000000000000000, 0x0);
639 try test__floatunditf(0x1, 0x3fff000000000000, 0x0);
640 try test__floatunditf(0x0, 0x0, 0x0);
641}
642
643fn test__floattitf(a: i128, expected: f128) !void {
644 const x = __floattitf(a);
646 return error.TestFailure;
647}
648
649test f128_floatFromInt_i64 {
650 try test_f128_floatFromInt_i64(0x7fffffffffffffff, make_tf(0x403dffffffffffff, 0xfffc000000000000));
651 try test_f128_floatFromInt_i64(0x123456789abcdef1, make_tf(0x403b23456789abcd, 0xef10000000000000));
652 try test_f128_floatFromInt_i64(0x2, make_tf(0x4000000000000000, 0x0));
653 try test_f128_floatFromInt_i64(0x1, make_tf(0x3fff000000000000, 0x0));
654 try test_f128_floatFromInt_i64(0x0, make_tf(0x0, 0x0));
655 try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0xffffffffffffffff)), make_tf(0xbfff000000000000, 0x0));
656 try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0xfffffffffffffffe)), make_tf(0xc000000000000000, 0x0));
657 try test_f128_floatFromInt_i64(-0x123456789abcdef1, make_tf(0xc03b23456789abcd, 0xef10000000000000));
658 try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000000)), make_tf(0xc03e000000000000, 0x0));
659}
660
661test f128_floatFromInt_u64 {
662 try test_f128_floatFromInt_u64(0xffffffffffffffff, 0x403effffffffffff, 0xfffe000000000000);
663 try test_f128_floatFromInt_u64(0xfffffffffffffffe, 0x403effffffffffff, 0xfffc000000000000);
664 try test_f128_floatFromInt_u64(0x8000000000000000, 0x403e000000000000, 0x0);
665 try test_f128_floatFromInt_u64(0x7fffffffffffffff, 0x403dffffffffffff, 0xfffc000000000000);
666 try test_f128_floatFromInt_u64(0x123456789abcdef1, 0x403b23456789abcd, 0xef10000000000000);
667 try test_f128_floatFromInt_u64(0x2, 0x4000000000000000, 0x0);
668 try test_f128_floatFromInt_u64(0x1, 0x3fff000000000000, 0x0);
669 try test_f128_floatFromInt_u64(0x0, 0x0, 0x0);
670}
671
672fn test_f128_floatFromInt_i128(a: i128, expected: f128) !void {
673 const x = f128_floatFromInt_i128(a);
645674 try testing.expect(x == expected);
646675}
647676
648fn test__floatuntitf(a: u128, expected: f128) !void {
649 const x = __floatuntitf(a);
677fn test_f128_floatFromInt_u128(a: u128, expected: f128) !void {
678 const x = f128_floatFromInt_u128(a);
650679 try testing.expect(x == expected);
651680}
652681
653test "floattitf" {
654 try test__floattitf(0, 0.0);
655
656 try test__floattitf(1, 1.0);
657 try test__floattitf(2, 2.0);
658 try test__floattitf(20, 20.0);
659 try test__floattitf(-1, -1.0);
660 try test__floattitf(-2, -2.0);
661 try test__floattitf(-20, -20.0);
662
663 try test__floattitf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
664 try test__floattitf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
665 try test__floattitf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
666 try test__floattitf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
667
668 try test__floattitf(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126);
669 try test__floattitf(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126);
670 try test__floattitf(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126);
671 try test__floattitf(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126);
672
673 try test__floattitf(make_ti(0x8000000000000000, 0), -0x1.000000p+127);
674 try test__floattitf(make_ti(0x8000000000000001, 0), -0x1.FFFFFFFFFFFFFFFCp+126);
675
676 try test__floattitf(0x0007FB72E8000000, 0x1.FEDCBAp+50);
677
678 try test__floattitf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
679 try test__floattitf(0x0007FB72EB000000, 0x1.FEDCBACp+50);
680 try test__floattitf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
681 try test__floattitf(0x0007FB72EC000000, 0x1.FEDCBBp+50);
682 try test__floattitf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
683
684 try test__floattitf(0x0007FB72E6000000, 0x1.FEDCB98p+50);
685 try test__floattitf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
686 try test__floattitf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
687 try test__floattitf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
688 try test__floattitf(0x0007FB72E4000000, 0x1.FEDCB9p+50);
689
690 try test__floattitf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
691 try test__floattitf(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57);
692 try test__floattitf(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57);
693 try test__floattitf(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57);
694 try test__floattitf(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57);
695 try test__floattitf(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57);
696 try test__floattitf(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57);
697 try test__floattitf(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57);
698 try test__floattitf(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57);
699 try test__floattitf(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57);
700 try test__floattitf(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57);
701 try test__floattitf(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57);
702 try test__floattitf(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57);
703 try test__floattitf(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57);
704 try test__floattitf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
705
706 try test__floattitf(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
707 try test__floattitf(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121);
708 try test__floattitf(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121);
709 try test__floattitf(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121);
710 try test__floattitf(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121);
711 try test__floattitf(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121);
712 try test__floattitf(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121);
713 try test__floattitf(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121);
714 try test__floattitf(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121);
715 try test__floattitf(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121);
716 try test__floattitf(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121);
717 try test__floattitf(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121);
718 try test__floattitf(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121);
719 try test__floattitf(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121);
720 try test__floattitf(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
721
722 try test__floattitf(make_ti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63);
723
724 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124);
725 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124);
726 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124);
727 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124);
728 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124);
729 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124);
730 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124);
731 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124);
732 try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124);
733}
734
735test "floatuntitf" {
736 try test__floatuntitf(0, 0.0);
737
738 try test__floatuntitf(1, 1.0);
739 try test__floatuntitf(2, 2.0);
740 try test__floatuntitf(20, 20.0);
741
742 try test__floatuntitf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
743 try test__floatuntitf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
744 try test__floatuntitf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
745 try test__floatuntitf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
746 try test__floatuntitf(0x7FFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFEp+59);
747 try test__floatuntitf(0xFFFFFFFFFFFFFFFE, 0xF.FFFFFFFFFFFFFFEp+60);
748 try test__floatuntitf(0xFFFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFFp+60);
749
750 try test__floatuntitf(0x8000008000000000, 0x8.000008p+60);
751 try test__floatuntitf(0x8000000000000800, 0x8.0000000000008p+60);
752 try test__floatuntitf(0x8000010000000000, 0x8.00001p+60);
753 try test__floatuntitf(0x8000000000001000, 0x8.000000000001p+60);
754
755 try test__floatuntitf(0x8000000000000000, 0x8p+60);
756 try test__floatuntitf(0x8000000000000001, 0x8.000000000000001p+60);
757
758 try test__floatuntitf(0x0007FB72E8000000, 0x1.FEDCBAp+50);
759
760 try test__floatuntitf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
761 try test__floatuntitf(0x0007FB72EB000000, 0x1.FEDCBACp+50);
762 try test__floatuntitf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
763 try test__floatuntitf(0x0007FB72EC000000, 0x1.FEDCBBp+50);
764 try test__floatuntitf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
765
766 try test__floatuntitf(0x0007FB72E6000000, 0x1.FEDCB98p+50);
767 try test__floatuntitf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
768 try test__floatuntitf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
769 try test__floatuntitf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
770 try test__floatuntitf(0x0007FB72E4000000, 0x1.FEDCB9p+50);
771
772 try test__floatuntitf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
773 try test__floatuntitf(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57);
774 try test__floatuntitf(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57);
775 try test__floatuntitf(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57);
776 try test__floatuntitf(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57);
777 try test__floatuntitf(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57);
778 try test__floatuntitf(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57);
779 try test__floatuntitf(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57);
780 try test__floatuntitf(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57);
781 try test__floatuntitf(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57);
782 try test__floatuntitf(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57);
783 try test__floatuntitf(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57);
784 try test__floatuntitf(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57);
785 try test__floatuntitf(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57);
786 try test__floatuntitf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
787
788 try test__floatuntitf(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
789 try test__floatuntitf(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121);
790 try test__floatuntitf(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121);
791 try test__floatuntitf(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121);
792 try test__floatuntitf(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121);
793 try test__floatuntitf(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121);
794 try test__floatuntitf(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121);
795 try test__floatuntitf(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121);
796 try test__floatuntitf(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121);
797 try test__floatuntitf(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121);
798 try test__floatuntitf(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121);
799 try test__floatuntitf(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121);
800 try test__floatuntitf(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121);
801 try test__floatuntitf(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121);
802 try test__floatuntitf(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
803
804 try test__floatuntitf(make_uti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63);
805
806 try test__floatuntitf(make_uti(0xFFFFFFFFFFFFFFFF, 0x0000000000000000), 0x1.FFFFFFFFFFFFFFFEp+127);
807 try test__floatuntitf(make_uti(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0x1.0000000000000000p+128);
808
809 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124);
810 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124);
811 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124);
812 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124);
813 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124);
814 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124);
815 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124);
816 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124);
817 try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124);
682test f128_floatFromInt_i128 {
683 try test_f128_floatFromInt_i128(0, 0.0);
684
685 try test_f128_floatFromInt_i128(1, 1.0);
686 try test_f128_floatFromInt_i128(2, 2.0);
687 try test_f128_floatFromInt_i128(20, 20.0);
688 try test_f128_floatFromInt_i128(-1, -1.0);
689 try test_f128_floatFromInt_i128(-2, -2.0);
690 try test_f128_floatFromInt_i128(-20, -20.0);
691
692 try test_f128_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
693 try test_f128_floatFromInt_i128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
694 try test_f128_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
695 try test_f128_floatFromInt_i128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
696
697 try test_f128_floatFromInt_i128(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126);
698 try test_f128_floatFromInt_i128(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126);
699 try test_f128_floatFromInt_i128(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126);
700 try test_f128_floatFromInt_i128(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126);
701
702 try test_f128_floatFromInt_i128(make_ti(0x8000000000000000, 0), -0x1.000000p+127);
703 try test_f128_floatFromInt_i128(make_ti(0x8000000000000001, 0), -0x1.FFFFFFFFFFFFFFFCp+126);
704
705 try test_f128_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
706
707 try test_f128_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
708 try test_f128_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBACp+50);
709 try test_f128_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
710 try test_f128_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBBp+50);
711 try test_f128_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
712
713 try test_f128_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCB98p+50);
714 try test_f128_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
715 try test_f128_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
716 try test_f128_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
717 try test_f128_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB9p+50);
718
719 try test_f128_floatFromInt_i128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
720 try test_f128_floatFromInt_i128(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57);
721 try test_f128_floatFromInt_i128(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57);
722 try test_f128_floatFromInt_i128(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57);
723 try test_f128_floatFromInt_i128(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57);
724 try test_f128_floatFromInt_i128(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57);
725 try test_f128_floatFromInt_i128(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57);
726 try test_f128_floatFromInt_i128(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57);
727 try test_f128_floatFromInt_i128(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57);
728 try test_f128_floatFromInt_i128(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57);
729 try test_f128_floatFromInt_i128(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57);
730 try test_f128_floatFromInt_i128(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57);
731 try test_f128_floatFromInt_i128(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57);
732 try test_f128_floatFromInt_i128(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57);
733 try test_f128_floatFromInt_i128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
734
735 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
736 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121);
737 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121);
738 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121);
739 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121);
740 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121);
741 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121);
742 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121);
743 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121);
744 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121);
745 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121);
746 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121);
747 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121);
748 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121);
749 try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
750
751 try test_f128_floatFromInt_i128(make_ti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63);
752
753 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124);
754 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124);
755 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124);
756 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124);
757 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124);
758 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124);
759 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124);
760 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124);
761 try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124);
762}
763
764test f128_floatFromInt_u128 {
765 try test_f128_floatFromInt_u128(0, 0.0);
766
767 try test_f128_floatFromInt_u128(1, 1.0);
768 try test_f128_floatFromInt_u128(2, 2.0);
769 try test_f128_floatFromInt_u128(20, 20.0);
770
771 try test_f128_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
772 try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
773 try test_f128_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
774 try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
775 try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFEp+59);
776 try test_f128_floatFromInt_u128(0xFFFFFFFFFFFFFFFE, 0xF.FFFFFFFFFFFFFFEp+60);
777 try test_f128_floatFromInt_u128(0xFFFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFFp+60);
778
779 try test_f128_floatFromInt_u128(0x8000008000000000, 0x8.000008p+60);
780 try test_f128_floatFromInt_u128(0x8000000000000800, 0x8.0000000000008p+60);
781 try test_f128_floatFromInt_u128(0x8000010000000000, 0x8.00001p+60);
782 try test_f128_floatFromInt_u128(0x8000000000001000, 0x8.000000000001p+60);
783
784 try test_f128_floatFromInt_u128(0x8000000000000000, 0x8p+60);
785 try test_f128_floatFromInt_u128(0x8000000000000001, 0x8.000000000000001p+60);
786
787 try test_f128_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50);
788
789 try test_f128_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
790 try test_f128_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50);
791 try test_f128_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
792 try test_f128_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50);
793 try test_f128_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
794
795 try test_f128_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50);
796 try test_f128_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
797 try test_f128_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
798 try test_f128_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
799 try test_f128_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50);
800
801 try test_f128_floatFromInt_u128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
802 try test_f128_floatFromInt_u128(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57);
803 try test_f128_floatFromInt_u128(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57);
804 try test_f128_floatFromInt_u128(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57);
805 try test_f128_floatFromInt_u128(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57);
806 try test_f128_floatFromInt_u128(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57);
807 try test_f128_floatFromInt_u128(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57);
808 try test_f128_floatFromInt_u128(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57);
809 try test_f128_floatFromInt_u128(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57);
810 try test_f128_floatFromInt_u128(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57);
811 try test_f128_floatFromInt_u128(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57);
812 try test_f128_floatFromInt_u128(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57);
813 try test_f128_floatFromInt_u128(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57);
814 try test_f128_floatFromInt_u128(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57);
815 try test_f128_floatFromInt_u128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
816
817 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121);
818 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121);
819 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121);
820 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121);
821 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121);
822 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121);
823 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121);
824 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121);
825 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121);
826 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121);
827 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121);
828 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121);
829 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121);
830 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121);
831 try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121);
832
833 try test_f128_floatFromInt_u128(make_uti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63);
834
835 try test_f128_floatFromInt_u128(make_uti(0xFFFFFFFFFFFFFFFF, 0x0000000000000000), 0x1.FFFFFFFFFFFFFFFEp+127);
836 try test_f128_floatFromInt_u128(make_uti(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0x1.0000000000000000p+128);
837
838 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124);
839 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124);
840 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124);
841 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124);
842 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124);
843 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124);
844 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124);
845 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124);
846 try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124);
818847}
819848
820849fn make_ti(high: u64, low: u64) i128 {
......@@ -838,45 +867,40 @@ fn make_tf(high: u64, low: u64) f128 {
838867 return @bitCast(result);
839868}
840869
841test "conversion to f16" {
842 try testing.expect(__floatunsihf(@as(u32, 0)) == 0.0);
843 try testing.expect(__floatunsihf(@as(u32, 1)) == 1.0);
844 try testing.expect(__floatunsihf(@as(u32, 65504)) == 65504);
845 try testing.expect(__floatunsihf(@as(u32, 65504 + (1 << 4))) == math.inf(f16));
846}
847
848test "conversion to f32" {
849 try testing.expect(__floatunsisf(@as(u32, 0)) == 0.0);
850 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u32))) != 1.0);
851 try testing.expect(__floatsisf(@as(i32, math.minInt(i32))) != 1.0);
852 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24))) == math.maxInt(u24));
853 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 1) == math.maxInt(u24) + 1); // 0x100_0000 - Exact
854 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 2) == math.maxInt(u24) + 1); // 0x100_0001 - Tie: Rounds down to even
855 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 3) == math.maxInt(u24) + 3); // 0x100_0002 - Exact
856 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 4) == math.maxInt(u24) + 5); // 0x100_0003 - Tie: Rounds up to even
857 try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 5) == math.maxInt(u24) + 5); // 0x100_0004 - Exact
858}
859
860test "conversion to f80" {
861 const floatFromInt = @import("./float_from_int.zig").floatFromInt;
862
863 try testing.expect(floatFromInt(f80, @as(i80, -12)) == -12);
864 try testing.expect(@as(u80, @intFromFloat(floatFromInt(f80, @as(u64, math.maxInt(u64)) + 0))) == math.maxInt(u64) + 0);
865 try testing.expect(@as(u80, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1))) == math.maxInt(u64) + 1);
866
867 try testing.expect(floatFromInt(f80, @as(u32, 0)) == 0.0);
868 try testing.expect(floatFromInt(f80, @as(u32, 1)) == 1.0);
869 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u32, math.maxInt(u24)) + 0))) == math.maxInt(u24));
870 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 0))) == math.maxInt(u64));
871 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1))) == math.maxInt(u64) + 1); // Exact
872 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 2))) == math.maxInt(u64) + 1); // Rounds down
873 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 3))) == math.maxInt(u64) + 3); // Tie - Exact
874 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 4))) == math.maxInt(u64) + 5); // Rounds up
875
876 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 0))) == math.maxInt(u65) + 1); // Rounds up
877 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 1))) == math.maxInt(u65) + 1); // Exact
878 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 2))) == math.maxInt(u65) + 1); // Rounds down
879 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 3))) == math.maxInt(u65) + 1); // Tie - Rounds down
880 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 4))) == math.maxInt(u65) + 5); // Rounds up
881 try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 5))) == math.maxInt(u65) + 5); // Exact
870test f16_floatFromInt_u32 {
871 try testing.expect(f16_floatFromInt_u32(0) == 0.0);
872 try testing.expect(f16_floatFromInt_u32(1) == 1.0);
873 try testing.expect(f16_floatFromInt_u32(65504) == 65504);
874 try testing.expect(f16_floatFromInt_u32(65504 + (1 << 4)) == math.inf(f16));
875}
876
877test f80_floatFromInt_u32 {
878 try testing.expect(f80_floatFromInt_u32(0) == 0.0);
879 try testing.expect(f80_floatFromInt_u32(1) == 1.0);
880 try testing.expect(f80_floatFromInt_u32(math.maxInt(u24) + 0) == math.maxInt(u24));
881}
882
883test f80_floatFromInt_u64 {
884 try testing.expect(f80_floatFromInt_u64(math.maxInt(u64) + 0) == math.maxInt(u64) + 0);
885}
886
887test f80_floatFromInt_i128 {
888 try testing.expect(f80_floatFromInt_i128(-12) == -12);
889}
890
891test f80_floatFromInt_u128 {
892 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 1) == math.maxInt(u64) + 1);
893
894 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 0) == math.maxInt(u64));
895 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 1) == math.maxInt(u64) + 1); // Exact
896 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 2) == math.maxInt(u64) + 1); // Rounds down
897 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 3) == math.maxInt(u64) + 3); // Tie - Exact
898 try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 4) == math.maxInt(u64) + 5); // Rounds up
899
900 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 0) == math.maxInt(u65) + 1); // Rounds up
901 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 1) == math.maxInt(u65) + 1); // Exact
902 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 2) == math.maxInt(u65) + 1); // Rounds down
903 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 3) == math.maxInt(u65) + 1); // Tie - Rounds down
904 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 4) == math.maxInt(u65) + 5); // Rounds up
905 try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 5) == math.maxInt(u65) + 5); // Exact
882906}
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;
1515const expect = std.testing.expect;
1616
1717const compiler_rt = @import("../compiler_rt.zig");
18const symbol = @import("../compiler_rt.zig").symbol;
18const symbol = compiler_rt.symbol;
1919
2020comptime {
2121 // floor
......@@ -41,52 +41,92 @@ comptime {
4141 symbol(&ceill, "ceill");
4242}
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 {
4548 return impl(f16, .floor, x);
4649}
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 {
4955 return impl(f32, .floor, x);
5056}
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 {
5362 return impl(f64, .floor, x);
5463}
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 {
5769 return impl(f80, .floor, x);
5870}
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 {
6176 return impl(f128, .floor, x);
6277}
6378
6479pub 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 }
6686}
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 {
6992 return impl(f16, .ceil, x);
7093}
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 {
7399 return impl(f32, .ceil, x);
74100}
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 {
77106 return impl(f64, .ceil, x);
78107}
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 {
81113 return impl(f80, .ceil, x);
82114}
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 {
85120 return impl(f128, .ceil, x);
86121}
87122
88123pub 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 }
90130}
91131
92132inline 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 {
144184 }
145185}
146186
147test "floor16" {
148 try expect(__floorh(1.3) == 1.0);
149 try expect(__floorh(-1.3) == -2.0);
150 try expect(__floorh(0.2) == 0.0);
151}
152
153test "floor32" {
154 try expect(floorf(1.3) == 1.0);
155 try expect(floorf(-1.3) == -2.0);
156 try expect(floorf(0.2) == 0.0);
157}
158
159test "floor64" {
160 try expect(floor(1.3) == 1.0);
161 try expect(floor(-1.3) == -2.0);
162 try expect(floor(0.2) == 0.0);
163}
164
165test "floor80" {
166 try expect(__floorx(1.3) == 1.0);
167 try expect(__floorx(-1.3) == -2.0);
168 try expect(__floorx(0.2) == 0.0);
169}
170
171test "floor128" {
172 try expect(floorq(1.3) == 1.0);
173 try expect(floorq(-1.3) == -2.0);
174 try expect(floorq(0.2) == 0.0);
175}
176
177test "floor16.special" {
178 try expect(__floorh(0.0) == 0.0);
179 try expect(__floorh(-0.0) == -0.0);
180 try expect(math.isPositiveInf(__floorh(math.inf(f16))));
181 try expect(math.isNegativeInf(__floorh(-math.inf(f16))));
182 try expect(math.isNan(__floorh(math.nan(f16))));
183}
184
185test "floor32.special" {
186 try expect(floorf(0.0) == 0.0);
187 try expect(floorf(-0.0) == -0.0);
188 try expect(math.isPositiveInf(floorf(math.inf(f32))));
189 try expect(math.isNegativeInf(floorf(-math.inf(f32))));
190 try expect(math.isNan(floorf(math.nan(f32))));
191}
192
193test "floor64.special" {
194 try expect(floor(0.0) == 0.0);
195 try expect(floor(-0.0) == -0.0);
196 try expect(math.isPositiveInf(floor(math.inf(f64))));
197 try expect(math.isNegativeInf(floor(-math.inf(f64))));
198 try expect(math.isNan(floor(math.nan(f64))));
199}
200
201test "floor80.special" {
202 try expect(__floorx(0.0) == 0.0);
203 try expect(__floorx(-0.0) == -0.0);
204 try expect(math.isPositiveInf(__floorx(math.inf(f80))));
205 try expect(math.isNegativeInf(__floorx(-math.inf(f80))));
206 try expect(math.isNan(__floorx(math.nan(f80))));
207}
208
209test "floor128.special" {
210 try expect(floorq(0.0) == 0.0);
211 try expect(floorq(-0.0) == -0.0);
212 try expect(math.isPositiveInf(floorq(math.inf(f128))));
213 try expect(math.isNegativeInf(floorq(-math.inf(f128))));
214 try expect(math.isNan(floorq(math.nan(f128))));
215}
216
217test "ceil16" {
218 try expect(__ceilh(1.3) == 2.0);
219 try expect(__ceilh(-1.3) == -1.0);
220 try expect(__ceilh(0.2) == 1.0);
221}
222
223test "ceil32" {
224 try expect(ceilf(1.3) == 2.0);
225 try expect(ceilf(-1.3) == -1.0);
226 try expect(ceilf(0.2) == 1.0);
227}
228
229test "ceil64" {
230 try expect(ceil(1.3) == 2.0);
231 try expect(ceil(-1.3) == -1.0);
232 try expect(ceil(0.2) == 1.0);
233}
234
235test "ceil80" {
236 try expect(__ceilx(1.3) == 2.0);
237 try expect(__ceilx(-1.3) == -1.0);
238 try expect(__ceilx(0.2) == 1.0);
239}
240
241test "ceil128" {
242 try expect(ceilq(1.3) == 2.0);
243 try expect(ceilq(-1.3) == -1.0);
244 try expect(ceilq(0.2) == 1.0);
245}
246
247test "ceil16.special" {
248 try expect(__ceilh(0.0) == 0.0);
249 try expect(__ceilh(-0.0) == -0.0);
250 try expect(math.isPositiveInf(__ceilh(math.inf(f16))));
251 try expect(math.isNegativeInf(__ceilh(-math.inf(f16))));
252 try expect(math.isNan(__ceilh(math.nan(f16))));
253}
254
255test "ceil32.special" {
256 try expect(ceilf(0.0) == 0.0);
257 try expect(ceilf(-0.0) == -0.0);
258 try expect(math.isPositiveInf(ceilf(math.inf(f32))));
259 try expect(math.isNegativeInf(ceilf(-math.inf(f32))));
260 try expect(math.isNan(ceilf(math.nan(f32))));
261}
262
263test "ceil64.special" {
264 try expect(ceil(0.0) == 0.0);
265 try expect(ceil(-0.0) == -0.0);
266 try expect(math.isPositiveInf(ceil(math.inf(f64))));
267 try expect(math.isNegativeInf(ceil(-math.inf(f64))));
268 try expect(math.isNan(ceil(math.nan(f64))));
269}
270
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))));
187test floor_f16 {
188 try expect(floor_f16(1.3) == 1.0);
189 try expect(floor_f16(-1.3) == -2.0);
190 try expect(floor_f16(-0.2) == -1.0);
191 try expect(math.isPositiveZero(floor_f16(0.2)));
192 try expect(math.isPositiveZero(floor_f16(0.0)));
193 try expect(math.isNegativeZero(floor_f16(-0.0)));
194 try expect(math.isPositiveInf(floor_f16(math.inf(f16))));
195 try expect(math.isNegativeInf(floor_f16(-math.inf(f16))));
196 try expect(math.isNan(floor_f16(math.nan(f16))));
197}
198
199test floor_f32 {
200 try expect(floor_f32(1.3) == 1.0);
201 try expect(floor_f32(-1.3) == -2.0);
202 try expect(floor_f32(-0.2) == -1.0);
203 try expect(math.isPositiveZero(floor_f32(0.2)));
204 try expect(math.isPositiveZero(floor_f32(0.0)));
205 try expect(math.isNegativeZero(floor_f32(-0.0)));
206 try expect(math.isPositiveInf(floor_f32(math.inf(f32))));
207 try expect(math.isNegativeInf(floor_f32(-math.inf(f32))));
208 try expect(math.isNan(floor_f32(math.nan(f32))));
209}
210
211test floor_f64 {
212 try expect(floor_f64(1.3) == 1.0);
213 try expect(floor_f64(-1.3) == -2.0);
214 try expect(floor_f64(-0.2) == -1.0);
215 try expect(math.isPositiveZero(floor_f64(0.2)));
216 try expect(math.isPositiveZero(floor_f64(0.0)));
217 try expect(math.isNegativeZero(floor_f64(-0.0)));
218 try expect(math.isPositiveInf(floor_f64(math.inf(f64))));
219 try expect(math.isNegativeInf(floor_f64(-math.inf(f64))));
220 try expect(math.isNan(floor_f64(math.nan(f64))));
221}
222
223test floor_f80 {
224 try expect(floor_f80(1.3) == 1.0);
225 try expect(floor_f80(-1.3) == -2.0);
226 try expect(floor_f80(-0.2) == -1.0);
227 try expect(math.isPositiveZero(floor_f80(0.2)));
228 try expect(math.isPositiveZero(floor_f80(0.0)));
229 try expect(math.isNegativeZero(floor_f80(-0.0)));
230 try expect(math.isPositiveInf(floor_f80(math.inf(f80))));
231 try expect(math.isNegativeInf(floor_f80(-math.inf(f80))));
232 try expect(math.isNan(floor_f80(math.nan(f80))));
233}
234
235test floor_f128 {
236 try expect(floor_f128(1.3) == 1.0);
237 try expect(floor_f128(-1.3) == -2.0);
238 try expect(floor_f128(-0.2) == -1.0);
239 try expect(math.isPositiveZero(floor_f128(0.2)));
240 try expect(math.isPositiveZero(floor_f128(0.0)));
241 try expect(math.isNegativeZero(floor_f128(-0.0)));
242 try expect(math.isPositiveInf(floor_f128(math.inf(f128))));
243 try expect(math.isNegativeInf(floor_f128(-math.inf(f128))));
244 try expect(math.isNan(floor_f128(math.nan(f128))));
245}
246
247test ceil_f16 {
248 try expect(ceil_f16(1.3) == 2.0);
249 try expect(ceil_f16(-1.3) == -1.0);
250 try expect(ceil_f16(0.2) == 1.0);
251 try expect(math.isNegativeZero(ceil_f16(-0.2)));
252 try expect(math.isPositiveZero(ceil_f16(0.0)));
253 try expect(math.isNegativeZero(ceil_f16(-0.0)));
254 try expect(math.isPositiveInf(ceil_f16(math.inf(f16))));
255 try expect(math.isNegativeInf(ceil_f16(-math.inf(f16))));
256 try expect(math.isNan(ceil_f16(math.nan(f16))));
257}
258
259test ceil_f32 {
260 try expect(ceil_f32(1.3) == 2.0);
261 try expect(ceil_f32(-1.3) == -1.0);
262 try expect(ceil_f32(0.2) == 1.0);
263 try expect(math.isNegativeZero(ceil_f32(-0.2)));
264 try expect(math.isPositiveZero(ceil_f32(0.0)));
265 try expect(math.isNegativeZero(ceil_f32(-0.0)));
266 try expect(math.isPositiveInf(ceil_f32(math.inf(f32))));
267 try expect(math.isNegativeInf(ceil_f32(-math.inf(f32))));
268 try expect(math.isNan(ceil_f32(math.nan(f32))));
269}
270
271test ceil_f64 {
272 try expect(ceil_f64(1.3) == 2.0);
273 try expect(ceil_f64(-1.3) == -1.0);
274 try expect(ceil_f64(0.2) == 1.0);
275 try expect(math.isNegativeZero(ceil_f64(-0.2)));
276 try expect(math.isPositiveZero(ceil_f64(0.0)));
277 try expect(math.isNegativeZero(ceil_f64(-0.0)));
278 try expect(math.isPositiveInf(ceil_f64(math.inf(f64))));
279 try expect(math.isNegativeInf(ceil_f64(-math.inf(f64))));
280 try expect(math.isNan(ceil_f64(math.nan(f64))));
281}
282
283test ceil_f80 {
284 try expect(ceil_f80(1.3) == 2.0);
285 try expect(ceil_f80(-1.3) == -1.0);
286 try expect(ceil_f80(0.2) == 1.0);
287 try expect(math.isNegativeZero(ceil_f80(-0.2)));
288 try expect(math.isPositiveZero(ceil_f80(0.0)));
289 try expect(math.isNegativeZero(ceil_f80(-0.0)));
290 try expect(math.isPositiveInf(ceil_f80(math.inf(f80))));
291 try expect(math.isNegativeInf(ceil_f80(-math.inf(f80))));
292 try expect(math.isNan(ceil_f80(math.nan(f80))));
293}
294
295test ceil_f128 {
296 try expect(ceil_f128(1.3) == 2.0);
297 try expect(ceil_f128(-1.3) == -1.0);
298 try expect(ceil_f128(0.2) == 1.0);
299 try expect(math.isNegativeZero(ceil_f128(-0.2)));
300 try expect(math.isPositiveZero(ceil_f128(0.0)));
301 try expect(math.isNegativeZero(ceil_f128(-0.0)));
302 try expect(math.isPositiveInf(ceil_f128(math.inf(f128))));
303 try expect(math.isNegativeInf(ceil_f128(-math.inf(f128))));
304 try expect(math.isNan(ceil_f128(math.nan(f128))));
285305}
lib/compiler_rt/fma.zig+47-32
......@@ -23,12 +23,18 @@ comptime {
2323 symbol(&fmal, "fmal");
2424}
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 {
2730 // TODO: more efficient implementation
28 return @floatCast(fmaf(x, y, z));
31 return @floatCast(fma_f32(x, y, z));
2932}
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 {
3238 const xy = @as(f64, x) * y;
3339 const xy_z = xy + z;
3440 const u = @as(u64, @bitCast(xy_z));
......@@ -42,8 +48,11 @@ pub fn fmaf(x: f32, y: f32, z: f32) callconv(.c) f32 {
4248 }
4349}
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}
4554/// 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 {
4756 if (!math.isFinite(x) or !math.isFinite(y)) {
4857 return x * y + z;
4958 }
......@@ -90,11 +99,17 @@ pub fn fma(x: f64, y: f64, z: f64) callconv(.c) f64 {
9099 }
91100}
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 {
94106 // TODO: more efficient implementation
95 return @floatCast(fmaq(a, b, c));
107 return @floatCast(fma_f128(a, b, c));
96108}
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}
98113/// Fused multiply-add: Compute x * y + z with a single rounding error.
99114///
100115/// 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 {
102117///
103118/// Dekker, T. A Floating-Point Technique for Extending the
104119/// 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 {
106121 if (!math.isFinite(x) or !math.isFinite(y)) {
107122 return x * y + z;
108123 }
......@@ -151,10 +166,10 @@ pub fn fmaq(x: f128, y: f128, z: f128) callconv(.c) f128 {
151166
152167pub fn fmal(x: c_longdouble, y: c_longdouble, z: c_longdouble) callconv(.c) c_longdouble {
153168 switch (@typeInfo(c_longdouble).float.bits) {
154 64 => return fma(x, y, z),
155 80 => return __fmax(x, y, z),
156 128 => return fmaq(x, y, z),
157 else => @compileError("unreachable"),
169 64 => return fma_f64(x, y, z),
170 80 => return fma_f80(x, y, z),
171 128 => return fma_f128(x, y, z),
172 else => comptime unreachable,
158173 }
159174}
160175
......@@ -316,35 +331,35 @@ fn dd_mul128(a: f128, b: f128) dd128 {
316331test "32" {
317332 const epsilon = 0.000001;
318333
319 try expect(math.approxEqAbs(f32, fmaf(0.0, 5.0, 9.124), 9.124, epsilon));
320 try expect(math.approxEqAbs(f32, fmaf(0.2, 5.0, 9.124), 10.124, epsilon));
321 try expect(math.approxEqAbs(f32, fmaf(0.8923, 5.0, 9.124), 13.5855, epsilon));
322 try expect(math.approxEqAbs(f32, fmaf(1.5, 5.0, 9.124), 16.624, epsilon));
323 try expect(math.approxEqAbs(f32, fmaf(37.45, 5.0, 9.124), 196.374004, epsilon));
324 try expect(math.approxEqAbs(f32, fmaf(89.123, 5.0, 9.124), 454.739005, epsilon));
325 try expect(math.approxEqAbs(f32, fmaf(123123.234375, 5.0, 9.124), 615625.295875, epsilon));
334 try expect(math.approxEqAbs(f32, fma_f32(0.0, 5.0, 9.124), 9.124, epsilon));
335 try expect(math.approxEqAbs(f32, fma_f32(0.2, 5.0, 9.124), 10.124, epsilon));
336 try expect(math.approxEqAbs(f32, fma_f32(0.8923, 5.0, 9.124), 13.5855, epsilon));
337 try expect(math.approxEqAbs(f32, fma_f32(1.5, 5.0, 9.124), 16.624, epsilon));
338 try expect(math.approxEqAbs(f32, fma_f32(37.45, 5.0, 9.124), 196.374004, epsilon));
339 try expect(math.approxEqAbs(f32, fma_f32(89.123, 5.0, 9.124), 454.739005, epsilon));
340 try expect(math.approxEqAbs(f32, fma_f32(123123.234375, 5.0, 9.124), 615625.295875, epsilon));
326341}
327342
328343test "64" {
329344 const epsilon = 0.000001;
330345
331 try expect(math.approxEqAbs(f64, fma(0.0, 5.0, 9.124), 9.124, epsilon));
332 try expect(math.approxEqAbs(f64, fma(0.2, 5.0, 9.124), 10.124, epsilon));
333 try expect(math.approxEqAbs(f64, fma(0.8923, 5.0, 9.124), 13.5855, epsilon));
334 try expect(math.approxEqAbs(f64, fma(1.5, 5.0, 9.124), 16.624, epsilon));
335 try expect(math.approxEqAbs(f64, fma(37.45, 5.0, 9.124), 196.374, epsilon));
336 try expect(math.approxEqAbs(f64, fma(89.123, 5.0, 9.124), 454.739, epsilon));
337 try expect(math.approxEqAbs(f64, fma(123123.234375, 5.0, 9.124), 615625.295875, epsilon));
346 try expect(math.approxEqAbs(f64, fma_f64(0.0, 5.0, 9.124), 9.124, epsilon));
347 try expect(math.approxEqAbs(f64, fma_f64(0.2, 5.0, 9.124), 10.124, epsilon));
348 try expect(math.approxEqAbs(f64, fma_f64(0.8923, 5.0, 9.124), 13.5855, epsilon));
349 try expect(math.approxEqAbs(f64, fma_f64(1.5, 5.0, 9.124), 16.624, epsilon));
350 try expect(math.approxEqAbs(f64, fma_f64(37.45, 5.0, 9.124), 196.374, epsilon));
351 try expect(math.approxEqAbs(f64, fma_f64(89.123, 5.0, 9.124), 454.739, epsilon));
352 try expect(math.approxEqAbs(f64, fma_f64(123123.234375, 5.0, 9.124), 615625.295875, epsilon));
338353}
339354
340355test "128" {
341356 const epsilon = 0.000001;
342357
343 try expect(math.approxEqAbs(f128, fmaq(0.0, 5.0, 9.124), 9.124, epsilon));
344 try expect(math.approxEqAbs(f128, fmaq(0.2, 5.0, 9.124), 10.124, epsilon));
345 try expect(math.approxEqAbs(f128, fmaq(0.8923, 5.0, 9.124), 13.5855, epsilon));
346 try expect(math.approxEqAbs(f128, fmaq(1.5, 5.0, 9.124), 16.624, epsilon));
347 try expect(math.approxEqAbs(f128, fmaq(37.45, 5.0, 9.124), 196.374, epsilon));
348 try expect(math.approxEqAbs(f128, fmaq(89.123, 5.0, 9.124), 454.739, epsilon));
349 try expect(math.approxEqAbs(f128, fmaq(123123.234375, 5.0, 9.124), 615625.295875, epsilon));
358 try expect(math.approxEqAbs(f128, fma_f128(0.0, 5.0, 9.124), 9.124, epsilon));
359 try expect(math.approxEqAbs(f128, fma_f128(0.2, 5.0, 9.124), 10.124, epsilon));
360 try expect(math.approxEqAbs(f128, fma_f128(0.8923, 5.0, 9.124), 13.5855, epsilon));
361 try expect(math.approxEqAbs(f128, fma_f128(1.5, 5.0, 9.124), 16.624, epsilon));
362 try expect(math.approxEqAbs(f128, fma_f128(37.45, 5.0, 9.124), 196.374, epsilon));
363 try expect(math.approxEqAbs(f128, fma_f128(89.123, 5.0, 9.124), 454.739, epsilon));
364 try expect(math.approxEqAbs(f128, fma_f128(123123.234375, 5.0, 9.124), 615625.295875, epsilon));
350365}
lib/compiler_rt/fmax.zig+24-9
......@@ -17,32 +17,47 @@ comptime {
1717 symbol(&fmaxl, "fmaxl");
1818}
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 {
2124 return generic_fmax(f16, x, y);
2225}
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 {
2531 return generic_fmax(f32, x, y);
2632}
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 {
2938 return generic_fmax(f64, x, y);
3039}
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 {
3345 return generic_fmax(f80, x, y);
3446}
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 {
3752 return generic_fmax(f128, x, y);
3853}
3954
4055pub fn fmaxl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble {
4156 switch (@typeInfo(c_longdouble).float.bits) {
42 64 => return fmax(x, y),
43 80 => return __fmaxx(x, y),
44 128 => return fmaxq(x, y),
45 else => @compileError("unreachable"),
57 64 => return fmax_f64(x, y),
58 80 => return fmax_f80(x, y),
59 128 => return fmax_f128(x, y),
60 else => comptime unreachable,
4661 }
4762}
4863
lib/compiler_rt/fmin.zig+24-9
......@@ -17,32 +17,47 @@ comptime {
1717 symbol(&fminl, "fminl");
1818}
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 {
2124 return generic_fmin(f16, x, y);
2225}
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 {
2531 return generic_fmin(f32, x, y);
2632}
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 {
2938 return generic_fmin(f64, x, y);
3039}
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 {
3345 return generic_fmin(f80, x, y);
3446}
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 {
3752 return generic_fmin(f128, x, y);
3853}
3954
4055pub fn fminl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble {
4156 switch (@typeInfo(c_longdouble).float.bits) {
42 64 => return fmin(x, y),
43 80 => return __fminx(x, y),
44 128 => return fminq(x, y),
45 else => @compileError("unreachable"),
57 64 => return fmin_f64(x, y),
58 80 => return fmin_f80(x, y),
59 128 => return fmin_f128(x, y),
60 else => comptime unreachable,
4661 }
4762}
4863
lib/compiler_rt/fmod.zig+49-34
......@@ -19,22 +19,34 @@ comptime {
1919 symbol(&fmodl, "fmodl");
2020}
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 {
2326 // TODO: more efficient implementation
24 return @floatCast(fmodf(x, y));
27 return @floatCast(fmod_f32(x, y));
2528}
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 {
2834 return generic_fmod(f32, x, y);
2935}
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 {
3241 return generic_fmod(f64, x, y);
3342}
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}
3547/// fmodx - floating modulo large, returns the remainder of division for f80 types
3648/// 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 {
3850 const T = f80;
3951 const Z = @Int(.unsigned, @bitSizeOf(T));
4052
......@@ -130,9 +142,12 @@ pub fn __fmodx(a: f80, b: f80) callconv(.c) f80 {
130142 }
131143}
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}
133148/// fmodq - floating modulo large, returns the remainder of division for f128 types
134149/// 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 {
136151 var amod = a;
137152 var bmod = b;
138153 const aPtr_u64: [*]u64 = @ptrCast(&amod);
......@@ -251,10 +266,10 @@ pub fn fmodq(a: f128, b: f128) callconv(.c) f128 {
251266
252267pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.c) c_longdouble {
253268 switch (@typeInfo(c_longdouble).float.bits) {
254 64 => return fmod(a, b),
255 80 => return __fmodx(a, b),
256 128 => return fmodq(a, b),
257 else => @compileError("unreachable"),
269 64 => return fmod_f64(a, b),
270 80 => return fmod_f80(a, b),
271 128 => return fmod_f128(a, b),
272 else => comptime unreachable,
258273 }
259274}
260275
......@@ -342,42 +357,42 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T {
342357 return @bitCast(ux);
343358}
344359
345test "fmodf" {
360test fmod_f32 {
346361 const nan_val = math.nan(f32);
347362 const inf_val = math.inf(f32);
348363
349 try std.testing.expect(math.isNan(fmodf(nan_val, 1.0)));
350 try std.testing.expect(math.isNan(fmodf(1.0, nan_val)));
351 try std.testing.expect(math.isNan(fmodf(inf_val, 1.0)));
352 try std.testing.expect(math.isNan(fmodf(0.0, 0.0)));
353 try std.testing.expect(math.isNan(fmodf(1.0, 0.0)));
364 try std.testing.expect(math.isNan(fmod_f32(nan_val, 1.0)));
365 try std.testing.expect(math.isNan(fmod_f32(1.0, nan_val)));
366 try std.testing.expect(math.isNan(fmod_f32(inf_val, 1.0)));
367 try std.testing.expect(math.isNan(fmod_f32(0.0, 0.0)));
368 try std.testing.expect(math.isNan(fmod_f32(1.0, 0.0)));
354369
355 try std.testing.expectEqual(@as(f32, 0.0), fmodf(0.0, 2.0));
356 try std.testing.expectEqual(@as(f32, -0.0), fmodf(-0.0, 2.0));
370 try std.testing.expectEqual(@as(f32, 0.0), fmod_f32(0.0, 2.0));
371 try std.testing.expectEqual(@as(f32, -0.0), fmod_f32(-0.0, 2.0));
357372
358 try std.testing.expectEqual(@as(f32, -2.0), fmodf(-32.0, 10.0));
359 try std.testing.expectEqual(@as(f32, -2.0), fmodf(-32.0, -10.0));
360 try std.testing.expectEqual(@as(f32, 2.0), fmodf(32.0, 10.0));
361 try std.testing.expectEqual(@as(f32, 2.0), fmodf(32.0, -10.0));
373 try std.testing.expectEqual(@as(f32, -2.0), fmod_f32(-32.0, 10.0));
374 try std.testing.expectEqual(@as(f32, -2.0), fmod_f32(-32.0, -10.0));
375 try std.testing.expectEqual(@as(f32, 2.0), fmod_f32(32.0, 10.0));
376 try std.testing.expectEqual(@as(f32, 2.0), fmod_f32(32.0, -10.0));
362377}
363378
364test "fmod" {
379test fmod_f64 {
365380 const nan_val = math.nan(f64);
366381 const inf_val = math.inf(f64);
367382
368 try std.testing.expect(math.isNan(fmod(nan_val, 1.0)));
369 try std.testing.expect(math.isNan(fmod(1.0, nan_val)));
370 try std.testing.expect(math.isNan(fmod(inf_val, 1.0)));
371 try std.testing.expect(math.isNan(fmod(0.0, 0.0)));
372 try std.testing.expect(math.isNan(fmod(1.0, 0.0)));
383 try std.testing.expect(math.isNan(fmod_f64(nan_val, 1.0)));
384 try std.testing.expect(math.isNan(fmod_f64(1.0, nan_val)));
385 try std.testing.expect(math.isNan(fmod_f64(inf_val, 1.0)));
386 try std.testing.expect(math.isNan(fmod_f64(0.0, 0.0)));
387 try std.testing.expect(math.isNan(fmod_f64(1.0, 0.0)));
373388
374 try std.testing.expectEqual(@as(f64, 0.0), fmod(0.0, 2.0));
375 try std.testing.expectEqual(@as(f64, -0.0), fmod(-0.0, 2.0));
389 try std.testing.expectEqual(@as(f64, 0.0), fmod_f64(0.0, 2.0));
390 try std.testing.expectEqual(@as(f64, -0.0), fmod_f64(-0.0, 2.0));
376391
377 try std.testing.expectEqual(@as(f64, -2.0), fmod(-32.0, 10.0));
378 try std.testing.expectEqual(@as(f64, -2.0), fmod(-32.0, -10.0));
379 try std.testing.expectEqual(@as(f64, 2.0), fmod(32.0, 10.0));
380 try std.testing.expectEqual(@as(f64, 2.0), fmod(32.0, -10.0));
392 try std.testing.expectEqual(@as(f64, -2.0), fmod_f64(-32.0, 10.0));
393 try std.testing.expectEqual(@as(f64, -2.0), fmod_f64(-32.0, -10.0));
394 try std.testing.expectEqual(@as(f64, 2.0), fmod_f64(32.0, 10.0));
395 try std.testing.expectEqual(@as(f64, 2.0), fmod_f64(32.0, -10.0));
381396}
382397
383398test {
lib/compiler_rt/fmodq_test.zig+32-32
......@@ -1,52 +1,52 @@
11const std = @import("std");
2const fmod = @import("fmod.zig");
2const fmod_f128 = @import("fmod.zig").fmod_f128;
33const testing = std.testing;
44
5fn test_fmodq(a: f128, b: f128, exp: f128) !void {
6 const res = fmod.fmodq(a, b);
5fn test_fmod_f128(a: f128, b: f128, exp: f128) !void {
6 const res = fmod_f128(a, b);
77 try testing.expect(exp == res);
88}
99
10fn test_fmodq_nans() !void {
11 try testing.expect(std.math.isNan(fmod.fmodq(1.0, std.math.nan(f128))));
12 try testing.expect(std.math.isNan(fmod.fmodq(1.0, -std.math.nan(f128))));
13 try testing.expect(std.math.isNan(fmod.fmodq(std.math.nan(f128), 1.0)));
14 try testing.expect(std.math.isNan(fmod.fmodq(-std.math.nan(f128), 1.0)));
10fn test_fmod_f128_nans() !void {
11 try testing.expect(std.math.isNan(fmod_f128(1.0, std.math.nan(f128))));
12 try testing.expect(std.math.isNan(fmod_f128(1.0, -std.math.nan(f128))));
13 try testing.expect(std.math.isNan(fmod_f128(std.math.nan(f128), 1.0)));
14 try testing.expect(std.math.isNan(fmod_f128(-std.math.nan(f128), 1.0)));
1515}
1616
17fn test_fmodq_infs() !void {
18 try testing.expect(fmod.fmodq(1.0, std.math.inf(f128)) == 1.0);
19 try testing.expect(fmod.fmodq(1.0, -std.math.inf(f128)) == 1.0);
20 try testing.expect(std.math.isNan(fmod.fmodq(std.math.inf(f128), 1.0)));
21 try testing.expect(std.math.isNan(fmod.fmodq(-std.math.inf(f128), 1.0)));
17fn test_fmod_f128_infs() !void {
18 try testing.expect(fmod_f128(1.0, std.math.inf(f128)) == 1.0);
19 try testing.expect(fmod_f128(1.0, -std.math.inf(f128)) == 1.0);
20 try testing.expect(std.math.isNan(fmod_f128(std.math.inf(f128), 1.0)));
21 try testing.expect(std.math.isNan(fmod_f128(-std.math.inf(f128), 1.0)));
2222}
2323
24test "fmodq" {
25 try test_fmodq(6.8, 4.0, 2.8);
26 try test_fmodq(6.8, -4.0, 2.8);
27 try test_fmodq(-6.8, 4.0, -2.8);
28 try test_fmodq(-6.8, -4.0, -2.8);
29 try test_fmodq(3.0, 2.0, 1.0);
30 try test_fmodq(-5.0, 3.0, -2.0);
31 try test_fmodq(3.0, 2.0, 1.0);
32 try test_fmodq(1.0, 2.0, 1.0);
33 try test_fmodq(0.0, 1.0, 0.0);
34 try test_fmodq(-0.0, 1.0, -0.0);
35 try test_fmodq(7046119.0, 5558362.0, 1487757.0);
36 try test_fmodq(9010357.0, 1957236.0, 1181413.0);
37 try test_fmodq(5192296858534827628530496329220095, 10.0, 5.0);
38 try test_fmodq(5192296858534827628530496329220095, 922337203681230954775807, 220474884073715748246157);
24test fmod_f128 {
25 try test_fmod_f128(6.8, 4.0, 2.8);
26 try test_fmod_f128(6.8, -4.0, 2.8);
27 try test_fmod_f128(-6.8, 4.0, -2.8);
28 try test_fmod_f128(-6.8, -4.0, -2.8);
29 try test_fmod_f128(3.0, 2.0, 1.0);
30 try test_fmod_f128(-5.0, 3.0, -2.0);
31 try test_fmod_f128(3.0, 2.0, 1.0);
32 try test_fmod_f128(1.0, 2.0, 1.0);
33 try test_fmod_f128(0.0, 1.0, 0.0);
34 try test_fmod_f128(-0.0, 1.0, -0.0);
35 try test_fmod_f128(7046119.0, 5558362.0, 1487757.0);
36 try test_fmod_f128(9010357.0, 1957236.0, 1181413.0);
37 try test_fmod_f128(5192296858534827628530496329220095, 10.0, 5.0);
38 try test_fmod_f128(5192296858534827628530496329220095, 922337203681230954775807, 220474884073715748246157);
3939
4040 // Denormals
4141 const a1: f128 = 0xedcb34a235253948765432134674p-16494;
4242 const b1: f128 = 0x5d2e38791cfbc0737402da5a9518p-16494;
4343 const exp1: f128 = 0x336ec3affb2db8618e4e7d5e1c44p-16494;
44 try test_fmodq(a1, b1, exp1);
44 try test_fmod_f128(a1, b1, exp1);
4545 const a2: f128 = 0x0.7654_3210_fdec_ba98_7654_3210_fdecp-16382;
4646 const b2: f128 = 0x0.0012_fdac_bdef_1234_fdec_3222_1111p-16382;
4747 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();
51 try test_fmodq_infs();
50 try test_fmod_f128_nans();
51 try test_fmod_f128_infs();
5252}
lib/compiler_rt/fmodx_test.zig+31-31
......@@ -1,52 +1,52 @@
11const std = @import("std");
22const builtin = @import("builtin");
3const fmod = @import("fmod.zig");
3const fmod_f80 = @import("fmod.zig").fmod_f80;
44const testing = std.testing;
55
6fn test_fmodx(a: f80, b: f80, exp: f80) !void {
7 const res = fmod.__fmodx(a, b);
6fn test_fmod_f80(a: f80, b: f80, exp: f80) !void {
7 const res = fmod_f80(a, b);
88 try testing.expect(exp == res);
99}
1010
11fn test_fmodx_nans() !void {
12 try testing.expect(std.math.isNan(fmod.__fmodx(1.0, std.math.nan(f80))));
13 try testing.expect(std.math.isNan(fmod.__fmodx(1.0, -std.math.nan(f80))));
14 try testing.expect(std.math.isNan(fmod.__fmodx(std.math.nan(f80), 1.0)));
15 try testing.expect(std.math.isNan(fmod.__fmodx(-std.math.nan(f80), 1.0)));
11fn test_fmod_f80_nans() !void {
12 try testing.expect(std.math.isNan(fmod_f80(1.0, std.math.nan(f80))));
13 try testing.expect(std.math.isNan(fmod_f80(1.0, -std.math.nan(f80))));
14 try testing.expect(std.math.isNan(fmod_f80(std.math.nan(f80), 1.0)));
15 try testing.expect(std.math.isNan(fmod_f80(-std.math.nan(f80), 1.0)));
1616}
1717
18fn test_fmodx_infs() !void {
19 try testing.expect(fmod.__fmodx(1.0, std.math.inf(f80)) == 1.0);
20 try testing.expect(fmod.__fmodx(1.0, -std.math.inf(f80)) == 1.0);
21 try testing.expect(std.math.isNan(fmod.__fmodx(std.math.inf(f80), 1.0)));
22 try testing.expect(std.math.isNan(fmod.__fmodx(-std.math.inf(f80), 1.0)));
18fn test_fmod_f80_infs() !void {
19 try testing.expect(fmod_f80(1.0, std.math.inf(f80)) == 1.0);
20 try testing.expect(fmod_f80(1.0, -std.math.inf(f80)) == 1.0);
21 try testing.expect(std.math.isNan(fmod_f80(std.math.inf(f80), 1.0)));
22 try testing.expect(std.math.isNan(fmod_f80(-std.math.inf(f80), 1.0)));
2323}
2424
25test "fmodx" {
26 try test_fmodx(6.4, 4.0, 2.4);
27 try test_fmodx(6.4, -4.0, 2.4);
28 try test_fmodx(-6.4, 4.0, -2.4);
29 try test_fmodx(-6.4, -4.0, -2.4);
30 try test_fmodx(3.0, 2.0, 1.0);
31 try test_fmodx(-5.0, 3.0, -2.0);
32 try test_fmodx(3.0, 2.0, 1.0);
33 try test_fmodx(1.0, 2.0, 1.0);
34 try test_fmodx(0.0, 1.0, 0.0);
35 try test_fmodx(-0.0, 1.0, -0.0);
36 try test_fmodx(7046119.0, 5558362.0, 1487757.0);
37 try test_fmodx(9010357.0, 1957236.0, 1181413.0);
38 try test_fmodx(9223372036854775807, 10.0, 7.0);
25test fmod_f80 {
26 try test_fmod_f80(6.4, 4.0, 2.4);
27 try test_fmod_f80(6.4, -4.0, 2.4);
28 try test_fmod_f80(-6.4, 4.0, -2.4);
29 try test_fmod_f80(-6.4, -4.0, -2.4);
30 try test_fmod_f80(3.0, 2.0, 1.0);
31 try test_fmod_f80(-5.0, 3.0, -2.0);
32 try test_fmod_f80(3.0, 2.0, 1.0);
33 try test_fmod_f80(1.0, 2.0, 1.0);
34 try test_fmod_f80(0.0, 1.0, 0.0);
35 try test_fmod_f80(-0.0, 1.0, -0.0);
36 try test_fmod_f80(7046119.0, 5558362.0, 1487757.0);
37 try test_fmod_f80(9010357.0, 1957236.0, 1181413.0);
38 try test_fmod_f80(9223372036854775807, 10.0, 7.0);
3939
4040 // Denormals
4141 const a1: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381;
4242 const b1: f80 = 0x0.2e97_1c3c_8e7d_e03ap-16381;
4343 const exp1: f80 = 0x0.19b7_61d7_fd96_dc30p-16381;
44 try test_fmodx(a1, b1, exp1);
44 try test_fmod_f80(a1, b1, exp1);
4545 const a2: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381;
4646 const b2: f80 = 0x0.0e97_1c3c_8e7d_e03ap-16381;
4747 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();
51 try test_fmodx_infs();
50 try test_fmod_f80_nans();
51 try test_fmod_f80_infs();
5252}
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 {
3636
3737pub fn __divmodti4(a: i128, b: i128, rem: *i128) callconv(.c) i128 {
3838 const d = __divti3(a, b);
39 rem.* = a -% (d * b);
39 rem.* = a - d *% b;
4040 return d;
4141}
4242
......@@ -69,7 +69,7 @@ fn test_one_divmodti4(a: i128, b: i128, expected_q: i128, expected_r: i128) !voi
6969
7070pub fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.c) i64 {
7171 const d = __divdi3(a, b);
72 rem.* = a -% (d * b);
72 rem.* = a - d *% b;
7373 return d;
7474}
7575
......@@ -79,21 +79,20 @@ fn test_one_divmoddi4(a: i64, b: i64, expected_q: i64, expected_r: i64) !void {
7979 try testing.expect(q == expected_q and r == expected_r);
8080}
8181
82const cases__divmoddi4 =
83 [_][4]i64{
84 [_]i64{ 0, 1, 0, 0 },
85 [_]i64{ 0, -1, 0, 0 },
86 [_]i64{ 2, 1, 2, 0 },
87 [_]i64{ 2, -1, -2, 0 },
88 [_]i64{ -2, 1, -2, 0 },
89 [_]i64{ -2, -1, 2, 0 },
90 [_]i64{ 7, 5, 1, 2 },
91 [_]i64{ -7, 5, -1, -2 },
92 [_]i64{ 19, 5, 3, 4 },
93 [_]i64{ 19, -5, -3, 4 },
94 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 },
95 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 },
96 };
82const cases__divmoddi4 = [_][4]i64{
83 [_]i64{ 0, 1, 0, 0 },
84 [_]i64{ 0, -1, 0, 0 },
85 [_]i64{ 2, 1, 2, 0 },
86 [_]i64{ 2, -1, -2, 0 },
87 [_]i64{ -2, 1, -2, 0 },
88 [_]i64{ -2, -1, 2, 0 },
89 [_]i64{ 7, 5, 1, 2 },
90 [_]i64{ -7, 5, -1, -2 },
91 [_]i64{ 19, 5, 3, 4 },
92 [_]i64{ 19, -5, -3, 4 },
93 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 },
94 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 },
95};
9796
9897test "test_divmoddi4" {
9998 for (cases__divmoddi4) |case| {
......@@ -105,10 +104,6 @@ pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.c) u64 {
105104 return udivmod(u64, a, b, maybe_rem);
106105}
107106
108test "test_udivmoddi4" {
109 _ = @import("udivmoddi4_test.zig");
110}
111
112107pub fn __divdi3(a: i64, b: i64) callconv(.c) i64 {
113108 // Set aside the sign of the quotient.
114109 const sign: u64 = @bitCast((a ^ b) >> 63);
......@@ -209,25 +204,24 @@ fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) !void {
209204
210205pub fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.c) i32 {
211206 const d = __divsi3(a, b);
212 rem.* = a -% (d * b);
207 rem.* = a - d *% b;
213208 return d;
214209}
215210
216const cases__divmodsi4 =
217 [_][4]i32{
218 [_]i32{ 0, 1, 0, 0 },
219 [_]i32{ 0, -1, 0, 0 },
220 [_]i32{ 2, 1, 2, 0 },
221 [_]i32{ 2, -1, -2, 0 },
222 [_]i32{ -2, 1, -2, 0 },
223 [_]i32{ -2, -1, 2, 0 },
224 [_]i32{ 7, 5, 1, 2 },
225 [_]i32{ -7, 5, -1, -2 },
226 [_]i32{ 19, 5, 3, 4 },
227 [_]i32{ 19, -5, -3, 4 },
228 [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 },
229 [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 },
230 };
211const cases__divmodsi4 = [_][4]i32{
212 [_]i32{ 0, 1, 0, 0 },
213 [_]i32{ 0, -1, 0, 0 },
214 [_]i32{ 2, 1, 2, 0 },
215 [_]i32{ 2, -1, -2, 0 },
216 [_]i32{ -2, 1, -2, 0 },
217 [_]i32{ -2, -1, 2, 0 },
218 [_]i32{ 7, 5, 1, 2 },
219 [_]i32{ -7, 5, -1, -2 },
220 [_]i32{ 19, 5, 3, 4 },
221 [_]i32{ 19, -5, -3, 4 },
222 [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 },
223 [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 },
224};
231225
232226fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) !void {
233227 var r: i32 = undefined;
......@@ -243,7 +237,7 @@ test "test_divmodsi4" {
243237
244238pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.c) u32 {
245239 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;
247241 return d;
248242}
249243
......@@ -486,7 +480,7 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) !void {
486480}
487481
488482pub fn __modsi3(n: i32, d: i32) callconv(.c) i32 {
489 return n -% __divsi3(n, d) * d;
483 return n - __divsi3(n, d) *% d;
490484}
491485
492486test "test_modsi3" {
......@@ -515,7 +509,7 @@ fn test_one_modsi3(a: i32, b: i32, expected_r: i32) !void {
515509}
516510
517511pub fn __umodsi3(n: u32, d: u32) callconv(.c) u32 {
518 return n -% __udivsi3(n, d) * d;
512 return n - __udivsi3(n, d) * d;
519513}
520514
521515test "test_umodsi3" {
......@@ -663,3 +657,8 @@ fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) !void {
663657 const r: u32 = __umodsi3(a, b);
664658 try testing.expect(r == expected_r);
665659}
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 @@
1const builtin = @import("builtin");
12const std = @import("std");
23const math = std.math;
34const Log2Int = std.math.Log2Int;
......@@ -6,29 +7,532 @@ const compiler_rt = @import("../compiler_rt.zig");
67const symbol = compiler_rt.symbol;
78
89comptime {
9 symbol(&__fixxfti, "__fixxfti");
1010 symbol(&__fixhfsi, "__fixhfsi");
1111 symbol(&__fixhfdi, "__fixhfdi");
1212 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);
13169}
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 {
16197 return intFromFloat(i128, a);
17198}
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 {
20219 return intFromFloat(i64, a);
21220}
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 {
24244 return intFromFloat(i32, a);
25245}
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 {
28261 return intFromFloat(i128, a);
29262}
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 {
32536 const F = @TypeOf(a);
33537 const float_bits = @typeInfo(F).float.bits;
34538 const int_bits = @typeInfo(I).int.bits;
......@@ -76,13 +580,14 @@ pub inline fn intFromFloat(comptime I: type, a: anytype) I {
76580 return result;
77581}
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();
80585 switch (result.len) {
81586 0 => return,
82587 inline 1...4 => |limbs_len| {
83588 const I = @Int(signedness, 32 * limbs_len);
84589 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) {
86591 .little => low_to_high,
87592 .big => switch (limbs_len) {
88593 1 => .{low_to_high[0]},
......@@ -111,7 +616,6 @@ pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, resul
111616 });
112617 switch (signedness) {
113618 .signed => {
114 const endian = @import("builtin").cpu.arch.endian();
115619 const exponent_limb = switch (endian) {
116620 .little => exponent / 32,
117621 .big => result.len - 1 - exponent / 32,
lib/compiler_rt/int_from_float_test.zig+913-897
......@@ -2,1023 +2,1039 @@ const std = @import("std");
22const testing = std.testing;
33const math = std.math;
44
5const __fixunshfti = @import("fixunshfti.zig").__fixunshfti;
6const __fixunsxfti = @import("fixunsxfti.zig").__fixunsxfti;
7
8// Conversion from f32
9const __fixsfsi = @import("fixsfsi.zig").__fixsfsi;
10const __fixunssfsi = @import("fixunssfsi.zig").__fixunssfsi;
11const __fixsfdi = @import("fixsfdi.zig").__fixsfdi;
12const __fixunssfdi = @import("fixunssfdi.zig").__fixunssfdi;
13const __fixsfti = @import("fixsfti.zig").__fixsfti;
14const __fixunssfti = @import("fixunssfti.zig").__fixunssfti;
15const __fixsfei = @import("fixsfei.zig").__fixsfei;
16const __fixunssfei = @import("fixunssfei.zig").__fixunssfei;
17
18// Conversion from f64
19const __fixdfsi = @import("fixdfsi.zig").__fixdfsi;
20const __fixunsdfsi = @import("fixunsdfsi.zig").__fixunsdfsi;
21const __fixdfdi = @import("fixdfdi.zig").__fixdfdi;
22const __fixunsdfdi = @import("fixunsdfdi.zig").__fixunsdfdi;
23const __fixdfti = @import("fixdfti.zig").__fixdfti;
24const __fixunsdfti = @import("fixunsdfti.zig").__fixunsdfti;
25const __fixdfei = @import("fixdfei.zig").__fixdfei;
26const __fixunsdfei = @import("fixunsdfei.zig").__fixunsdfei;
27
28// Conversion from f128
29const __fixtfsi = @import("fixtfsi.zig").__fixtfsi;
30const __fixunstfsi = @import("fixunstfsi.zig").__fixunstfsi;
31const __fixtfdi = @import("fixtfdi.zig").__fixtfdi;
32const __fixunstfdi = @import("fixunstfdi.zig").__fixunstfdi;
33const __fixtfti = @import("fixtfti.zig").__fixtfti;
34const __fixunstfti = @import("fixunstfti.zig").__fixunstfti;
35
36fn test__fixsfsi(a: f32, expected: i32) !void {
37 const x = __fixsfsi(a);
5const impl = @import("int_from_float.zig");
6
7const i32_intFromFloat_f16 = impl.i32_intFromFloat_f16;
8const u32_intFromFloat_f16 = impl.u32_intFromFloat_f16;
9const i64_intFromFloat_f16 = impl.i64_intFromFloat_f16;
10const u64_intFromFloat_f16 = impl.u64_intFromFloat_f16;
11const i128_intFromFloat_f16 = impl.i128_intFromFloat_f16;
12const u128_intFromFloat_f16 = impl.u128_intFromFloat_f16;
13const signed_intFromFloat_f16 = impl.signed_intFromFloat_f16;
14const unsigned_intFromFloat_f16 = impl.unsigned_intFromFloat_f16;
15
16const i32_intFromFloat_f32 = impl.i32_intFromFloat_f32;
17const u32_intFromFloat_f32 = impl.u32_intFromFloat_f32;
18const i64_intFromFloat_f32 = impl.i64_intFromFloat_f32;
19const u64_intFromFloat_f32 = impl.u64_intFromFloat_f32;
20const i128_intFromFloat_f32 = impl.i128_intFromFloat_f32;
21const u128_intFromFloat_f32 = impl.u128_intFromFloat_f32;
22const signed_intFromFloat_f32 = impl.signed_intFromFloat_f32;
23const unsigned_intFromFloat_f32 = impl.unsigned_intFromFloat_f32;
24
25const i32_intFromFloat_f64 = impl.i32_intFromFloat_f64;
26const u32_intFromFloat_f64 = impl.u32_intFromFloat_f64;
27const i64_intFromFloat_f64 = impl.i64_intFromFloat_f64;
28const u64_intFromFloat_f64 = impl.u64_intFromFloat_f64;
29const i128_intFromFloat_f64 = impl.i128_intFromFloat_f64;
30const u128_intFromFloat_f64 = impl.u128_intFromFloat_f64;
31const signed_intFromFloat_f64 = impl.signed_intFromFloat_f64;
32const unsigned_intFromFloat_f64 = impl.unsigned_intFromFloat_f64;
33
34const i32_intFromFloat_f80 = impl.i32_intFromFloat_f80;
35const u32_intFromFloat_f80 = impl.u32_intFromFloat_f80;
36const i64_intFromFloat_f80 = impl.i64_intFromFloat_f80;
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);
3854 try testing.expect(x == expected);
3955}
4056
41fn test__fixunssfsi(a: f32, expected: u32) !void {
42 const x = __fixunssfsi(a);
57fn test_u32_intFromFloat_f32(a: f32, expected: u32) !void {
58 const x = u32_intFromFloat_f32(a);
4359 try testing.expect(x == expected);
4460}
4561
46test "fixsfsi" {
47 try test__fixsfsi(-math.floatMax(f32), math.minInt(i32));
48
49 try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
50 try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
51
52 try test__fixsfsi(-0x1.0000000000000p+127, -0x80000000);
53 try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
54 try test__fixsfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
55
56 try test__fixsfsi(-0x1.0000000000001p+63, -0x80000000);
57 try test__fixsfsi(-0x1.0000000000000p+63, -0x80000000);
58 try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);
59 try test__fixsfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);
60
61 try test__fixsfsi(-0x1.FFFFFEp+62, -0x80000000);
62 try test__fixsfsi(-0x1.FFFFFCp+62, -0x80000000);
63
64 try test__fixsfsi(-0x1.000000p+31, -0x80000000);
65 try test__fixsfsi(-0x1.FFFFFFp+30, -0x80000000);
66 try test__fixsfsi(-0x1.FFFFFEp+30, -0x7FFFFF80);
67 try test__fixsfsi(-0x1.FFFFFCp+30, -0x7FFFFF00);
68
69 try test__fixsfsi(-2.01, -2);
70 try test__fixsfsi(-2.0, -2);
71 try test__fixsfsi(-1.99, -1);
72 try test__fixsfsi(-1.0, -1);
73 try test__fixsfsi(-0.99, 0);
74 try test__fixsfsi(-0.5, 0);
75
76 try test__fixsfsi(-math.floatMin(f32), 0);
77 try test__fixsfsi(0.0, 0);
78 try test__fixsfsi(math.floatMin(f32), 0);
79 try test__fixsfsi(0.5, 0);
80 try test__fixsfsi(0.99, 0);
81 try test__fixsfsi(1.0, 1);
82 try test__fixsfsi(1.5, 1);
83 try test__fixsfsi(1.99, 1);
84 try test__fixsfsi(2.0, 2);
85 try test__fixsfsi(2.01, 2);
86
87 try test__fixsfsi(0x1.FFFFFCp+30, 0x7FFFFF00);
88 try test__fixsfsi(0x1.FFFFFEp+30, 0x7FFFFF80);
89 try test__fixsfsi(0x1.FFFFFFp+30, 0x7FFFFFFF);
90 try test__fixsfsi(0x1.000000p+31, 0x7FFFFFFF);
91
92 try test__fixsfsi(0x1.FFFFFCp+62, 0x7FFFFFFF);
93 try test__fixsfsi(0x1.FFFFFEp+62, 0x7FFFFFFF);
94
95 try test__fixsfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
96 try test__fixsfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
97 try test__fixsfsi(0x1.0000000000000p+63, 0x7FFFFFFF);
98 try test__fixsfsi(0x1.0000000000001p+63, 0x7FFFFFFF);
99
100 try test__fixsfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
101 try test__fixsfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
102 try test__fixsfsi(0x1.0000000000000p+127, 0x7FFFFFFF);
103
104 try test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
105 try test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
106
107 try test__fixsfsi(math.floatMax(f32), math.maxInt(i32));
62test i32_intFromFloat_f32 {
63 try test_i32_intFromFloat_f32(-math.floatMax(f32), math.minInt(i32));
64
65 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
66 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
67
68 try test_i32_intFromFloat_f32(-0x1.0000000000000p+127, -0x80000000);
69 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
70 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
71
72 try test_i32_intFromFloat_f32(-0x1.0000000000001p+63, -0x80000000);
73 try test_i32_intFromFloat_f32(-0x1.0000000000000p+63, -0x80000000);
74 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);
75 try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);
76
77 try test_i32_intFromFloat_f32(-0x1.FFFFFEp+62, -0x80000000);
78 try test_i32_intFromFloat_f32(-0x1.FFFFFCp+62, -0x80000000);
79
80 try test_i32_intFromFloat_f32(-0x1.000000p+31, -0x80000000);
81 try test_i32_intFromFloat_f32(-0x1.FFFFFFp+30, -0x80000000);
82 try test_i32_intFromFloat_f32(-0x1.FFFFFEp+30, -0x7FFFFF80);
83 try test_i32_intFromFloat_f32(-0x1.FFFFFCp+30, -0x7FFFFF00);
84
85 try test_i32_intFromFloat_f32(-2.01, -2);
86 try test_i32_intFromFloat_f32(-2.0, -2);
87 try test_i32_intFromFloat_f32(-1.99, -1);
88 try test_i32_intFromFloat_f32(-1.0, -1);
89 try test_i32_intFromFloat_f32(-0.99, 0);
90 try test_i32_intFromFloat_f32(-0.5, 0);
91
92 try test_i32_intFromFloat_f32(-math.floatMin(f32), 0);
93 try test_i32_intFromFloat_f32(0.0, 0);
94 try test_i32_intFromFloat_f32(math.floatMin(f32), 0);
95 try test_i32_intFromFloat_f32(0.5, 0);
96 try test_i32_intFromFloat_f32(0.99, 0);
97 try test_i32_intFromFloat_f32(1.0, 1);
98 try test_i32_intFromFloat_f32(1.5, 1);
99 try test_i32_intFromFloat_f32(1.99, 1);
100 try test_i32_intFromFloat_f32(2.0, 2);
101 try test_i32_intFromFloat_f32(2.01, 2);
102
103 try test_i32_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00);
104 try test_i32_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80);
105 try test_i32_intFromFloat_f32(0x1.FFFFFFp+30, 0x7FFFFFFF);
106 try test_i32_intFromFloat_f32(0x1.000000p+31, 0x7FFFFFFF);
107
108 try test_i32_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFFFF);
109 try test_i32_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFFFF);
110
111 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
112 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
113 try test_i32_intFromFloat_f32(0x1.0000000000000p+63, 0x7FFFFFFF);
114 try test_i32_intFromFloat_f32(0x1.0000000000001p+63, 0x7FFFFFFF);
115
116 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
117 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
118 try test_i32_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFF);
119
120 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
121 try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
122
123 try test_i32_intFromFloat_f32(math.floatMax(f32), math.maxInt(i32));
108124}
109125
110test "fixunssfsi" {
111 try test__fixunssfsi(0.0, 0);
112
113 try test__fixunssfsi(0.5, 0);
114 try test__fixunssfsi(0.99, 0);
115 try test__fixunssfsi(1.0, 1);
116 try test__fixunssfsi(1.5, 1);
117 try test__fixunssfsi(1.99, 1);
118 try test__fixunssfsi(2.0, 2);
119 try test__fixunssfsi(2.01, 2);
120 try test__fixunssfsi(-0.5, 0);
121 try test__fixunssfsi(-0.99, 0);
122
123 try test__fixunssfsi(-1.0, 0);
124 try test__fixunssfsi(-1.5, 0);
125 try test__fixunssfsi(-1.99, 0);
126 try test__fixunssfsi(-2.0, 0);
127 try test__fixunssfsi(-2.01, 0);
128
129 try test__fixunssfsi(0x1.000000p+31, 0x80000000);
130 try test__fixunssfsi(0x1.000000p+32, 0xFFFFFFFF);
131 try test__fixunssfsi(0x1.FFFFFEp+31, 0xFFFFFF00);
132 try test__fixunssfsi(0x1.FFFFFEp+30, 0x7FFFFF80);
133 try test__fixunssfsi(0x1.FFFFFCp+30, 0x7FFFFF00);
134
135 try test__fixunssfsi(-0x1.FFFFFEp+30, 0);
136 try test__fixunssfsi(-0x1.FFFFFCp+30, 0);
126test u32_intFromFloat_f32 {
127 try test_u32_intFromFloat_f32(0.0, 0);
128
129 try test_u32_intFromFloat_f32(0.5, 0);
130 try test_u32_intFromFloat_f32(0.99, 0);
131 try test_u32_intFromFloat_f32(1.0, 1);
132 try test_u32_intFromFloat_f32(1.5, 1);
133 try test_u32_intFromFloat_f32(1.99, 1);
134 try test_u32_intFromFloat_f32(2.0, 2);
135 try test_u32_intFromFloat_f32(2.01, 2);
136 try test_u32_intFromFloat_f32(-0.5, 0);
137 try test_u32_intFromFloat_f32(-0.99, 0);
138
139 try test_u32_intFromFloat_f32(-1.0, 0);
140 try test_u32_intFromFloat_f32(-1.5, 0);
141 try test_u32_intFromFloat_f32(-1.99, 0);
142 try test_u32_intFromFloat_f32(-2.0, 0);
143 try test_u32_intFromFloat_f32(-2.01, 0);
144
145 try test_u32_intFromFloat_f32(0x1.000000p+31, 0x80000000);
146 try test_u32_intFromFloat_f32(0x1.000000p+32, 0xFFFFFFFF);
147 try test_u32_intFromFloat_f32(0x1.FFFFFEp+31, 0xFFFFFF00);
148 try test_u32_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80);
149 try test_u32_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00);
150
151 try test_u32_intFromFloat_f32(-0x1.FFFFFEp+30, 0);
152 try test_u32_intFromFloat_f32(-0x1.FFFFFCp+30, 0);
137153}
138154
139fn test__fixsfdi(a: f32, expected: i64) !void {
140 const x = __fixsfdi(a);
155fn test_i64_intFromFloat_f32(a: f32, expected: i64) !void {
156 const x = i64_intFromFloat_f32(a);
141157 try testing.expect(x == expected);
142158}
143159
144fn test__fixunssfdi(a: f32, expected: u64) !void {
145 const x = __fixunssfdi(a);
160fn test_u64_intFromFloat_f32(a: f32, expected: u64) !void {
161 const x = u64_intFromFloat_f32(a);
146162 try testing.expect(x == expected);
147163}
148164
149test "fixsfdi" {
150 try test__fixsfdi(-math.floatMax(f32), math.minInt(i64));
151
152 try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
153 try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
154
155 try test__fixsfdi(-0x1.0000000000000p+127, -0x8000000000000000);
156 try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
157 try test__fixsfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
158
159 try test__fixsfdi(-0x1.0000000000001p+63, -0x8000000000000000);
160 try test__fixsfdi(-0x1.0000000000000p+63, -0x8000000000000000);
161 try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000);
162 try test__fixsfdi(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000);
163
164 try test__fixsfdi(-0x1.FFFFFFp+62, -0x8000000000000000);
165 try test__fixsfdi(-0x1.FFFFFEp+62, -0x7fffff8000000000);
166 try test__fixsfdi(-0x1.FFFFFCp+62, -0x7fffff0000000000);
167
168 try test__fixsfdi(-2.01, -2);
169 try test__fixsfdi(-2.0, -2);
170 try test__fixsfdi(-1.99, -1);
171 try test__fixsfdi(-1.0, -1);
172 try test__fixsfdi(-0.99, 0);
173 try test__fixsfdi(-0.5, 0);
174 try test__fixsfdi(-math.floatMin(f32), 0);
175 try test__fixsfdi(0.0, 0);
176 try test__fixsfdi(math.floatMin(f32), 0);
177 try test__fixsfdi(0.5, 0);
178 try test__fixsfdi(0.99, 0);
179 try test__fixsfdi(1.0, 1);
180 try test__fixsfdi(1.5, 1);
181 try test__fixsfdi(1.99, 1);
182 try test__fixsfdi(2.0, 2);
183 try test__fixsfdi(2.01, 2);
184
185 try test__fixsfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
186 try test__fixsfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
187 try test__fixsfdi(0x1.FFFFFFp+62, 0x7FFFFFFFFFFFFFFF);
188
189 try test__fixsfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFFFFF);
190 try test__fixsfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFFFF);
191 try test__fixsfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
192 try test__fixsfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
193
194 try test__fixsfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
195 try test__fixsfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
196 try test__fixsfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
197
198 try test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
199 try test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
200
201 try test__fixsfdi(math.floatMax(f32), math.maxInt(i64));
165test i64_intFromFloat_f32 {
166 try test_i64_intFromFloat_f32(-math.floatMax(f32), math.minInt(i64));
167
168 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
169 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
170
171 try test_i64_intFromFloat_f32(-0x1.0000000000000p+127, -0x8000000000000000);
172 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
173 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
174
175 try test_i64_intFromFloat_f32(-0x1.0000000000001p+63, -0x8000000000000000);
176 try test_i64_intFromFloat_f32(-0x1.0000000000000p+63, -0x8000000000000000);
177 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000);
178 try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000);
179
180 try test_i64_intFromFloat_f32(-0x1.FFFFFFp+62, -0x8000000000000000);
181 try test_i64_intFromFloat_f32(-0x1.FFFFFEp+62, -0x7fffff8000000000);
182 try test_i64_intFromFloat_f32(-0x1.FFFFFCp+62, -0x7fffff0000000000);
183
184 try test_i64_intFromFloat_f32(-2.01, -2);
185 try test_i64_intFromFloat_f32(-2.0, -2);
186 try test_i64_intFromFloat_f32(-1.99, -1);
187 try test_i64_intFromFloat_f32(-1.0, -1);
188 try test_i64_intFromFloat_f32(-0.99, 0);
189 try test_i64_intFromFloat_f32(-0.5, 0);
190 try test_i64_intFromFloat_f32(-math.floatMin(f32), 0);
191 try test_i64_intFromFloat_f32(0.0, 0);
192 try test_i64_intFromFloat_f32(math.floatMin(f32), 0);
193 try test_i64_intFromFloat_f32(0.5, 0);
194 try test_i64_intFromFloat_f32(0.99, 0);
195 try test_i64_intFromFloat_f32(1.0, 1);
196 try test_i64_intFromFloat_f32(1.5, 1);
197 try test_i64_intFromFloat_f32(1.99, 1);
198 try test_i64_intFromFloat_f32(2.0, 2);
199 try test_i64_intFromFloat_f32(2.01, 2);
200
201 try test_i64_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
202 try test_i64_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
203 try test_i64_intFromFloat_f32(0x1.FFFFFFp+62, 0x7FFFFFFFFFFFFFFF);
204
205 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFFFFF);
206 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFFFF);
207 try test_i64_intFromFloat_f32(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
208 try test_i64_intFromFloat_f32(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
209
210 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
211 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
212 try test_i64_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
213
214 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
215 try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
216
217 try test_i64_intFromFloat_f32(math.floatMax(f32), math.maxInt(i64));
202218}
203219
204test "fixunssfdi" {
205 try test__fixunssfdi(0.0, 0);
206
207 try test__fixunssfdi(0.5, 0);
208 try test__fixunssfdi(0.99, 0);
209 try test__fixunssfdi(1.0, 1);
210 try test__fixunssfdi(1.5, 1);
211 try test__fixunssfdi(1.99, 1);
212 try test__fixunssfdi(2.0, 2);
213 try test__fixunssfdi(2.01, 2);
214 try test__fixunssfdi(-0.5, 0);
215 try test__fixunssfdi(-0.99, 0);
216
217 try test__fixunssfdi(-1.0, 0);
218 try test__fixunssfdi(-1.5, 0);
219 try test__fixunssfdi(-1.99, 0);
220 try test__fixunssfdi(-2.0, 0);
221 try test__fixunssfdi(-2.01, 0);
222
223 try test__fixunssfdi(0x1.FFFFFEp+63, 0xFFFFFF0000000000);
224 try test__fixunssfdi(0x1.000000p+63, 0x8000000000000000);
225 try test__fixunssfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
226 try test__fixunssfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
227
228 try test__fixunssfdi(-0x1.FFFFFEp+62, 0x0000000000000000);
229 try test__fixunssfdi(-0x1.FFFFFCp+62, 0x0000000000000000);
220test u64_intFromFloat_f32 {
221 try test_u64_intFromFloat_f32(0.0, 0);
222
223 try test_u64_intFromFloat_f32(0.5, 0);
224 try test_u64_intFromFloat_f32(0.99, 0);
225 try test_u64_intFromFloat_f32(1.0, 1);
226 try test_u64_intFromFloat_f32(1.5, 1);
227 try test_u64_intFromFloat_f32(1.99, 1);
228 try test_u64_intFromFloat_f32(2.0, 2);
229 try test_u64_intFromFloat_f32(2.01, 2);
230 try test_u64_intFromFloat_f32(-0.5, 0);
231 try test_u64_intFromFloat_f32(-0.99, 0);
232
233 try test_u64_intFromFloat_f32(-1.0, 0);
234 try test_u64_intFromFloat_f32(-1.5, 0);
235 try test_u64_intFromFloat_f32(-1.99, 0);
236 try test_u64_intFromFloat_f32(-2.0, 0);
237 try test_u64_intFromFloat_f32(-2.01, 0);
238
239 try test_u64_intFromFloat_f32(0x1.FFFFFEp+63, 0xFFFFFF0000000000);
240 try test_u64_intFromFloat_f32(0x1.000000p+63, 0x8000000000000000);
241 try test_u64_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
242 try test_u64_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
243
244 try test_u64_intFromFloat_f32(-0x1.FFFFFEp+62, 0x0000000000000000);
245 try test_u64_intFromFloat_f32(-0x1.FFFFFCp+62, 0x0000000000000000);
230246}
231247
232fn test__fixsfti(a: f32, expected: i128) !void {
233 const x = __fixsfti(a);
248fn test_i128_intFromFloat_f32(a: f32, expected: i128) !void {
249 const x = i128_intFromFloat_f32(a);
234250 try testing.expect(x == expected);
235251}
236252
237fn test__fixunssfti(a: f32, expected: u128) !void {
238 const x = __fixunssfti(a);
253fn test_u128_intFromFloat_f32(a: f32, expected: u128) !void {
254 const x = u128_intFromFloat_f32(a);
239255 try testing.expect(x == expected);
240256}
241257
242test "fixsfti" {
243 try test__fixsfti(-math.floatMax(f32), math.minInt(i128));
244
245 try test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
246 try test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
247
248 try test__fixsfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
249 try test__fixsfti(-0x1.FFFFFFFFFFFFFp+126, -0x80000000000000000000000000000000);
250 try test__fixsfti(-0x1.FFFFFFFFFFFFEp+126, -0x80000000000000000000000000000000);
251 try test__fixsfti(-0x1.FFFFFF0000000p+126, -0x80000000000000000000000000000000);
252 try test__fixsfti(-0x1.FFFFFE0000000p+126, -0x7FFFFF80000000000000000000000000);
253 try test__fixsfti(-0x1.FFFFFC0000000p+126, -0x7FFFFF00000000000000000000000000);
254
255 try test__fixsfti(-0x1.0000000000001p+63, -0x8000000000000000);
256 try test__fixsfti(-0x1.0000000000000p+63, -0x8000000000000000);
257 try test__fixsfti(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000);
258 try test__fixsfti(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000);
259
260 try test__fixsfti(-0x1.FFFFFFp+62, -0x8000000000000000);
261 try test__fixsfti(-0x1.FFFFFEp+62, -0x7fffff8000000000);
262 try test__fixsfti(-0x1.FFFFFCp+62, -0x7fffff0000000000);
263
264 try test__fixsfti(-0x1.000000p+31, -0x80000000);
265 try test__fixsfti(-0x1.FFFFFFp+30, -0x80000000);
266 try test__fixsfti(-0x1.FFFFFEp+30, -0x7FFFFF80);
267 try test__fixsfti(-0x1.FFFFFCp+30, -0x7FFFFF00);
268
269 try test__fixsfti(-2.01, -2);
270 try test__fixsfti(-2.0, -2);
271 try test__fixsfti(-1.99, -1);
272 try test__fixsfti(-1.0, -1);
273 try test__fixsfti(-0.99, 0);
274 try test__fixsfti(-0.5, 0);
275 try test__fixsfti(-math.floatMin(f32), 0);
276 try test__fixsfti(0.0, 0);
277 try test__fixsfti(math.floatMin(f32), 0);
278 try test__fixsfti(0.5, 0);
279 try test__fixsfti(0.99, 0);
280 try test__fixsfti(1.0, 1);
281 try test__fixsfti(1.5, 1);
282 try test__fixsfti(1.99, 1);
283 try test__fixsfti(2.0, 2);
284 try test__fixsfti(2.01, 2);
285
286 try test__fixsfti(0x1.FFFFFCp+30, 0x7FFFFF00);
287 try test__fixsfti(0x1.FFFFFEp+30, 0x7FFFFF80);
288 try test__fixsfti(0x1.FFFFFFp+30, 0x80000000);
289 try test__fixsfti(0x1.000000p+31, 0x80000000);
290
291 try test__fixsfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
292 try test__fixsfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
293 try test__fixsfti(0x1.FFFFFFp+62, 0x8000000000000000);
294
295 try test__fixsfti(0x1.FFFFFFFFFFFFEp+62, 0x8000000000000000);
296 try test__fixsfti(0x1.FFFFFFFFFFFFFp+62, 0x8000000000000000);
297 try test__fixsfti(0x1.0000000000000p+63, 0x8000000000000000);
298 try test__fixsfti(0x1.0000000000001p+63, 0x8000000000000000);
299
300 try test__fixsfti(0x1.FFFFFC0000000p+126, 0x7FFFFF00000000000000000000000000);
301 try test__fixsfti(0x1.FFFFFE0000000p+126, 0x7FFFFF80000000000000000000000000);
302 try test__fixsfti(0x1.FFFFFF0000000p+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
303 try test__fixsfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
304 try test__fixsfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
305 try test__fixsfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
306
307 try test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
308 try test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
309
310 try test__fixsfti(math.floatMax(f32), math.maxInt(i128));
258test i128_intFromFloat_f32 {
259 try test_i128_intFromFloat_f32(-math.floatMax(f32), math.minInt(i128));
260
261 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
262 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
263
264 try test_i128_intFromFloat_f32(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
265 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x80000000000000000000000000000000);
266 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x80000000000000000000000000000000);
267 try test_i128_intFromFloat_f32(-0x1.FFFFFF0000000p+126, -0x80000000000000000000000000000000);
268 try test_i128_intFromFloat_f32(-0x1.FFFFFE0000000p+126, -0x7FFFFF80000000000000000000000000);
269 try test_i128_intFromFloat_f32(-0x1.FFFFFC0000000p+126, -0x7FFFFF00000000000000000000000000);
270
271 try test_i128_intFromFloat_f32(-0x1.0000000000001p+63, -0x8000000000000000);
272 try test_i128_intFromFloat_f32(-0x1.0000000000000p+63, -0x8000000000000000);
273 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000);
274 try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000);
275
276 try test_i128_intFromFloat_f32(-0x1.FFFFFFp+62, -0x8000000000000000);
277 try test_i128_intFromFloat_f32(-0x1.FFFFFEp+62, -0x7fffff8000000000);
278 try test_i128_intFromFloat_f32(-0x1.FFFFFCp+62, -0x7fffff0000000000);
279
280 try test_i128_intFromFloat_f32(-0x1.000000p+31, -0x80000000);
281 try test_i128_intFromFloat_f32(-0x1.FFFFFFp+30, -0x80000000);
282 try test_i128_intFromFloat_f32(-0x1.FFFFFEp+30, -0x7FFFFF80);
283 try test_i128_intFromFloat_f32(-0x1.FFFFFCp+30, -0x7FFFFF00);
284
285 try test_i128_intFromFloat_f32(-2.01, -2);
286 try test_i128_intFromFloat_f32(-2.0, -2);
287 try test_i128_intFromFloat_f32(-1.99, -1);
288 try test_i128_intFromFloat_f32(-1.0, -1);
289 try test_i128_intFromFloat_f32(-0.99, 0);
290 try test_i128_intFromFloat_f32(-0.5, 0);
291 try test_i128_intFromFloat_f32(-math.floatMin(f32), 0);
292 try test_i128_intFromFloat_f32(0.0, 0);
293 try test_i128_intFromFloat_f32(math.floatMin(f32), 0);
294 try test_i128_intFromFloat_f32(0.5, 0);
295 try test_i128_intFromFloat_f32(0.99, 0);
296 try test_i128_intFromFloat_f32(1.0, 1);
297 try test_i128_intFromFloat_f32(1.5, 1);
298 try test_i128_intFromFloat_f32(1.99, 1);
299 try test_i128_intFromFloat_f32(2.0, 2);
300 try test_i128_intFromFloat_f32(2.01, 2);
301
302 try test_i128_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00);
303 try test_i128_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80);
304 try test_i128_intFromFloat_f32(0x1.FFFFFFp+30, 0x80000000);
305 try test_i128_intFromFloat_f32(0x1.000000p+31, 0x80000000);
306
307 try test_i128_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
308 try test_i128_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
309 try test_i128_intFromFloat_f32(0x1.FFFFFFp+62, 0x8000000000000000);
310
311 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x8000000000000000);
312 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x8000000000000000);
313 try test_i128_intFromFloat_f32(0x1.0000000000000p+63, 0x8000000000000000);
314 try test_i128_intFromFloat_f32(0x1.0000000000001p+63, 0x8000000000000000);
315
316 try test_i128_intFromFloat_f32(0x1.FFFFFC0000000p+126, 0x7FFFFF00000000000000000000000000);
317 try test_i128_intFromFloat_f32(0x1.FFFFFE0000000p+126, 0x7FFFFF80000000000000000000000000);
318 try test_i128_intFromFloat_f32(0x1.FFFFFF0000000p+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
319 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
320 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
321 try test_i128_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
322
323 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
324 try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
325
326 try test_i128_intFromFloat_f32(math.floatMax(f32), math.maxInt(i128));
311327}
312328
313test "fixunssfti" {
314 try test__fixunssfti(0.0, 0);
315
316 try test__fixunssfti(0.5, 0);
317 try test__fixunssfti(0.99, 0);
318 try test__fixunssfti(1.0, 1);
319 try test__fixunssfti(1.5, 1);
320 try test__fixunssfti(1.99, 1);
321 try test__fixunssfti(2.0, 2);
322 try test__fixunssfti(2.01, 2);
323 try test__fixunssfti(-0.5, 0);
324 try test__fixunssfti(-0.99, 0);
325
326 try test__fixunssfti(-1.0, 0);
327 try test__fixunssfti(-1.5, 0);
328 try test__fixunssfti(-1.99, 0);
329 try test__fixunssfti(-2.0, 0);
330 try test__fixunssfti(-2.01, 0);
331
332 try test__fixunssfti(0x1.FFFFFEp+63, 0xFFFFFF0000000000);
333 try test__fixunssfti(0x1.000000p+63, 0x8000000000000000);
334 try test__fixunssfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
335 try test__fixunssfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
336 try test__fixunssfti(0x1.FFFFFEp+127, 0xFFFFFF00000000000000000000000000);
337 try test__fixunssfti(0x1.000000p+127, 0x80000000000000000000000000000000);
338 try test__fixunssfti(0x1.FFFFFEp+126, 0x7FFFFF80000000000000000000000000);
339 try test__fixunssfti(0x1.FFFFFCp+126, 0x7FFFFF00000000000000000000000000);
340
341 try test__fixunssfti(-0x1.FFFFFEp+62, 0x0000000000000000);
342 try test__fixunssfti(-0x1.FFFFFCp+62, 0x0000000000000000);
343 try test__fixunssfti(-0x1.FFFFFEp+126, 0x0000000000000000);
344 try test__fixunssfti(-0x1.FFFFFCp+126, 0x0000000000000000);
345 try test__fixunssfti(math.floatMax(f32), 0xffffff00000000000000000000000000);
346 try test__fixunssfti(math.inf(f32), math.maxInt(u128));
329test u128_intFromFloat_f32 {
330 try test_u128_intFromFloat_f32(0.0, 0);
331
332 try test_u128_intFromFloat_f32(0.5, 0);
333 try test_u128_intFromFloat_f32(0.99, 0);
334 try test_u128_intFromFloat_f32(1.0, 1);
335 try test_u128_intFromFloat_f32(1.5, 1);
336 try test_u128_intFromFloat_f32(1.99, 1);
337 try test_u128_intFromFloat_f32(2.0, 2);
338 try test_u128_intFromFloat_f32(2.01, 2);
339 try test_u128_intFromFloat_f32(-0.5, 0);
340 try test_u128_intFromFloat_f32(-0.99, 0);
341
342 try test_u128_intFromFloat_f32(-1.0, 0);
343 try test_u128_intFromFloat_f32(-1.5, 0);
344 try test_u128_intFromFloat_f32(-1.99, 0);
345 try test_u128_intFromFloat_f32(-2.0, 0);
346 try test_u128_intFromFloat_f32(-2.01, 0);
347
348 try test_u128_intFromFloat_f32(0x1.FFFFFEp+63, 0xFFFFFF0000000000);
349 try test_u128_intFromFloat_f32(0x1.000000p+63, 0x8000000000000000);
350 try test_u128_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
351 try test_u128_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
352 try test_u128_intFromFloat_f32(0x1.FFFFFEp+127, 0xFFFFFF00000000000000000000000000);
353 try test_u128_intFromFloat_f32(0x1.000000p+127, 0x80000000000000000000000000000000);
354 try test_u128_intFromFloat_f32(0x1.FFFFFEp+126, 0x7FFFFF80000000000000000000000000);
355 try test_u128_intFromFloat_f32(0x1.FFFFFCp+126, 0x7FFFFF00000000000000000000000000);
356
357 try test_u128_intFromFloat_f32(-0x1.FFFFFEp+62, 0x0000000000000000);
358 try test_u128_intFromFloat_f32(-0x1.FFFFFCp+62, 0x0000000000000000);
359 try test_u128_intFromFloat_f32(-0x1.FFFFFEp+126, 0x0000000000000000);
360 try test_u128_intFromFloat_f32(-0x1.FFFFFCp+126, 0x0000000000000000);
361 try test_u128_intFromFloat_f32(math.floatMax(f32), 0xffffff00000000000000000000000000);
362 try test_u128_intFromFloat_f32(math.inf(f32), math.maxInt(u128));
347363}
348364
349fn test_fixsfei(comptime T: type, expected: T, a: f32) !void {
365fn test_intFromFloat_f32(comptime T: type, expected: T, a: f32) !void {
350366 const int = @typeInfo(T).int;
351367 var actual: T = undefined;
352368 _ = switch (int.signedness) {
353 .signed => __fixsfei,
354 .unsigned => __fixunssfei,
355 }(@ptrCast(&actual), int.bits, a);
369 .signed => signed_intFromFloat_f32,
370 .unsigned => unsigned_intFromFloat_f32,
371 }(@ptrCast(&actual), a);
356372 try testing.expect(expected == actual);
357373}
358374
359test "fixsfei" {
360 try test_fixsfei(i256, -1 << 127, -0x1p127);
361 try test_fixsfei(i256, -1 << 100, -0x1p100);
362 try test_fixsfei(i256, -1 << 50, -0x1p50);
363 try test_fixsfei(i256, -1 << 1, -0x1p1);
364 try test_fixsfei(i256, -1 << 0, -0x1p0);
365 try test_fixsfei(i256, 0, 0);
366 try test_fixsfei(i256, 1 << 0, 0x1p0);
367 try test_fixsfei(i256, 1 << 1, 0x1p1);
368 try test_fixsfei(i256, 1 << 50, 0x1p50);
369 try test_fixsfei(i256, 1 << 100, 0x1p100);
370 try test_fixsfei(i256, 1 << 127, 0x1p127);
375test signed_intFromFloat_f32 {
376 try test_intFromFloat_f32(i256, -1 << 127, -0x1p127);
377 try test_intFromFloat_f32(i256, -1 << 100, -0x1p100);
378 try test_intFromFloat_f32(i256, -1 << 50, -0x1p50);
379 try test_intFromFloat_f32(i256, -1 << 1, -0x1p1);
380 try test_intFromFloat_f32(i256, -1 << 0, -0x1p0);
381 try test_intFromFloat_f32(i256, 0, 0);
382 try test_intFromFloat_f32(i256, 1 << 0, 0x1p0);
383 try test_intFromFloat_f32(i256, 1 << 1, 0x1p1);
384 try test_intFromFloat_f32(i256, 1 << 50, 0x1p50);
385 try test_intFromFloat_f32(i256, 1 << 100, 0x1p100);
386 try test_intFromFloat_f32(i256, 1 << 127, 0x1p127);
371387}
372388
373test "fixunsfei" {
374 try test_fixsfei(u256, 0, 0);
375 try test_fixsfei(u256, 1 << 0, 0x1p0);
376 try test_fixsfei(u256, 1 << 1, 0x1p1);
377 try test_fixsfei(u256, 1 << 50, 0x1p50);
378 try test_fixsfei(u256, 1 << 100, 0x1p100);
379 try test_fixsfei(u256, 1 << 127, 0x1p127);
389test unsigned_intFromFloat_f32 {
390 try test_intFromFloat_f32(u256, 0, 0);
391 try test_intFromFloat_f32(u256, 1 << 0, 0x1p0);
392 try test_intFromFloat_f32(u256, 1 << 1, 0x1p1);
393 try test_intFromFloat_f32(u256, 1 << 50, 0x1p50);
394 try test_intFromFloat_f32(u256, 1 << 100, 0x1p100);
395 try test_intFromFloat_f32(u256, 1 << 127, 0x1p127);
380396}
381397
382fn test__fixdfsi(a: f64, expected: i32) !void {
383 const x = __fixdfsi(a);
398fn test_i32_intFromFloat_f64(a: f64, expected: i32) !void {
399 const x = i32_intFromFloat_f64(a);
384400 try testing.expect(x == expected);
385401}
386402
387fn test__fixunsdfsi(a: f64, expected: u32) !void {
388 const x = __fixunsdfsi(a);
403fn test_u32_intFromFloat_f64(a: f64, expected: u32) !void {
404 const x = u32_intFromFloat_f64(a);
389405 try testing.expect(x == expected);
390406}
391407
392test "fixdfsi" {
393 try test__fixdfsi(-math.floatMax(f64), math.minInt(i32));
394
395 try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
396 try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
397
398 try test__fixdfsi(-0x1.0000000000000p+127, -0x80000000);
399 try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
400 try test__fixdfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
401
402 try test__fixdfsi(-0x1.0000000000001p+63, -0x80000000);
403 try test__fixdfsi(-0x1.0000000000000p+63, -0x80000000);
404 try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);
405 try test__fixdfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);
406
407 try test__fixdfsi(-0x1.FFFFFEp+62, -0x80000000);
408 try test__fixdfsi(-0x1.FFFFFCp+62, -0x80000000);
409
410 try test__fixdfsi(-0x1.000000p+31, -0x80000000);
411 try test__fixdfsi(-0x1.FFFFFFp+30, -0x7FFFFFC0);
412 try test__fixdfsi(-0x1.FFFFFEp+30, -0x7FFFFF80);
413
414 try test__fixdfsi(-2.01, -2);
415 try test__fixdfsi(-2.0, -2);
416 try test__fixdfsi(-1.99, -1);
417 try test__fixdfsi(-1.0, -1);
418 try test__fixdfsi(-0.99, 0);
419 try test__fixdfsi(-0.5, 0);
420 try test__fixdfsi(-math.floatMin(f64), 0);
421 try test__fixdfsi(0.0, 0);
422 try test__fixdfsi(math.floatMin(f64), 0);
423 try test__fixdfsi(0.5, 0);
424 try test__fixdfsi(0.99, 0);
425 try test__fixdfsi(1.0, 1);
426 try test__fixdfsi(1.5, 1);
427 try test__fixdfsi(1.99, 1);
428 try test__fixdfsi(2.0, 2);
429 try test__fixdfsi(2.01, 2);
430
431 try test__fixdfsi(0x1.FFFFFEp+30, 0x7FFFFF80);
432 try test__fixdfsi(0x1.FFFFFFp+30, 0x7FFFFFC0);
433 try test__fixdfsi(0x1.000000p+31, 0x7FFFFFFF);
434
435 try test__fixdfsi(0x1.FFFFFCp+62, 0x7FFFFFFF);
436 try test__fixdfsi(0x1.FFFFFEp+62, 0x7FFFFFFF);
437
438 try test__fixdfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
439 try test__fixdfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
440 try test__fixdfsi(0x1.0000000000000p+63, 0x7FFFFFFF);
441 try test__fixdfsi(0x1.0000000000001p+63, 0x7FFFFFFF);
442
443 try test__fixdfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
444 try test__fixdfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
445 try test__fixdfsi(0x1.0000000000000p+127, 0x7FFFFFFF);
446
447 try test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
448 try test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
449
450 try test__fixdfsi(math.floatMax(f64), math.maxInt(i32));
408test i32_intFromFloat_f64 {
409 try test_i32_intFromFloat_f64(-math.floatMax(f64), math.minInt(i32));
410
411 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
412 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
413
414 try test_i32_intFromFloat_f64(-0x1.0000000000000p+127, -0x80000000);
415 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
416 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
417
418 try test_i32_intFromFloat_f64(-0x1.0000000000001p+63, -0x80000000);
419 try test_i32_intFromFloat_f64(-0x1.0000000000000p+63, -0x80000000);
420 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);
421 try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);
422
423 try test_i32_intFromFloat_f64(-0x1.FFFFFEp+62, -0x80000000);
424 try test_i32_intFromFloat_f64(-0x1.FFFFFCp+62, -0x80000000);
425
426 try test_i32_intFromFloat_f64(-0x1.000000p+31, -0x80000000);
427 try test_i32_intFromFloat_f64(-0x1.FFFFFFp+30, -0x7FFFFFC0);
428 try test_i32_intFromFloat_f64(-0x1.FFFFFEp+30, -0x7FFFFF80);
429
430 try test_i32_intFromFloat_f64(-2.01, -2);
431 try test_i32_intFromFloat_f64(-2.0, -2);
432 try test_i32_intFromFloat_f64(-1.99, -1);
433 try test_i32_intFromFloat_f64(-1.0, -1);
434 try test_i32_intFromFloat_f64(-0.99, 0);
435 try test_i32_intFromFloat_f64(-0.5, 0);
436 try test_i32_intFromFloat_f64(-math.floatMin(f64), 0);
437 try test_i32_intFromFloat_f64(0.0, 0);
438 try test_i32_intFromFloat_f64(math.floatMin(f64), 0);
439 try test_i32_intFromFloat_f64(0.5, 0);
440 try test_i32_intFromFloat_f64(0.99, 0);
441 try test_i32_intFromFloat_f64(1.0, 1);
442 try test_i32_intFromFloat_f64(1.5, 1);
443 try test_i32_intFromFloat_f64(1.99, 1);
444 try test_i32_intFromFloat_f64(2.0, 2);
445 try test_i32_intFromFloat_f64(2.01, 2);
446
447 try test_i32_intFromFloat_f64(0x1.FFFFFEp+30, 0x7FFFFF80);
448 try test_i32_intFromFloat_f64(0x1.FFFFFFp+30, 0x7FFFFFC0);
449 try test_i32_intFromFloat_f64(0x1.000000p+31, 0x7FFFFFFF);
450
451 try test_i32_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFFFF);
452 try test_i32_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFFFF);
453
454 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
455 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
456 try test_i32_intFromFloat_f64(0x1.0000000000000p+63, 0x7FFFFFFF);
457 try test_i32_intFromFloat_f64(0x1.0000000000001p+63, 0x7FFFFFFF);
458
459 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
460 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
461 try test_i32_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFF);
462
463 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
464 try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
465
466 try test_i32_intFromFloat_f64(math.floatMax(f64), math.maxInt(i32));
451467}
452468
453test "fixunsdfsi" {
454 try test__fixunsdfsi(0.0, 0);
455
456 try test__fixunsdfsi(0.5, 0);
457 try test__fixunsdfsi(0.99, 0);
458 try test__fixunsdfsi(1.0, 1);
459 try test__fixunsdfsi(1.5, 1);
460 try test__fixunsdfsi(1.99, 1);
461 try test__fixunsdfsi(2.0, 2);
462 try test__fixunsdfsi(2.01, 2);
463 try test__fixunsdfsi(-0.5, 0);
464 try test__fixunsdfsi(-0.99, 0);
465 try test__fixunsdfsi(-1.0, 0);
466 try test__fixunsdfsi(-1.5, 0);
467 try test__fixunsdfsi(-1.99, 0);
468 try test__fixunsdfsi(-2.0, 0);
469 try test__fixunsdfsi(-2.01, 0);
470
471 try test__fixunsdfsi(0x1.000000p+31, 0x80000000);
472 try test__fixunsdfsi(0x1.000000p+32, 0xFFFFFFFF);
473 try test__fixunsdfsi(0x1.FFFFFEp+31, 0xFFFFFF00);
474 try test__fixunsdfsi(0x1.FFFFFEp+30, 0x7FFFFF80);
475 try test__fixunsdfsi(0x1.FFFFFCp+30, 0x7FFFFF00);
476
477 try test__fixunsdfsi(-0x1.FFFFFEp+30, 0);
478 try test__fixunsdfsi(-0x1.FFFFFCp+30, 0);
479
480 try test__fixunsdfsi(0x1.FFFFFFFEp+31, 0xFFFFFFFF);
481 try test__fixunsdfsi(0x1.FFFFFFFC00000p+30, 0x7FFFFFFF);
482 try test__fixunsdfsi(0x1.FFFFFFF800000p+30, 0x7FFFFFFE);
469test u32_intFromFloat_f64 {
470 try test_u32_intFromFloat_f64(0.0, 0);
471
472 try test_u32_intFromFloat_f64(0.5, 0);
473 try test_u32_intFromFloat_f64(0.99, 0);
474 try test_u32_intFromFloat_f64(1.0, 1);
475 try test_u32_intFromFloat_f64(1.5, 1);
476 try test_u32_intFromFloat_f64(1.99, 1);
477 try test_u32_intFromFloat_f64(2.0, 2);
478 try test_u32_intFromFloat_f64(2.01, 2);
479 try test_u32_intFromFloat_f64(-0.5, 0);
480 try test_u32_intFromFloat_f64(-0.99, 0);
481 try test_u32_intFromFloat_f64(-1.0, 0);
482 try test_u32_intFromFloat_f64(-1.5, 0);
483 try test_u32_intFromFloat_f64(-1.99, 0);
484 try test_u32_intFromFloat_f64(-2.0, 0);
485 try test_u32_intFromFloat_f64(-2.01, 0);
486
487 try test_u32_intFromFloat_f64(0x1.000000p+31, 0x80000000);
488 try test_u32_intFromFloat_f64(0x1.000000p+32, 0xFFFFFFFF);
489 try test_u32_intFromFloat_f64(0x1.FFFFFEp+31, 0xFFFFFF00);
490 try test_u32_intFromFloat_f64(0x1.FFFFFEp+30, 0x7FFFFF80);
491 try test_u32_intFromFloat_f64(0x1.FFFFFCp+30, 0x7FFFFF00);
492
493 try test_u32_intFromFloat_f64(-0x1.FFFFFEp+30, 0);
494 try test_u32_intFromFloat_f64(-0x1.FFFFFCp+30, 0);
495
496 try test_u32_intFromFloat_f64(0x1.FFFFFFFEp+31, 0xFFFFFFFF);
497 try test_u32_intFromFloat_f64(0x1.FFFFFFFC00000p+30, 0x7FFFFFFF);
498 try test_u32_intFromFloat_f64(0x1.FFFFFFF800000p+30, 0x7FFFFFFE);
483499}
484500
485fn test__fixdfdi(a: f64, expected: i64) !void {
486 const x = __fixdfdi(a);
501fn test_i64_intFromFloat_f64(a: f64, expected: i64) !void {
502 const x = i64_intFromFloat_f64(a);
487503 try testing.expect(x == expected);
488504}
489505
490fn test__fixunsdfdi(a: f64, expected: u64) !void {
491 const x = __fixunsdfdi(a);
506fn test_u64_intFromFloat_f64(a: f64, expected: u64) !void {
507 const x = u64_intFromFloat_f64(a);
492508 try testing.expect(x == expected);
493509}
494510
495test "fixdfdi" {
496 try test__fixdfdi(-math.floatMax(f64), math.minInt(i64));
497
498 try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
499 try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
500
501 try test__fixdfdi(-0x1.0000000000000p+127, -0x8000000000000000);
502 try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
503 try test__fixdfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
504
505 try test__fixdfdi(-0x1.0000000000001p+63, -0x8000000000000000);
506 try test__fixdfdi(-0x1.0000000000000p+63, -0x8000000000000000);
507 try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
508 try test__fixdfdi(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
509
510 try test__fixdfdi(-0x1.FFFFFEp+62, -0x7fffff8000000000);
511 try test__fixdfdi(-0x1.FFFFFCp+62, -0x7fffff0000000000);
512
513 try test__fixdfdi(-2.01, -2);
514 try test__fixdfdi(-2.0, -2);
515 try test__fixdfdi(-1.99, -1);
516 try test__fixdfdi(-1.0, -1);
517 try test__fixdfdi(-0.99, 0);
518 try test__fixdfdi(-0.5, 0);
519 try test__fixdfdi(-math.floatMin(f64), 0);
520 try test__fixdfdi(0.0, 0);
521 try test__fixdfdi(math.floatMin(f64), 0);
522 try test__fixdfdi(0.5, 0);
523 try test__fixdfdi(0.99, 0);
524 try test__fixdfdi(1.0, 1);
525 try test__fixdfdi(1.5, 1);
526 try test__fixdfdi(1.99, 1);
527 try test__fixdfdi(2.0, 2);
528 try test__fixdfdi(2.01, 2);
529
530 try test__fixdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
531 try test__fixdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
532
533 try test__fixdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
534 try test__fixdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
535 try test__fixdfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
536 try test__fixdfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
537
538 try test__fixdfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
539 try test__fixdfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
540 try test__fixdfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
541
542 try test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
543 try test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
544
545 try test__fixdfdi(math.floatMax(f64), math.maxInt(i64));
511test i64_intFromFloat_f64 {
512 try test_i64_intFromFloat_f64(-math.floatMax(f64), math.minInt(i64));
513
514 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
515 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
516
517 try test_i64_intFromFloat_f64(-0x1.0000000000000p+127, -0x8000000000000000);
518 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
519 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
520
521 try test_i64_intFromFloat_f64(-0x1.0000000000001p+63, -0x8000000000000000);
522 try test_i64_intFromFloat_f64(-0x1.0000000000000p+63, -0x8000000000000000);
523 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
524 try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
525
526 try test_i64_intFromFloat_f64(-0x1.FFFFFEp+62, -0x7fffff8000000000);
527 try test_i64_intFromFloat_f64(-0x1.FFFFFCp+62, -0x7fffff0000000000);
528
529 try test_i64_intFromFloat_f64(-2.01, -2);
530 try test_i64_intFromFloat_f64(-2.0, -2);
531 try test_i64_intFromFloat_f64(-1.99, -1);
532 try test_i64_intFromFloat_f64(-1.0, -1);
533 try test_i64_intFromFloat_f64(-0.99, 0);
534 try test_i64_intFromFloat_f64(-0.5, 0);
535 try test_i64_intFromFloat_f64(-math.floatMin(f64), 0);
536 try test_i64_intFromFloat_f64(0.0, 0);
537 try test_i64_intFromFloat_f64(math.floatMin(f64), 0);
538 try test_i64_intFromFloat_f64(0.5, 0);
539 try test_i64_intFromFloat_f64(0.99, 0);
540 try test_i64_intFromFloat_f64(1.0, 1);
541 try test_i64_intFromFloat_f64(1.5, 1);
542 try test_i64_intFromFloat_f64(1.99, 1);
543 try test_i64_intFromFloat_f64(2.0, 2);
544 try test_i64_intFromFloat_f64(2.01, 2);
545
546 try test_i64_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
547 try test_i64_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
548
549 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
550 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
551 try test_i64_intFromFloat_f64(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
552 try test_i64_intFromFloat_f64(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
553
554 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
555 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
556 try test_i64_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
557
558 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
559 try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
560
561 try test_i64_intFromFloat_f64(math.floatMax(f64), math.maxInt(i64));
546562}
547563
548test "fixunsdfdi" {
549 try test__fixunsdfdi(0.0, 0);
550 try test__fixunsdfdi(0.5, 0);
551 try test__fixunsdfdi(0.99, 0);
552 try test__fixunsdfdi(1.0, 1);
553 try test__fixunsdfdi(1.5, 1);
554 try test__fixunsdfdi(1.99, 1);
555 try test__fixunsdfdi(2.0, 2);
556 try test__fixunsdfdi(2.01, 2);
557 try test__fixunsdfdi(-0.5, 0);
558 try test__fixunsdfdi(-0.99, 0);
559 try test__fixunsdfdi(-1.0, 0);
560 try test__fixunsdfdi(-1.5, 0);
561 try test__fixunsdfdi(-1.99, 0);
562 try test__fixunsdfdi(-2.0, 0);
563 try test__fixunsdfdi(-2.01, 0);
564
565 try test__fixunsdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
566 try test__fixunsdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
567
568 try test__fixunsdfdi(-0x1.FFFFFEp+62, 0);
569 try test__fixunsdfdi(-0x1.FFFFFCp+62, 0);
570
571 try test__fixunsdfdi(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800);
572 try test__fixunsdfdi(0x1.0000000000000p+63, 0x8000000000000000);
573 try test__fixunsdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
574 try test__fixunsdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
575
576 try test__fixunsdfdi(-0x1.FFFFFFFFFFFFFp+62, 0);
577 try test__fixunsdfdi(-0x1.FFFFFFFFFFFFEp+62, 0);
564test u64_intFromFloat_f64 {
565 try test_u64_intFromFloat_f64(0.0, 0);
566 try test_u64_intFromFloat_f64(0.5, 0);
567 try test_u64_intFromFloat_f64(0.99, 0);
568 try test_u64_intFromFloat_f64(1.0, 1);
569 try test_u64_intFromFloat_f64(1.5, 1);
570 try test_u64_intFromFloat_f64(1.99, 1);
571 try test_u64_intFromFloat_f64(2.0, 2);
572 try test_u64_intFromFloat_f64(2.01, 2);
573 try test_u64_intFromFloat_f64(-0.5, 0);
574 try test_u64_intFromFloat_f64(-0.99, 0);
575 try test_u64_intFromFloat_f64(-1.0, 0);
576 try test_u64_intFromFloat_f64(-1.5, 0);
577 try test_u64_intFromFloat_f64(-1.99, 0);
578 try test_u64_intFromFloat_f64(-2.0, 0);
579 try test_u64_intFromFloat_f64(-2.01, 0);
580
581 try test_u64_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
582 try test_u64_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
583
584 try test_u64_intFromFloat_f64(-0x1.FFFFFEp+62, 0);
585 try test_u64_intFromFloat_f64(-0x1.FFFFFCp+62, 0);
586
587 try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800);
588 try test_u64_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000);
589 try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
590 try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
591
592 try test_u64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, 0);
593 try test_u64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, 0);
578594}
579595
580fn test__fixdfti(a: f64, expected: i128) !void {
581 const x = __fixdfti(a);
596fn test_i128_intFromFloat_f64(a: f64, expected: i128) !void {
597 const x = i128_intFromFloat_f64(a);
582598 try testing.expect(x == expected);
583599}
584600
585fn test__fixunsdfti(a: f64, expected: u128) !void {
586 const x = __fixunsdfti(a);
601fn test_u128_intFromFloat_f64(a: f64, expected: u128) !void {
602 const x = u128_intFromFloat_f64(a);
587603 try testing.expect(x == expected);
588604}
589605
590test "fixdfti" {
591 try test__fixdfti(-math.floatMax(f64), math.minInt(i128));
592
593 try test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
594 try test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
595
596 try test__fixdfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
597 try test__fixdfti(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000);
598 try test__fixdfti(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000);
599
600 try test__fixdfti(-0x1.0000000000001p+63, -0x8000000000000800);
601 try test__fixdfti(-0x1.0000000000000p+63, -0x8000000000000000);
602 try test__fixdfti(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
603 try test__fixdfti(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
604
605 try test__fixdfti(-0x1.FFFFFEp+62, -0x7fffff8000000000);
606 try test__fixdfti(-0x1.FFFFFCp+62, -0x7fffff0000000000);
607
608 try test__fixdfti(-2.01, -2);
609 try test__fixdfti(-2.0, -2);
610 try test__fixdfti(-1.99, -1);
611 try test__fixdfti(-1.0, -1);
612 try test__fixdfti(-0.99, 0);
613 try test__fixdfti(-0.5, 0);
614 try test__fixdfti(-math.floatMin(f64), 0);
615 try test__fixdfti(0.0, 0);
616 try test__fixdfti(math.floatMin(f64), 0);
617 try test__fixdfti(0.5, 0);
618 try test__fixdfti(0.99, 0);
619 try test__fixdfti(1.0, 1);
620 try test__fixdfti(1.5, 1);
621 try test__fixdfti(1.99, 1);
622 try test__fixdfti(2.0, 2);
623 try test__fixdfti(2.01, 2);
624
625 try test__fixdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
626 try test__fixdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
627
628 try test__fixdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
629 try test__fixdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
630 try test__fixdfti(0x1.0000000000000p+63, 0x8000000000000000);
631 try test__fixdfti(0x1.0000000000001p+63, 0x8000000000000800);
632
633 try test__fixdfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);
634 try test__fixdfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);
635 try test__fixdfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
636
637 try test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
638 try test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
639
640 try test__fixdfti(math.floatMax(f64), math.maxInt(i128));
606test i128_intFromFloat_f64 {
607 try test_i128_intFromFloat_f64(-math.floatMax(f64), math.minInt(i128));
608
609 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
610 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
611
612 try test_i128_intFromFloat_f64(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
613 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000);
614 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000);
615
616 try test_i128_intFromFloat_f64(-0x1.0000000000001p+63, -0x8000000000000800);
617 try test_i128_intFromFloat_f64(-0x1.0000000000000p+63, -0x8000000000000000);
618 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
619 try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
620
621 try test_i128_intFromFloat_f64(-0x1.FFFFFEp+62, -0x7fffff8000000000);
622 try test_i128_intFromFloat_f64(-0x1.FFFFFCp+62, -0x7fffff0000000000);
623
624 try test_i128_intFromFloat_f64(-2.01, -2);
625 try test_i128_intFromFloat_f64(-2.0, -2);
626 try test_i128_intFromFloat_f64(-1.99, -1);
627 try test_i128_intFromFloat_f64(-1.0, -1);
628 try test_i128_intFromFloat_f64(-0.99, 0);
629 try test_i128_intFromFloat_f64(-0.5, 0);
630 try test_i128_intFromFloat_f64(-math.floatMin(f64), 0);
631 try test_i128_intFromFloat_f64(0.0, 0);
632 try test_i128_intFromFloat_f64(math.floatMin(f64), 0);
633 try test_i128_intFromFloat_f64(0.5, 0);
634 try test_i128_intFromFloat_f64(0.99, 0);
635 try test_i128_intFromFloat_f64(1.0, 1);
636 try test_i128_intFromFloat_f64(1.5, 1);
637 try test_i128_intFromFloat_f64(1.99, 1);
638 try test_i128_intFromFloat_f64(2.0, 2);
639 try test_i128_intFromFloat_f64(2.01, 2);
640
641 try test_i128_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
642 try test_i128_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
643
644 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
645 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
646 try test_i128_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000);
647 try test_i128_intFromFloat_f64(0x1.0000000000001p+63, 0x8000000000000800);
648
649 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);
650 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);
651 try test_i128_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
652
653 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
654 try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
655
656 try test_i128_intFromFloat_f64(math.floatMax(f64), math.maxInt(i128));
641657}
642658
643test "fixunsdfti" {
644 try test__fixunsdfti(0.0, 0);
645
646 try test__fixunsdfti(0.5, 0);
647 try test__fixunsdfti(0.99, 0);
648 try test__fixunsdfti(1.0, 1);
649 try test__fixunsdfti(1.5, 1);
650 try test__fixunsdfti(1.99, 1);
651 try test__fixunsdfti(2.0, 2);
652 try test__fixunsdfti(2.01, 2);
653 try test__fixunsdfti(-0.5, 0);
654 try test__fixunsdfti(-0.99, 0);
655 try test__fixunsdfti(-1.0, 0);
656 try test__fixunsdfti(-1.5, 0);
657 try test__fixunsdfti(-1.99, 0);
658 try test__fixunsdfti(-2.0, 0);
659 try test__fixunsdfti(-2.01, 0);
660
661 try test__fixunsdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
662 try test__fixunsdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
663
664 try test__fixunsdfti(-0x1.FFFFFEp+62, 0);
665 try test__fixunsdfti(-0x1.FFFFFCp+62, 0);
666
667 try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800);
668 try test__fixunsdfti(0x1.0000000000000p+63, 0x8000000000000000);
669 try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
670 try test__fixunsdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
671
672 try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+127, 0xFFFFFFFFFFFFF8000000000000000000);
673 try test__fixunsdfti(0x1.0000000000000p+127, 0x80000000000000000000000000000000);
674 try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);
675 try test__fixunsdfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);
676 try test__fixunsdfti(0x1.0000000000000p+128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
677
678 try test__fixunsdfti(-0x1.FFFFFFFFFFFFFp+62, 0);
679 try test__fixunsdfti(-0x1.FFFFFFFFFFFFEp+62, 0);
659test u128_intFromFloat_f64 {
660 try test_u128_intFromFloat_f64(0.0, 0);
661
662 try test_u128_intFromFloat_f64(0.5, 0);
663 try test_u128_intFromFloat_f64(0.99, 0);
664 try test_u128_intFromFloat_f64(1.0, 1);
665 try test_u128_intFromFloat_f64(1.5, 1);
666 try test_u128_intFromFloat_f64(1.99, 1);
667 try test_u128_intFromFloat_f64(2.0, 2);
668 try test_u128_intFromFloat_f64(2.01, 2);
669 try test_u128_intFromFloat_f64(-0.5, 0);
670 try test_u128_intFromFloat_f64(-0.99, 0);
671 try test_u128_intFromFloat_f64(-1.0, 0);
672 try test_u128_intFromFloat_f64(-1.5, 0);
673 try test_u128_intFromFloat_f64(-1.99, 0);
674 try test_u128_intFromFloat_f64(-2.0, 0);
675 try test_u128_intFromFloat_f64(-2.01, 0);
676
677 try test_u128_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
678 try test_u128_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
679
680 try test_u128_intFromFloat_f64(-0x1.FFFFFEp+62, 0);
681 try test_u128_intFromFloat_f64(-0x1.FFFFFCp+62, 0);
682
683 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800);
684 try test_u128_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000);
685 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
686 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
687
688 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+127, 0xFFFFFFFFFFFFF8000000000000000000);
689 try test_u128_intFromFloat_f64(0x1.0000000000000p+127, 0x80000000000000000000000000000000);
690 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);
691 try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);
692 try test_u128_intFromFloat_f64(0x1.0000000000000p+128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
693
694 try test_u128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, 0);
695 try test_u128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, 0);
680696}
681697
682fn test_fixdfei(comptime T: type, expected: T, a: f64) !void {
698fn test_intFromFloat_f64(comptime T: type, expected: T, a: f64) !void {
683699 const int = @typeInfo(T).int;
684700 var actual: T = undefined;
685701 _ = switch (int.signedness) {
686 .signed => __fixdfei,
687 .unsigned => __fixunsdfei,
688 }(@ptrCast(&actual), int.bits, a);
702 .signed => signed_intFromFloat_f64,
703 .unsigned => unsigned_intFromFloat_f64,
704 }(@ptrCast(&actual), a);
689705 try testing.expect(expected == actual);
690706}
691707
692test "fixdfei" {
693 try test_fixdfei(i256, -1 << 255, -0x1p255);
694 try test_fixdfei(i256, -1 << 127, -0x1p127);
695 try test_fixdfei(i256, -1 << 100, -0x1p100);
696 try test_fixdfei(i256, -1 << 50, -0x1p50);
697 try test_fixdfei(i256, -1 << 1, -0x1p1);
698 try test_fixdfei(i256, -1 << 0, -0x1p0);
699 try test_fixdfei(i256, 0, 0);
700 try test_fixdfei(i256, 1 << 0, 0x1p0);
701 try test_fixdfei(i256, 1 << 1, 0x1p1);
702 try test_fixdfei(i256, 1 << 50, 0x1p50);
703 try test_fixdfei(i256, 1 << 100, 0x1p100);
704 try test_fixdfei(i256, 1 << 127, 0x1p127);
705 try test_fixdfei(i256, 1 << 254, 0x1p254);
708test signed_intFromFloat_f64 {
709 try test_intFromFloat_f64(i256, -1 << 255, -0x1p255);
710 try test_intFromFloat_f64(i256, -1 << 127, -0x1p127);
711 try test_intFromFloat_f64(i256, -1 << 100, -0x1p100);
712 try test_intFromFloat_f64(i256, -1 << 50, -0x1p50);
713 try test_intFromFloat_f64(i256, -1 << 1, -0x1p1);
714 try test_intFromFloat_f64(i256, -1 << 0, -0x1p0);
715 try test_intFromFloat_f64(i256, 0, 0);
716 try test_intFromFloat_f64(i256, 1 << 0, 0x1p0);
717 try test_intFromFloat_f64(i256, 1 << 1, 0x1p1);
718 try test_intFromFloat_f64(i256, 1 << 50, 0x1p50);
719 try test_intFromFloat_f64(i256, 1 << 100, 0x1p100);
720 try test_intFromFloat_f64(i256, 1 << 127, 0x1p127);
721 try test_intFromFloat_f64(i256, 1 << 254, 0x1p254);
706722}
707723
708test "fixundfei" {
709 try test_fixdfei(u256, 0, 0);
710 try test_fixdfei(u256, 1 << 0, 0x1p0);
711 try test_fixdfei(u256, 1 << 1, 0x1p1);
712 try test_fixdfei(u256, 1 << 50, 0x1p50);
713 try test_fixdfei(u256, 1 << 100, 0x1p100);
714 try test_fixdfei(u256, 1 << 127, 0x1p127);
715 try test_fixdfei(u256, 1 << 255, 0x1p255);
724test unsigned_intFromFloat_f64 {
725 try test_intFromFloat_f64(u256, 0, 0);
726 try test_intFromFloat_f64(u256, 1 << 0, 0x1p0);
727 try test_intFromFloat_f64(u256, 1 << 1, 0x1p1);
728 try test_intFromFloat_f64(u256, 1 << 50, 0x1p50);
729 try test_intFromFloat_f64(u256, 1 << 100, 0x1p100);
730 try test_intFromFloat_f64(u256, 1 << 127, 0x1p127);
731 try test_intFromFloat_f64(u256, 1 << 255, 0x1p255);
716732}
717733
718fn test__fixtfsi(a: f128, expected: i32) !void {
719 const x = __fixtfsi(a);
734fn test_i32_intFromFloat_f128(a: f128, expected: i32) !void {
735 const x = i32_intFromFloat_f128(a);
720736 try testing.expect(x == expected);
721737}
722738
723fn test__fixunstfsi(a: f128, expected: u32) !void {
724 const x = __fixunstfsi(a);
739fn test_u32_intFromFloat_f128(a: f128, expected: u32) !void {
740 const x = u32_intFromFloat_f128(a);
725741 try testing.expect(x == expected);
726742}
727743
728test "fixtfsi" {
729 try test__fixtfsi(-math.floatMax(f128), math.minInt(i32));
730
731 try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
732 try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
733
734 try test__fixtfsi(-0x1.0000000000000p+127, -0x80000000);
735 try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
736 try test__fixtfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
737
738 try test__fixtfsi(-0x1.0000000000001p+63, -0x80000000);
739 try test__fixtfsi(-0x1.0000000000000p+63, -0x80000000);
740 try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);
741 try test__fixtfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);
742
743 try test__fixtfsi(-0x1.FFFFFEp+62, -0x80000000);
744 try test__fixtfsi(-0x1.FFFFFCp+62, -0x80000000);
745
746 try test__fixtfsi(-0x1.000000p+31, -0x80000000);
747 try test__fixtfsi(-0x1.FFFFFFp+30, -0x7FFFFFC0);
748 try test__fixtfsi(-0x1.FFFFFEp+30, -0x7FFFFF80);
749 try test__fixtfsi(-0x1.FFFFFCp+30, -0x7FFFFF00);
750
751 try test__fixtfsi(-2.01, -2);
752 try test__fixtfsi(-2.0, -2);
753 try test__fixtfsi(-1.99, -1);
754 try test__fixtfsi(-1.0, -1);
755 try test__fixtfsi(-0.99, 0);
756 try test__fixtfsi(-0.5, 0);
757 try test__fixtfsi(-math.floatMin(f32), 0);
758 try test__fixtfsi(0.0, 0);
759 try test__fixtfsi(math.floatMin(f32), 0);
760 try test__fixtfsi(0.5, 0);
761 try test__fixtfsi(0.99, 0);
762 try test__fixtfsi(1.0, 1);
763 try test__fixtfsi(1.5, 1);
764 try test__fixtfsi(1.99, 1);
765 try test__fixtfsi(2.0, 2);
766 try test__fixtfsi(2.01, 2);
767
768 try test__fixtfsi(0x1.FFFFFCp+30, 0x7FFFFF00);
769 try test__fixtfsi(0x1.FFFFFEp+30, 0x7FFFFF80);
770 try test__fixtfsi(0x1.FFFFFFp+30, 0x7FFFFFC0);
771 try test__fixtfsi(0x1.000000p+31, 0x7FFFFFFF);
772
773 try test__fixtfsi(0x1.FFFFFCp+62, 0x7FFFFFFF);
774 try test__fixtfsi(0x1.FFFFFEp+62, 0x7FFFFFFF);
775
776 try test__fixtfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
777 try test__fixtfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
778 try test__fixtfsi(0x1.0000000000000p+63, 0x7FFFFFFF);
779 try test__fixtfsi(0x1.0000000000001p+63, 0x7FFFFFFF);
780
781 try test__fixtfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
782 try test__fixtfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
783 try test__fixtfsi(0x1.0000000000000p+127, 0x7FFFFFFF);
784
785 try test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
786 try test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
787
788 try test__fixtfsi(math.floatMax(f128), math.maxInt(i32));
744test i32_intFromFloat_f128 {
745 try test_i32_intFromFloat_f128(-math.floatMax(f128), math.minInt(i32));
746
747 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32));
748 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000);
749
750 try test_i32_intFromFloat_f128(-0x1.0000000000000p+127, -0x80000000);
751 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x80000000);
752 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x80000000);
753
754 try test_i32_intFromFloat_f128(-0x1.0000000000001p+63, -0x80000000);
755 try test_i32_intFromFloat_f128(-0x1.0000000000000p+63, -0x80000000);
756 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x80000000);
757 try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x80000000);
758
759 try test_i32_intFromFloat_f128(-0x1.FFFFFEp+62, -0x80000000);
760 try test_i32_intFromFloat_f128(-0x1.FFFFFCp+62, -0x80000000);
761
762 try test_i32_intFromFloat_f128(-0x1.000000p+31, -0x80000000);
763 try test_i32_intFromFloat_f128(-0x1.FFFFFFp+30, -0x7FFFFFC0);
764 try test_i32_intFromFloat_f128(-0x1.FFFFFEp+30, -0x7FFFFF80);
765 try test_i32_intFromFloat_f128(-0x1.FFFFFCp+30, -0x7FFFFF00);
766
767 try test_i32_intFromFloat_f128(-2.01, -2);
768 try test_i32_intFromFloat_f128(-2.0, -2);
769 try test_i32_intFromFloat_f128(-1.99, -1);
770 try test_i32_intFromFloat_f128(-1.0, -1);
771 try test_i32_intFromFloat_f128(-0.99, 0);
772 try test_i32_intFromFloat_f128(-0.5, 0);
773 try test_i32_intFromFloat_f128(-math.floatMin(f32), 0);
774 try test_i32_intFromFloat_f128(0.0, 0);
775 try test_i32_intFromFloat_f128(math.floatMin(f32), 0);
776 try test_i32_intFromFloat_f128(0.5, 0);
777 try test_i32_intFromFloat_f128(0.99, 0);
778 try test_i32_intFromFloat_f128(1.0, 1);
779 try test_i32_intFromFloat_f128(1.5, 1);
780 try test_i32_intFromFloat_f128(1.99, 1);
781 try test_i32_intFromFloat_f128(2.0, 2);
782 try test_i32_intFromFloat_f128(2.01, 2);
783
784 try test_i32_intFromFloat_f128(0x1.FFFFFCp+30, 0x7FFFFF00);
785 try test_i32_intFromFloat_f128(0x1.FFFFFEp+30, 0x7FFFFF80);
786 try test_i32_intFromFloat_f128(0x1.FFFFFFp+30, 0x7FFFFFC0);
787 try test_i32_intFromFloat_f128(0x1.000000p+31, 0x7FFFFFFF);
788
789 try test_i32_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFFFF);
790 try test_i32_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFFFF);
791
792 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF);
793 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF);
794 try test_i32_intFromFloat_f128(0x1.0000000000000p+63, 0x7FFFFFFF);
795 try test_i32_intFromFloat_f128(0x1.0000000000001p+63, 0x7FFFFFFF);
796
797 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF);
798 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF);
799 try test_i32_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFF);
800
801 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF);
802 try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32));
803
804 try test_i32_intFromFloat_f128(math.floatMax(f128), math.maxInt(i32));
789805}
790806
791test "fixunstfsi" {
792 try test__fixunstfsi(math.inf(f128), 0xffffffff);
793 try test__fixunstfsi(0, 0x0);
794 try test__fixunstfsi(0x1.23456789abcdefp+5, 0x24);
795 try test__fixunstfsi(0x1.23456789abcdefp-3, 0x0);
796 try test__fixunstfsi(0x1.23456789abcdefp+20, 0x123456);
797 try test__fixunstfsi(0x1.23456789abcdefp+40, 0xffffffff);
798 try test__fixunstfsi(0x1.23456789abcdefp+256, 0xffffffff);
799 try test__fixunstfsi(-0x1.23456789abcdefp+3, 0x0);
800
801 try test__fixunstfsi(0x1p+32, 0xFFFFFFFF);
807test u32_intFromFloat_f128 {
808 try test_u32_intFromFloat_f128(math.inf(f128), 0xffffffff);
809 try test_u32_intFromFloat_f128(0, 0x0);
810 try test_u32_intFromFloat_f128(0x1.23456789abcdefp+5, 0x24);
811 try test_u32_intFromFloat_f128(0x1.23456789abcdefp-3, 0x0);
812 try test_u32_intFromFloat_f128(0x1.23456789abcdefp+20, 0x123456);
813 try test_u32_intFromFloat_f128(0x1.23456789abcdefp+40, 0xffffffff);
814 try test_u32_intFromFloat_f128(0x1.23456789abcdefp+256, 0xffffffff);
815 try test_u32_intFromFloat_f128(-0x1.23456789abcdefp+3, 0x0);
816
817 try test_u32_intFromFloat_f128(0x1p+32, 0xFFFFFFFF);
802818}
803819
804fn test__fixtfdi(a: f128, expected: i64) !void {
805 const x = __fixtfdi(a);
820fn test_i64_intFromFloat_f128(a: f128, expected: i64) !void {
821 const x = i64_intFromFloat_f128(a);
806822 try testing.expect(x == expected);
807823}
808824
809fn test__fixunstfdi(a: f128, expected: u64) !void {
810 const x = __fixunstfdi(a);
825fn test_u64_intFromFloat_f128(a: f128, expected: u64) !void {
826 const x = u64_intFromFloat_f128(a);
811827 try testing.expect(x == expected);
812828}
813829
814test "fixtfdi" {
815 try test__fixtfdi(-math.floatMax(f128), math.minInt(i64));
816
817 try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
818 try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
819
820 try test__fixtfdi(-0x1.0000000000000p+127, -0x8000000000000000);
821 try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
822 try test__fixtfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
823
824 try test__fixtfdi(-0x1.0000000000001p+63, -0x8000000000000000);
825 try test__fixtfdi(-0x1.0000000000000p+63, -0x8000000000000000);
826 try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
827 try test__fixtfdi(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
828
829 try test__fixtfdi(-0x1.FFFFFEp+62, -0x7FFFFF8000000000);
830 try test__fixtfdi(-0x1.FFFFFCp+62, -0x7FFFFF0000000000);
831
832 try test__fixtfdi(-0x1.000000p+31, -0x80000000);
833 try test__fixtfdi(-0x1.FFFFFFp+30, -0x7FFFFFC0);
834 try test__fixtfdi(-0x1.FFFFFEp+30, -0x7FFFFF80);
835 try test__fixtfdi(-0x1.FFFFFCp+30, -0x7FFFFF00);
836
837 try test__fixtfdi(-2.01, -2);
838 try test__fixtfdi(-2.0, -2);
839 try test__fixtfdi(-1.99, -1);
840 try test__fixtfdi(-1.0, -1);
841 try test__fixtfdi(-0.99, 0);
842 try test__fixtfdi(-0.5, 0);
843 try test__fixtfdi(-math.floatMin(f64), 0);
844 try test__fixtfdi(0.0, 0);
845 try test__fixtfdi(math.floatMin(f64), 0);
846 try test__fixtfdi(0.5, 0);
847 try test__fixtfdi(0.99, 0);
848 try test__fixtfdi(1.0, 1);
849 try test__fixtfdi(1.5, 1);
850 try test__fixtfdi(1.99, 1);
851 try test__fixtfdi(2.0, 2);
852 try test__fixtfdi(2.01, 2);
853
854 try test__fixtfdi(0x1.FFFFFCp+30, 0x7FFFFF00);
855 try test__fixtfdi(0x1.FFFFFEp+30, 0x7FFFFF80);
856 try test__fixtfdi(0x1.FFFFFFp+30, 0x7FFFFFC0);
857 try test__fixtfdi(0x1.000000p+31, 0x80000000);
858
859 try test__fixtfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
860 try test__fixtfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
861
862 try test__fixtfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
863 try test__fixtfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
864 try test__fixtfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
865 try test__fixtfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
866
867 try test__fixtfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
868 try test__fixtfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
869 try test__fixtfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
870
871 try test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
872 try test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
873
874 try test__fixtfdi(math.floatMax(f128), math.maxInt(i64));
830test i64_intFromFloat_f128 {
831 try test_i64_intFromFloat_f128(-math.floatMax(f128), math.minInt(i64));
832
833 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64));
834 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000);
835
836 try test_i64_intFromFloat_f128(-0x1.0000000000000p+127, -0x8000000000000000);
837 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000);
838 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000);
839
840 try test_i64_intFromFloat_f128(-0x1.0000000000001p+63, -0x8000000000000000);
841 try test_i64_intFromFloat_f128(-0x1.0000000000000p+63, -0x8000000000000000);
842 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
843 try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
844
845 try test_i64_intFromFloat_f128(-0x1.FFFFFEp+62, -0x7FFFFF8000000000);
846 try test_i64_intFromFloat_f128(-0x1.FFFFFCp+62, -0x7FFFFF0000000000);
847
848 try test_i64_intFromFloat_f128(-0x1.000000p+31, -0x80000000);
849 try test_i64_intFromFloat_f128(-0x1.FFFFFFp+30, -0x7FFFFFC0);
850 try test_i64_intFromFloat_f128(-0x1.FFFFFEp+30, -0x7FFFFF80);
851 try test_i64_intFromFloat_f128(-0x1.FFFFFCp+30, -0x7FFFFF00);
852
853 try test_i64_intFromFloat_f128(-2.01, -2);
854 try test_i64_intFromFloat_f128(-2.0, -2);
855 try test_i64_intFromFloat_f128(-1.99, -1);
856 try test_i64_intFromFloat_f128(-1.0, -1);
857 try test_i64_intFromFloat_f128(-0.99, 0);
858 try test_i64_intFromFloat_f128(-0.5, 0);
859 try test_i64_intFromFloat_f128(-math.floatMin(f64), 0);
860 try test_i64_intFromFloat_f128(0.0, 0);
861 try test_i64_intFromFloat_f128(math.floatMin(f64), 0);
862 try test_i64_intFromFloat_f128(0.5, 0);
863 try test_i64_intFromFloat_f128(0.99, 0);
864 try test_i64_intFromFloat_f128(1.0, 1);
865 try test_i64_intFromFloat_f128(1.5, 1);
866 try test_i64_intFromFloat_f128(1.99, 1);
867 try test_i64_intFromFloat_f128(2.0, 2);
868 try test_i64_intFromFloat_f128(2.01, 2);
869
870 try test_i64_intFromFloat_f128(0x1.FFFFFCp+30, 0x7FFFFF00);
871 try test_i64_intFromFloat_f128(0x1.FFFFFEp+30, 0x7FFFFF80);
872 try test_i64_intFromFloat_f128(0x1.FFFFFFp+30, 0x7FFFFFC0);
873 try test_i64_intFromFloat_f128(0x1.000000p+31, 0x80000000);
874
875 try test_i64_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
876 try test_i64_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
877
878 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
879 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
880 try test_i64_intFromFloat_f128(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF);
881 try test_i64_intFromFloat_f128(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF);
882
883 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF);
884 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF);
885 try test_i64_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF);
886
887 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF);
888 try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64));
889
890 try test_i64_intFromFloat_f128(math.floatMax(f128), math.maxInt(i64));
875891}
876892
877test "fixunstfdi" {
878 try test__fixunstfdi(0.0, 0);
879
880 try test__fixunstfdi(0.5, 0);
881 try test__fixunstfdi(0.99, 0);
882 try test__fixunstfdi(1.0, 1);
883 try test__fixunstfdi(1.5, 1);
884 try test__fixunstfdi(1.99, 1);
885 try test__fixunstfdi(2.0, 2);
886 try test__fixunstfdi(2.01, 2);
887 try test__fixunstfdi(-0.5, 0);
888 try test__fixunstfdi(-0.99, 0);
889 try test__fixunstfdi(-1.0, 0);
890 try test__fixunstfdi(-1.5, 0);
891 try test__fixunstfdi(-1.99, 0);
892 try test__fixunstfdi(-2.0, 0);
893 try test__fixunstfdi(-2.01, 0);
894
895 try test__fixunstfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
896 try test__fixunstfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
897
898 try test__fixunstfdi(-0x1.FFFFFEp+62, 0);
899 try test__fixunstfdi(-0x1.FFFFFCp+62, 0);
900
901 try test__fixunstfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
902 try test__fixunstfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
903
904 try test__fixunstfdi(-0x1.FFFFFFFFFFFFFp+62, 0);
905 try test__fixunstfdi(-0x1.FFFFFFFFFFFFEp+62, 0);
906
907 try test__fixunstfdi(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF);
908 try test__fixunstfdi(0x1.0000000000000002p+63, 0x8000000000000001);
909 try test__fixunstfdi(0x1.0000000000000000p+63, 0x8000000000000000);
910 try test__fixunstfdi(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF);
911 try test__fixunstfdi(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE);
912 try test__fixunstfdi(0x1p+64, 0xFFFFFFFFFFFFFFFF);
913
914 try test__fixunstfdi(-0x1.0000000000000000p+63, 0);
915 try test__fixunstfdi(-0x1.FFFFFFFFFFFFFFFCp+62, 0);
916 try test__fixunstfdi(-0x1.FFFFFFFFFFFFFFF8p+62, 0);
893test u64_intFromFloat_f128 {
894 try test_u64_intFromFloat_f128(0.0, 0);
895
896 try test_u64_intFromFloat_f128(0.5, 0);
897 try test_u64_intFromFloat_f128(0.99, 0);
898 try test_u64_intFromFloat_f128(1.0, 1);
899 try test_u64_intFromFloat_f128(1.5, 1);
900 try test_u64_intFromFloat_f128(1.99, 1);
901 try test_u64_intFromFloat_f128(2.0, 2);
902 try test_u64_intFromFloat_f128(2.01, 2);
903 try test_u64_intFromFloat_f128(-0.5, 0);
904 try test_u64_intFromFloat_f128(-0.99, 0);
905 try test_u64_intFromFloat_f128(-1.0, 0);
906 try test_u64_intFromFloat_f128(-1.5, 0);
907 try test_u64_intFromFloat_f128(-1.99, 0);
908 try test_u64_intFromFloat_f128(-2.0, 0);
909 try test_u64_intFromFloat_f128(-2.01, 0);
910
911 try test_u64_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
912 try test_u64_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
913
914 try test_u64_intFromFloat_f128(-0x1.FFFFFEp+62, 0);
915 try test_u64_intFromFloat_f128(-0x1.FFFFFCp+62, 0);
916
917 try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
918 try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
919
920 try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, 0);
921 try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, 0);
922
923 try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF);
924 try test_u64_intFromFloat_f128(0x1.0000000000000002p+63, 0x8000000000000001);
925 try test_u64_intFromFloat_f128(0x1.0000000000000000p+63, 0x8000000000000000);
926 try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF);
927 try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE);
928 try test_u64_intFromFloat_f128(0x1p+64, 0xFFFFFFFFFFFFFFFF);
929
930 try test_u64_intFromFloat_f128(-0x1.0000000000000000p+63, 0);
931 try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFFFCp+62, 0);
932 try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFFF8p+62, 0);
917933}
918934
919fn test__fixtfti(a: f128, expected: i128) !void {
920 const x = __fixtfti(a);
935fn test_i128_intFromFloat_f128(a: f128, expected: i128) !void {
936 const x = i128_intFromFloat_f128(a);
921937 try testing.expect(x == expected);
922938}
923939
924fn test__fixunstfti(a: f128, expected: u128) !void {
925 const x = __fixunstfti(a);
940fn test_u128_intFromFloat_f128(a: f128, expected: u128) !void {
941 const x = u128_intFromFloat_f128(a);
926942 try testing.expect(x == expected);
927943}
928944
929test "fixtfti" {
930 try test__fixtfti(-math.floatMax(f128), math.minInt(i128));
931
932 try test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
933 try test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
934
935 try test__fixtfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
936 try test__fixtfti(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000);
937 try test__fixtfti(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000);
938
939 try test__fixtfti(-0x1.0000000000001p+63, -0x8000000000000800);
940 try test__fixtfti(-0x1.0000000000000p+63, -0x8000000000000000);
941 try test__fixtfti(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
942 try test__fixtfti(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
943
944 try test__fixtfti(-0x1.FFFFFEp+62, -0x7fffff8000000000);
945 try test__fixtfti(-0x1.FFFFFCp+62, -0x7fffff0000000000);
946
947 try test__fixtfti(-2.01, -2);
948 try test__fixtfti(-2.0, -2);
949 try test__fixtfti(-1.99, -1);
950 try test__fixtfti(-1.0, -1);
951 try test__fixtfti(-0.99, 0);
952 try test__fixtfti(-0.5, 0);
953 try test__fixtfti(-math.floatMin(f128), 0);
954 try test__fixtfti(0.0, 0);
955 try test__fixtfti(math.floatMin(f128), 0);
956 try test__fixtfti(0.5, 0);
957 try test__fixtfti(0.99, 0);
958 try test__fixtfti(1.0, 1);
959 try test__fixtfti(1.5, 1);
960 try test__fixtfti(1.99, 1);
961 try test__fixtfti(2.0, 2);
962 try test__fixtfti(2.01, 2);
963
964 try test__fixtfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
965 try test__fixtfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
966
967 try test__fixtfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
968 try test__fixtfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
969 try test__fixtfti(0x1.0000000000000p+63, 0x8000000000000000);
970 try test__fixtfti(0x1.0000000000001p+63, 0x8000000000000800);
971
972 try test__fixtfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);
973 try test__fixtfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);
974 try test__fixtfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
975
976 try test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
977 try test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
978
979 try test__fixtfti(math.floatMax(f128), math.maxInt(i128));
945test i128_intFromFloat_f128 {
946 try test_i128_intFromFloat_f128(-math.floatMax(f128), math.minInt(i128));
947
948 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128));
949 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000);
950
951 try test_i128_intFromFloat_f128(-0x1.0000000000000p+127, -0x80000000000000000000000000000000);
952 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000);
953 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000);
954
955 try test_i128_intFromFloat_f128(-0x1.0000000000001p+63, -0x8000000000000800);
956 try test_i128_intFromFloat_f128(-0x1.0000000000000p+63, -0x8000000000000000);
957 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00);
958 try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800);
959
960 try test_i128_intFromFloat_f128(-0x1.FFFFFEp+62, -0x7fffff8000000000);
961 try test_i128_intFromFloat_f128(-0x1.FFFFFCp+62, -0x7fffff0000000000);
962
963 try test_i128_intFromFloat_f128(-2.01, -2);
964 try test_i128_intFromFloat_f128(-2.0, -2);
965 try test_i128_intFromFloat_f128(-1.99, -1);
966 try test_i128_intFromFloat_f128(-1.0, -1);
967 try test_i128_intFromFloat_f128(-0.99, 0);
968 try test_i128_intFromFloat_f128(-0.5, 0);
969 try test_i128_intFromFloat_f128(-math.floatMin(f128), 0);
970 try test_i128_intFromFloat_f128(0.0, 0);
971 try test_i128_intFromFloat_f128(math.floatMin(f128), 0);
972 try test_i128_intFromFloat_f128(0.5, 0);
973 try test_i128_intFromFloat_f128(0.99, 0);
974 try test_i128_intFromFloat_f128(1.0, 1);
975 try test_i128_intFromFloat_f128(1.5, 1);
976 try test_i128_intFromFloat_f128(1.99, 1);
977 try test_i128_intFromFloat_f128(2.0, 2);
978 try test_i128_intFromFloat_f128(2.01, 2);
979
980 try test_i128_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000);
981 try test_i128_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000);
982
983 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800);
984 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00);
985 try test_i128_intFromFloat_f128(0x1.0000000000000p+63, 0x8000000000000000);
986 try test_i128_intFromFloat_f128(0x1.0000000000001p+63, 0x8000000000000800);
987
988 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000);
989 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000);
990 try test_i128_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
991
992 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
993 try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128));
994
995 try test_i128_intFromFloat_f128(math.floatMax(f128), math.maxInt(i128));
980996}
981997
982test "fixunstfti" {
983 try test__fixunstfti(math.inf(f128), 0xffffffffffffffffffffffffffffffff);
998test u128_intFromFloat_f128 {
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);
988 try test__fixunstfti(0.99, 0);
989 try test__fixunstfti(1.0, 1);
990 try test__fixunstfti(1.5, 1);
991 try test__fixunstfti(1.99, 1);
992 try test__fixunstfti(2.0, 2);
993 try test__fixunstfti(2.01, 2);
994 try test__fixunstfti(-0.01, 0);
995 try test__fixunstfti(-0.99, 0);
1003 try test_u128_intFromFloat_f128(0.5, 0);
1004 try test_u128_intFromFloat_f128(0.99, 0);
1005 try test_u128_intFromFloat_f128(1.0, 1);
1006 try test_u128_intFromFloat_f128(1.5, 1);
1007 try test_u128_intFromFloat_f128(1.99, 1);
1008 try test_u128_intFromFloat_f128(2.0, 2);
1009 try test_u128_intFromFloat_f128(2.01, 2);
1010 try test_u128_intFromFloat_f128(-0.01, 0);
1011 try test_u128_intFromFloat_f128(-0.99, 0);
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);
1000 try test__fixunstfti(0x1.FFFFFEp+127, 0xffffff00000000000000000000000000);
1001 try test__fixunstfti(0x1.FFFFFEp+128, 0xffffffffffffffffffffffffffffffff);
1002 try test__fixunstfti(0x1.FFFFFEp+129, 0xffffffffffffffffffffffffffffffff);
1015 try test_u128_intFromFloat_f128(0x1.FFFFFEp+126, 0x7fffff80000000000000000000000000);
1016 try test_u128_intFromFloat_f128(0x1.FFFFFEp+127, 0xffffff00000000000000000000000000);
1017 try test_u128_intFromFloat_f128(0x1.FFFFFEp+128, 0xffffffffffffffffffffffffffffffff);
1018 try test_u128_intFromFloat_f128(0x1.FFFFFEp+129, 0xffffffffffffffffffffffffffffffff);
10031019}
10041020
1005fn test__fixunshfti(a: f16, expected: u128) !void {
1006 const x = __fixunshfti(a);
1021fn test_u128_intFromFloat_f16(a: f16, expected: u128) !void {
1022 const x = impl.u128_intFromFloat_f16(a);
10071023 try testing.expect(x == expected);
10081024}
10091025
1010test "fixunshfti for f16" {
1011 try test__fixunshfti(math.inf(f16), math.maxInt(u128));
1012 try test__fixunshfti(math.floatMax(f16), 65504);
1026test u128_intFromFloat_f16 {
1027 try test_u128_intFromFloat_f16(math.inf(f16), math.maxInt(u128));
1028 try test_u128_intFromFloat_f16(math.floatMax(f16), 65504);
10131029}
10141030
1015fn test__fixunsxfti(a: f80, expected: u128) !void {
1016 const x = __fixunsxfti(a);
1031fn test_u128_intFromFloat_f80(a: f80, expected: u128) !void {
1032 const x = impl.u128_intFromFloat_f80(a);
10171033 try testing.expect(x == expected);
10181034}
10191035
1020test "fixunsxfti for f80" {
1021 try test__fixunsxfti(math.inf(f80), math.maxInt(u128));
1022 try test__fixunsxfti(math.floatMax(f80), math.maxInt(u128));
1023 try test__fixunsxfti(math.maxInt(u64), math.maxInt(u64));
1036test u128_intFromFloat_f80 {
1037 try test_u128_intFromFloat_f80(math.inf(f80), math.maxInt(u128));
1038 try test_u128_intFromFloat_f80(math.floatMax(f80), math.maxInt(u128));
1039 try test_u128_intFromFloat_f80(math.maxInt(u64), math.maxInt(u64));
10241040}
lib/compiler_rt/limb64.zig+1-1
......@@ -6,7 +6,7 @@ const minInt = std.math.minInt;
66
77const builtin = @import("builtin");
88const compiler_rt = @import("../compiler_rt.zig");
9const symbol = @import("../compiler_rt.zig").symbol;
9const symbol = compiler_rt.symbol;
1010
1111const endian = builtin.cpu.arch.endian();
1212
lib/compiler_rt/log.zig+112-97
......@@ -11,7 +11,7 @@ const expectEqual = std.testing.expectEqual;
1111const expectApproxEqRel = std.testing.expectApproxEqRel;
1212
1313const compiler_rt = @import("../compiler_rt.zig");
14const symbol = @import("../compiler_rt.zig").symbol;
14const symbol = compiler_rt.symbol;
1515
1616comptime {
1717 symbol(&__logh, "__logh");
......@@ -25,12 +25,18 @@ comptime {
2525 symbol(&logl, "logl");
2626}
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 {
2932 // TODO: more efficient implementation
30 return @floatCast(logf(a));
33 return @floatCast(log_f32(a));
3134}
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 {
3440 const ln2_hi: f32 = 6.9313812256e-01;
3541 const ln2_lo: f32 = 9.0580006145e-06;
3642 const Lg1: f32 = 0xaaaaaa.0p-24;
......@@ -82,7 +88,10 @@ pub fn logf(x_: f32) callconv(.c) f32 {
8288 return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
8389}
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 {
8695 const poly1 = [_]f64{
8796 -0x1p-1,
8897 0x1.5555555555577p-2,
......@@ -432,11 +441,17 @@ pub fn log(x: f64) callconv(.c) f64 {
432441 return @bitCast(y);
433442}
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 {
436448 // TODO: more efficient implementation
437 return @floatCast(logq(a));
449 return @floatCast(log_f128(a));
438450}
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}
440455/// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic"
441456/// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990
442457///
......@@ -449,7 +464,7 @@ pub fn __logx(a: f80) callconv(.c) f80 {
449464///
450465/// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case):
451466/// <= 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 {
453468 const impl = @import("log_f128.zig");
454469
455470 if (impl.specialCases(x)) |y|
......@@ -626,123 +641,123 @@ pub fn logq(x: f128) callconv(.c) f128 {
626641
627642pub fn logl(x: c_longdouble) callconv(.c) c_longdouble {
628643 switch (@typeInfo(c_longdouble).float.bits) {
629 64 => return log(x),
630 80 => return __logx(x),
631 128 => return logq(x),
632 else => @compileError("unreachable"),
644 64 => return log_f64(x),
645 80 => return log_f80(x),
646 128 => return log_f128(x),
647 else => comptime unreachable,
633648 }
634649}
635650
636651test "logf() special" {
637 try expectEqual(logf(0.0), -math.inf(f32));
638 try expectEqual(logf(-0.0), -math.inf(f32));
639 try expect(math.isPositiveZero(logf(1.0)));
640 try expectEqual(logf(math.e), 1.0);
641 try expectEqual(logf(math.inf(f32)), math.inf(f32));
642 try expect(math.isNan(logf(-1.0)));
643 try expect(math.isNan(logf(-math.inf(f32))));
644 try expect(math.isNan(logf(math.nan(f32))));
645 try expect(math.isNan(logf(math.snan(f32))));
652 try expectEqual(log_f32(0.0), -math.inf(f32));
653 try expectEqual(log_f32(-0.0), -math.inf(f32));
654 try expect(math.isPositiveZero(log_f32(1.0)));
655 try expectEqual(log_f32(math.e), 1.0);
656 try expectEqual(log_f32(math.inf(f32)), math.inf(f32));
657 try expect(math.isNan(log_f32(-1.0)));
658 try expect(math.isNan(log_f32(-math.inf(f32))));
659 try expect(math.isNan(log_f32(math.nan(f32))));
660 try expect(math.isNan(log_f32(math.snan(f32))));
646661}
647662
648663test "logf() sanity" {
649 try expect(math.isNan(logf(-0x1.0223a0p+3)));
650 try expectEqual(logf(0x1.161868p+2), 0x1.7815b0p+0);
651 try expect(math.isNan(logf(-0x1.0c34b4p+3)));
652 try expect(math.isNan(logf(-0x1.a206f0p+2)));
653 try expectEqual(logf(0x1.288bbcp+3), 0x1.1cfcd6p+1);
654 try expectEqual(logf(0x1.52efd0p-1), -0x1.a6694cp-2);
655 try expect(math.isNan(logf(-0x1.a05cc8p-2)));
656 try expectEqual(logf(0x1.1f9efap-1), -0x1.2742bap-1);
657 try expectEqual(logf(0x1.8c5db0p-1), -0x1.062160p-2);
658 try expect(math.isNan(logf(-0x1.5b86eap-1)));
664 try expect(math.isNan(log_f32(-0x1.0223a0p+3)));
665 try expectEqual(log_f32(0x1.161868p+2), 0x1.7815b0p+0);
666 try expect(math.isNan(log_f32(-0x1.0c34b4p+3)));
667 try expect(math.isNan(log_f32(-0x1.a206f0p+2)));
668 try expectEqual(log_f32(0x1.288bbcp+3), 0x1.1cfcd6p+1);
669 try expectEqual(log_f32(0x1.52efd0p-1), -0x1.a6694cp-2);
670 try expect(math.isNan(log_f32(-0x1.a05cc8p-2)));
671 try expectEqual(log_f32(0x1.1f9efap-1), -0x1.2742bap-1);
672 try expectEqual(log_f32(0x1.8c5db0p-1), -0x1.062160p-2);
673 try expect(math.isNan(log_f32(-0x1.5b86eap-1)));
659674}
660675
661676test "logf() boundary" {
662 try expectEqual(logf(0x1.fffffep+127), 0x1.62e430p+6); // Max input value
663 try expectEqual(logf(0x1p-149), -0x1.9d1da0p+6); // Min positive input value
664 try expect(math.isNan(logf(-0x1p-149))); // Min negative input value
665 try expectEqual(logf(0x1.000002p+0), 0x1.fffffep-24); // Last value before result reaches +0
666 try expectEqual(logf(0x1.fffffep-1), -0x1p-24); // Last value before result reaches -0
667 try expectEqual(logf(0x1p-126), -0x1.5d58a0p+6); // First subnormal
668 try expect(math.isNan(logf(-0x1p-126))); // First negative subnormal
677 try expectEqual(log_f32(0x1.fffffep+127), 0x1.62e430p+6); // Max input value
678 try expectEqual(log_f32(0x1p-149), -0x1.9d1da0p+6); // Min positive input value
679 try expect(math.isNan(log_f32(-0x1p-149))); // Min negative input value
680 try expectEqual(log_f32(0x1.000002p+0), 0x1.fffffep-24); // Last value before result reaches +0
681 try expectEqual(log_f32(0x1.fffffep-1), -0x1p-24); // Last value before result reaches -0
682 try expectEqual(log_f32(0x1p-126), -0x1.5d58a0p+6); // First subnormal
683 try expect(math.isNan(log_f32(-0x1p-126))); // First negative subnormal
669684}
670685
671686test "log() special" {
672 try expectEqual(log(0.0), -math.inf(f64));
673 try expectEqual(log(-0.0), -math.inf(f64));
674 try expect(math.isPositiveZero(log(1.0)));
675 try expectEqual(log(math.e), 1.0);
676 try expectEqual(log(math.inf(f64)), math.inf(f64));
677 try expect(math.isNan(log(-1.0)));
678 try expect(math.isNan(log(-math.inf(f64))));
679 try expect(math.isNan(log(math.nan(f64))));
680 try expect(math.isNan(log(math.snan(f64))));
687 try expectEqual(log_f64(0.0), -math.inf(f64));
688 try expectEqual(log_f64(-0.0), -math.inf(f64));
689 try expect(math.isPositiveZero(log_f64(1.0)));
690 try expectEqual(log_f64(math.e), 1.0);
691 try expectEqual(log_f64(math.inf(f64)), math.inf(f64));
692 try expect(math.isNan(log_f64(-1.0)));
693 try expect(math.isNan(log_f64(-math.inf(f64))));
694 try expect(math.isNan(log_f64(math.nan(f64))));
695 try expect(math.isNan(log_f64(math.snan(f64))));
681696}
682697
683698test "log() sanity" {
684 try expect(math.isNan(log(-0x1.02239f3c6a8f1p+3)));
685 try expectEqual(log(0x1.161868e18bc67p+2), 0x1.7815b08f99c65p+0);
686 try expect(math.isNan(log(-0x1.0c34b3e01e6e7p+3)));
687 try expect(math.isNan(log(-0x1.a206f0a19dcc4p+2)));
688 try expectEqual(log(0x1.288bbb0d6a1e6p+3), 0x1.1cfcd53d72604p+1);
689 try expectEqual(log(0x1.52efd0cd80497p-1), -0x1.a6694a4a85621p-2);
690 try expect(math.isNan(log(-0x1.a05cc754481d1p-2)));
691 try expectEqual(log(0x1.1f9ef934745cbp-1), -0x1.2742bc03d02ddp-1);
692 try expectEqual(log(0x1.8c5db097f7442p-1), -0x1.06215de4a3f92p-2);
693 try expect(math.isNan(log(-0x1.5b86ea8118a0ep-1)));
699 try expect(math.isNan(log_f64(-0x1.02239f3c6a8f1p+3)));
700 try expectEqual(log_f64(0x1.161868e18bc67p+2), 0x1.7815b08f99c65p+0);
701 try expect(math.isNan(log_f64(-0x1.0c34b3e01e6e7p+3)));
702 try expect(math.isNan(log_f64(-0x1.a206f0a19dcc4p+2)));
703 try expectEqual(log_f64(0x1.288bbb0d6a1e6p+3), 0x1.1cfcd53d72604p+1);
704 try expectEqual(log_f64(0x1.52efd0cd80497p-1), -0x1.a6694a4a85621p-2);
705 try expect(math.isNan(log_f64(-0x1.a05cc754481d1p-2)));
706 try expectEqual(log_f64(0x1.1f9ef934745cbp-1), -0x1.2742bc03d02ddp-1);
707 try expectEqual(log_f64(0x1.8c5db097f7442p-1), -0x1.06215de4a3f92p-2);
708 try expect(math.isNan(log_f64(-0x1.5b86ea8118a0ep-1)));
694709}
695710
696711test "log() boundary" {
697 try expectEqual(log(0x1.fffffffffffffp+1023), 0x1.62e42fefa39efp+9); // Max input value
698 try expectEqual(log(0x1p-1074), -0x1.74385446d71c3p+9); // Min positive input value
699 try expect(math.isNan(log(-0x1p-1074))); // Min negative input value
700 try expectEqual(log(0x1.0000000000001p+0), 0x1.fffffffffffffp-53); // Last value before result reaches +0
701 try expectEqual(log(0x1.fffffffffffffp-1), -0x1p-53); // Last value before result reaches -0
702 try expectEqual(log(0x1p-1022), -0x1.6232bdd7abcd2p+9); // First subnormal
703 try expect(math.isNan(log(-0x1p-1022))); // First negative subnormal
712 try expectEqual(log_f64(0x1.fffffffffffffp+1023), 0x1.62e42fefa39efp+9); // Max input value
713 try expectEqual(log_f64(0x1p-1074), -0x1.74385446d71c3p+9); // Min positive input value
714 try expect(math.isNan(log_f64(-0x1p-1074))); // Min negative input value
715 try expectEqual(log_f64(0x1.0000000000001p+0), 0x1.fffffffffffffp-53); // Last value before result reaches +0
716 try expectEqual(log_f64(0x1.fffffffffffffp-1), -0x1p-53); // Last value before result reaches -0
717 try expectEqual(log_f64(0x1p-1022), -0x1.6232bdd7abcd2p+9); // First subnormal
718 try expect(math.isNan(log_f64(-0x1p-1022))); // First negative subnormal
704719}
705720
706721test "logq() special" {
707 try expectEqual(logq(0.0), -math.inf(f128));
708 try expectEqual(logq(-0.0), -math.inf(f128));
709 try expect(math.isPositiveZero(logq(1.0)));
722 try expectEqual(log_f128(0.0), -math.inf(f128));
723 try expectEqual(log_f128(-0.0), -math.inf(f128));
724 try expect(math.isPositiveZero(log_f128(1.0)));
710725 // Sadly, the rounding gods decided that 0.9999999999999999999999999999999999
711 // is the correctly rounded value of logq(math.e)
712 try expectApproxEqRel(logq(math.e), 1.0, math.floatEpsAt(f128, 1.0));
713 try expectEqual(logq(math.inf(f128)), math.inf(f128));
714 try expect(math.isNan(logq(-1.0)));
715 try expect(math.isNan(logq(-math.inf(f128))));
716 try expect(math.isNan(logq(math.nan(f128))));
717 try expect(math.isNan(logq(math.snan(f128))));
726 // is the correctly rounded value of log_f128(math.e)
727 try expectApproxEqRel(log_f128(math.e), 1.0, math.floatEpsAt(f128, 1.0));
728 try expectEqual(log_f128(math.inf(f128)), math.inf(f128));
729 try expect(math.isNan(log_f128(-1.0)));
730 try expect(math.isNan(log_f128(-math.inf(f128))));
731 try expect(math.isNan(log_f128(math.nan(f128))));
732 try expect(math.isNan(log_f128(math.snan(f128))));
718733}
719734
720735test "logq() boundary" {
721 try expectEqual(logq(0x1.ffffffffffffffffffffffffffffp16383), 0x1.62e42fefa39ef35793c7673007e6p13); // Max input value
722 try expectEqual(logq(0x1p-16494), -0x1.6546282207802c89d24d65e96274p13); // Min positive input value
723 try expect(math.isNan(logq(-0x1p-16494))); // Min negative input value
724 try expectEqual(logq(0x1.0000000000000000000000000001p0), 0x1.ffffffffffffffffffffffffffffp-113); // Last value before result reaches +0
725 try expectEqual(logq(0x1.ffffffffffffffffffffffffffffp-1), -0x1p-113); // Last value before result reaches -0
726 try expectEqual(logq(0x1p-16382), -0x1.62d918ce2421d65ff90ac8f4ce66p13); // First subnormal
727 try expect(math.isNan(logq(-0x1p-16382))); // First negative subnormal
736 try expectEqual(log_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1.62e42fefa39ef35793c7673007e6p13); // Max input value
737 try expectEqual(log_f128(0x1p-16494), -0x1.6546282207802c89d24d65e96274p13); // Min positive input value
738 try expect(math.isNan(log_f128(-0x1p-16494))); // Min negative input value
739 try expectEqual(log_f128(0x1.0000000000000000000000000001p0), 0x1.ffffffffffffffffffffffffffffp-113); // Last value before result reaches +0
740 try expectEqual(log_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1p-113); // Last value before result reaches -0
741 try expectEqual(log_f128(0x1p-16382), -0x1.62d918ce2421d65ff90ac8f4ce66p13); // First subnormal
742 try expect(math.isNan(log_f128(-0x1p-16382))); // First negative subnormal
728743}
729744
730745test "logq() sanity" {
731 try expectEqual(logq(4.151135979023751199079583784623537e-4), -7.7869583453055243113993340258295346e0);
732 try expectEqual(logq(9.614234245933828353176667689130293e-14), -2.9972946567656004014786271559909435e1);
733 try expectEqual(logq(1.012889803704721484375e13), 2.9946413646144315985379677542014356e1);
734 try expectEqual(logq(2.397741857206453154086912e24), 5.613656963346284538829358703465392e1);
735 try expectEqual(logq(3.442377567808290806386655232e27), 6.3405959896920645453203836625419693e1);
736 try expectEqual(logq(1.0689155158234028407981544637594257e-8), -1.835403614606774451014272772421113e1);
737 try expectEqual(logq(1.4813913545768791536741499811327596e-10), -2.263286917934202003739900705050399e1);
738 try expectEqual(logq(4.518948965781299591064453125e10), 2.453413036705097282892685629562292e1);
739 try expectEqual(logq(1.200355637363589375e14), 3.2418809179272977400408325788186897e1);
740 try expectEqual(logq(6.6145398293682003021240234375e9), 2.261253606737223221601998075023261e1);
741 try expectEqual(logq(5.16179116383965741056e20), 4.7692985503915646405875629300054525e1);
746 try expectEqual(log_f128(4.151135979023751199079583784623537e-4), -7.7869583453055243113993340258295346e0);
747 try expectEqual(log_f128(9.614234245933828353176667689130293e-14), -2.9972946567656004014786271559909435e1);
748 try expectEqual(log_f128(1.012889803704721484375e13), 2.9946413646144315985379677542014356e1);
749 try expectEqual(log_f128(2.397741857206453154086912e24), 5.613656963346284538829358703465392e1);
750 try expectEqual(log_f128(3.442377567808290806386655232e27), 6.3405959896920645453203836625419693e1);
751 try expectEqual(log_f128(1.0689155158234028407981544637594257e-8), -1.835403614606774451014272772421113e1);
752 try expectEqual(log_f128(1.4813913545768791536741499811327596e-10), -2.263286917934202003739900705050399e1);
753 try expectEqual(log_f128(4.518948965781299591064453125e10), 2.453413036705097282892685629562292e1);
754 try expectEqual(log_f128(1.200355637363589375e14), 3.2418809179272977400408325788186897e1);
755 try expectEqual(log_f128(6.6145398293682003021240234375e9), 2.261253606737223221601998075023261e1);
756 try expectEqual(log_f128(5.16179116383965741056e20), 4.7692985503915646405875629300054525e1);
742757 // testing near 1
743 try expectEqual(logq(1.026586845186097528392910049888087e0), 2.6239557099466251374193777672800004e-2);
744 try expectEqual(logq(9.878220373715243107115568932385941e-1), -1.2252721576456821219120474521538944e-2);
745 try expectEqual(logq(9.417921077517196685541245315675951e-1), -5.997072116986790367958922503195352e-2);
746 try expectEqual(logq(1.043095786320424537962914257605007e0), 4.219300911769055080390811808602425e-2);
747 try expectEqual(logq(1.019043049323190694932517175175235e0), 1.8863999985309781522599012445793722e-2);
758 try expectEqual(log_f128(1.026586845186097528392910049888087e0), 2.6239557099466251374193777672800004e-2);
759 try expectEqual(log_f128(9.878220373715243107115568932385941e-1), -1.2252721576456821219120474521538944e-2);
760 try expectEqual(log_f128(9.417921077517196685541245315675951e-1), -5.997072116986790367958922503195352e-2);
761 try expectEqual(log_f128(1.043095786320424537962914257605007e0), 4.219300911769055080390811808602425e-2);
762 try expectEqual(log_f128(1.019043049323190694932517175175235e0), 1.8863999985309781522599012445793722e-2);
748763}
lib/compiler_rt/log10.zig+113-98
......@@ -25,12 +25,18 @@ comptime {
2525 symbol(&log10l, "log10l");
2626}
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 {
2932 // TODO: more efficient implementation
30 return @floatCast(log10f(a));
33 return @floatCast(log10_f32(a));
3134}
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 {
3440 const ivln10hi: f32 = 4.3432617188e-01;
3541 const ivln10lo: f32 = -3.1689971365e-05;
3642 const log10_2hi: f32 = 3.0102920532e-01;
......@@ -90,7 +96,10 @@ pub fn log10f(x_: f32) callconv(.c) f32 {
9096 return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi;
9197}
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 {
94103 const ivln10hi: f64 = 4.34294481878168880939e-01;
95104 const ivln10lo: f64 = 2.50829467116452752298e-11;
96105 const log10_2hi: f64 = 3.01029995663611771306e-01;
......@@ -165,11 +174,17 @@ pub fn log10(x_: f64) callconv(.c) f64 {
165174 return val_lo + val_hi;
166175}
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 {
169181 // TODO: more efficient implementation
170 return @floatCast(log10q(a));
182 return @floatCast(log10_f128(a));
171183}
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}
173188/// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic"
174189/// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990
175190///
......@@ -182,7 +197,7 @@ pub fn __log10x(a: f80) callconv(.c) f80 {
182197///
183198/// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case):
184199/// <= 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 {
186201 const impl = @import("log_f128.zig");
187202
188203 if (impl.specialCases(x)) |y|
......@@ -359,124 +374,124 @@ pub fn log10q(x: f128) callconv(.c) f128 {
359374
360375pub fn log10l(x: c_longdouble) callconv(.c) c_longdouble {
361376 switch (@typeInfo(c_longdouble).float.bits) {
362 64 => return log10(x),
363 80 => return __log10x(x),
364 128 => return log10q(x),
365 else => @compileError("unreachable"),
377 64 => return log10_f64(x),
378 80 => return log10_f80(x),
379 128 => return log10_f128(x),
380 else => comptime unreachable,
366381 }
367382}
368383
369384test "log10f() special" {
370 try expectEqual(log10f(0.0), -math.inf(f32));
371 try expectEqual(log10f(-0.0), -math.inf(f32));
372 try expect(math.isPositiveZero(log10f(1.0)));
373 try expectEqual(log10f(10.0), 1.0);
374 try expectEqual(log10f(0.1), -1.0);
375 try expectEqual(log10f(math.inf(f32)), math.inf(f32));
376 try expect(math.isNan(log10f(-1.0)));
377 try expect(math.isNan(log10f(-math.inf(f32))));
378 try expect(math.isNan(log10f(math.nan(f32))));
379 try expect(math.isNan(log10f(math.snan(f32))));
385 try expectEqual(log10_f32(0.0), -math.inf(f32));
386 try expectEqual(log10_f32(-0.0), -math.inf(f32));
387 try expect(math.isPositiveZero(log10_f32(1.0)));
388 try expectEqual(log10_f32(10.0), 1.0);
389 try expectEqual(log10_f32(0.1), -1.0);
390 try expectEqual(log10_f32(math.inf(f32)), math.inf(f32));
391 try expect(math.isNan(log10_f32(-1.0)));
392 try expect(math.isNan(log10_f32(-math.inf(f32))));
393 try expect(math.isNan(log10_f32(math.nan(f32))));
394 try expect(math.isNan(log10_f32(math.snan(f32))));
380395}
381396
382397test "log10f() sanity" {
383 try expect(math.isNan(log10f(-0x1.0223a0p+3)));
384 try expectEqual(log10f(0x1.161868p+2), 0x1.46a9bcp-1);
385 try expect(math.isNan(log10f(-0x1.0c34b4p+3)));
386 try expect(math.isNan(log10f(-0x1.a206f0p+2)));
387 try expectEqual(log10f(0x1.288bbcp+3), 0x1.ef1300p-1);
388 try expectEqual(log10f(0x1.52efd0p-1), -0x1.6ee6dcp-3); // Disagrees with GCC in last bit
389 try expect(math.isNan(log10f(-0x1.a05cc8p-2)));
390 try expectEqual(log10f(0x1.1f9efap-1), -0x1.0075ccp-2);
391 try expectEqual(log10f(0x1.8c5db0p-1), -0x1.c75df8p-4);
392 try expect(math.isNan(log10f(-0x1.5b86eap-1)));
398 try expect(math.isNan(log10_f32(-0x1.0223a0p+3)));
399 try expectEqual(log10_f32(0x1.161868p+2), 0x1.46a9bcp-1);
400 try expect(math.isNan(log10_f32(-0x1.0c34b4p+3)));
401 try expect(math.isNan(log10_f32(-0x1.a206f0p+2)));
402 try expectEqual(log10_f32(0x1.288bbcp+3), 0x1.ef1300p-1);
403 try expectEqual(log10_f32(0x1.52efd0p-1), -0x1.6ee6dcp-3); // Disagrees with GCC in last bit
404 try expect(math.isNan(log10_f32(-0x1.a05cc8p-2)));
405 try expectEqual(log10_f32(0x1.1f9efap-1), -0x1.0075ccp-2);
406 try expectEqual(log10_f32(0x1.8c5db0p-1), -0x1.c75df8p-4);
407 try expect(math.isNan(log10_f32(-0x1.5b86eap-1)));
393408}
394409
395410test "log10f() boundary" {
396 try expectEqual(log10f(0x1.fffffep+127), 0x1.344136p+5); // Max input value
397 try expectEqual(log10f(0x1p-149), -0x1.66d3e8p+5); // Min positive input value
398 try expect(math.isNan(log10f(-0x1p-149))); // Min negative input value
399 try expectEqual(log10f(0x1.000002p+0), 0x1.bcb7b0p-25); // Last value before result reaches +0
400 try expectEqual(log10f(0x1.fffffep-1), -0x1.bcb7b2p-26); // Last value before result reaches -0
401 try expectEqual(log10f(0x1p-126), -0x1.2f7030p+5); // First subnormal
402 try expect(math.isNan(log10f(-0x1p-126))); // First negative subnormal
411 try expectEqual(log10_f32(0x1.fffffep+127), 0x1.344136p+5); // Max input value
412 try expectEqual(log10_f32(0x1p-149), -0x1.66d3e8p+5); // Min positive input value
413 try expect(math.isNan(log10_f32(-0x1p-149))); // Min negative input value
414 try expectEqual(log10_f32(0x1.000002p+0), 0x1.bcb7b0p-25); // Last value before result reaches +0
415 try expectEqual(log10_f32(0x1.fffffep-1), -0x1.bcb7b2p-26); // Last value before result reaches -0
416 try expectEqual(log10_f32(0x1p-126), -0x1.2f7030p+5); // First subnormal
417 try expect(math.isNan(log10_f32(-0x1p-126))); // First negative subnormal
403418}
404419
405420test "log10() special" {
406 try expectEqual(log10(0.0), -math.inf(f64));
407 try expectEqual(log10(-0.0), -math.inf(f64));
408 try expect(math.isPositiveZero(log10(1.0)));
409 try expectEqual(log10(10.0), 1.0);
410 try expectEqual(log10(0.1), -1.0);
411 try expectEqual(log10(math.inf(f64)), math.inf(f64));
412 try expect(math.isNan(log10(-1.0)));
413 try expect(math.isNan(log10(-math.inf(f64))));
414 try expect(math.isNan(log10(math.nan(f64))));
415 try expect(math.isNan(log10(math.snan(f64))));
421 try expectEqual(log10_f64(0.0), -math.inf(f64));
422 try expectEqual(log10_f64(-0.0), -math.inf(f64));
423 try expect(math.isPositiveZero(log10_f64(1.0)));
424 try expectEqual(log10_f64(10.0), 1.0);
425 try expectEqual(log10_f64(0.1), -1.0);
426 try expectEqual(log10_f64(math.inf(f64)), math.inf(f64));
427 try expect(math.isNan(log10_f64(-1.0)));
428 try expect(math.isNan(log10_f64(-math.inf(f64))));
429 try expect(math.isNan(log10_f64(math.nan(f64))));
430 try expect(math.isNan(log10_f64(math.snan(f64))));
416431}
417432
418433test "log10() sanity" {
419 try expect(math.isNan(log10(-0x1.02239f3c6a8f1p+3)));
420 try expectEqual(log10(0x1.161868e18bc67p+2), 0x1.46a9bd1d2eb87p-1);
421 try expect(math.isNan(log10(-0x1.0c34b3e01e6e7p+3)));
422 try expect(math.isNan(log10(-0x1.a206f0a19dcc4p+2)));
423 try expectEqual(log10(0x1.288bbb0d6a1e6p+3), 0x1.ef12fff994862p-1);
424 try expectEqual(log10(0x1.52efd0cd80497p-1), -0x1.6ee6db5a155cbp-3);
425 try expect(math.isNan(log10(-0x1.a05cc754481d1p-2)));
426 try expectEqual(log10(0x1.1f9ef934745cbp-1), -0x1.0075cda79d321p-2);
427 try expectEqual(log10(0x1.8c5db097f7442p-1), -0x1.c75df6442465ap-4);
428 try expect(math.isNan(log10(-0x1.5b86ea8118a0ep-1)));
434 try expect(math.isNan(log10_f64(-0x1.02239f3c6a8f1p+3)));
435 try expectEqual(log10_f64(0x1.161868e18bc67p+2), 0x1.46a9bd1d2eb87p-1);
436 try expect(math.isNan(log10_f64(-0x1.0c34b3e01e6e7p+3)));
437 try expect(math.isNan(log10_f64(-0x1.a206f0a19dcc4p+2)));
438 try expectEqual(log10_f64(0x1.288bbb0d6a1e6p+3), 0x1.ef12fff994862p-1);
439 try expectEqual(log10_f64(0x1.52efd0cd80497p-1), -0x1.6ee6db5a155cbp-3);
440 try expect(math.isNan(log10_f64(-0x1.a05cc754481d1p-2)));
441 try expectEqual(log10_f64(0x1.1f9ef934745cbp-1), -0x1.0075cda79d321p-2);
442 try expectEqual(log10_f64(0x1.8c5db097f7442p-1), -0x1.c75df6442465ap-4);
443 try expect(math.isNan(log10_f64(-0x1.5b86ea8118a0ep-1)));
429444}
430445
431446test "log10() boundary" {
432 try expectEqual(log10(0x1.fffffffffffffp+1023), 0x1.34413509f79ffp+8); // Max input value
433 try expectEqual(log10(0x1p-1074), -0x1.434e6420f4374p+8); // Min positive input value
434 try expect(math.isNan(log10(-0x1p-1074))); // Min negative input value
435 try expectEqual(log10(0x1.0000000000001p+0), 0x1.bcb7b1526e50dp-54); // Last value before result reaches +0
436 try expectEqual(log10(0x1.fffffffffffffp-1), -0x1.bcb7b1526e50fp-55); // Last value before result reaches -0
437 try expectEqual(log10(0x1p-1022), -0x1.33a7146f72a42p+8); // First subnormal
438 try expect(math.isNan(log10(-0x1p-1022))); // First negative subnormal
447 try expectEqual(log10_f64(0x1.fffffffffffffp+1023), 0x1.34413509f79ffp+8); // Max input value
448 try expectEqual(log10_f64(0x1p-1074), -0x1.434e6420f4374p+8); // Min positive input value
449 try expect(math.isNan(log10_f64(-0x1p-1074))); // Min negative input value
450 try expectEqual(log10_f64(0x1.0000000000001p+0), 0x1.bcb7b1526e50dp-54); // Last value before result reaches +0
451 try expectEqual(log10_f64(0x1.fffffffffffffp-1), -0x1.bcb7b1526e50fp-55); // Last value before result reaches -0
452 try expectEqual(log10_f64(0x1p-1022), -0x1.33a7146f72a42p+8); // First subnormal
453 try expect(math.isNan(log10_f64(-0x1p-1022))); // First negative subnormal
439454}
440455
441456test "log10q() special" {
442 try expectEqual(log10q(0.0), -math.inf(f128));
443 try expectEqual(log10q(-0.0), -math.inf(f128));
444 try expect(math.isPositiveZero(log10q(1.0)));
445 try expectEqual(log10q(10.0), 1.0);
446 try expectEqual(log10q(0.1), -1.0);
447 try expectEqual(log10q(math.inf(f128)), math.inf(f128));
448 try expect(math.isNan(log10q(-1.0)));
449 try expect(math.isNan(log10q(-math.inf(f128))));
450 try expect(math.isNan(log10q(math.nan(f128))));
451 try expect(math.isNan(log10q(math.snan(f128))));
457 try expectEqual(log10_f128(0.0), -math.inf(f128));
458 try expectEqual(log10_f128(-0.0), -math.inf(f128));
459 try expect(math.isPositiveZero(log10_f128(1.0)));
460 try expectEqual(log10_f128(10.0), 1.0);
461 try expectEqual(log10_f128(0.1), -1.0);
462 try expectEqual(log10_f128(math.inf(f128)), math.inf(f128));
463 try expect(math.isNan(log10_f128(-1.0)));
464 try expect(math.isNan(log10_f128(-math.inf(f128))));
465 try expect(math.isNan(log10_f128(math.nan(f128))));
466 try expect(math.isNan(log10_f128(math.snan(f128))));
452467}
453468
454469test "log10q() sanity" {
455 try expectEqual(log10q(2.1744503117482705706605762784484114e1949), 1.949337349488073972035715318447419e3);
456 try expectEqual(log10q(2.3695331993665660983204066767386505e2150), 2.1503746627979481420243846411400265e3);
457 try expectEqual(log10q(1.8071775728314983136779370752110857e612), 6.122570008283284411311428111991705e2);
458 try expectEqual(log10q(2.612170297226630737309271722008693e-2629), -2.628582998513179919647069989114319e3);
459 try expectEqual(log10q(8.485091636263895897993044621224502e-3748), -3.7470713434630800881474518447042895e3);
460 try expectEqual(log10q(4.3668077579803801413736022136116655e-4051), -4.0503598359268068567757367259544416e3);
461 try expectEqual(log10q(2.9321353260885285826237030859036923e4830), 4.830467184010313310864606285356782e3);
462 try expectEqual(log10q(6.6119754254652455408442826553161645e-1417), -1.416179668769227128601620567685071e3);
463 try expectEqual(log10q(5.2459104673488555418645321788108695e4178), 4.178719820874155944446586083585479e3);
464 try expectEqual(log10q(7.809812890804996586377267218360886e-418), -4.1710735937091966815220294599598215e2);
470 try expectEqual(log10_f128(2.1744503117482705706605762784484114e1949), 1.949337349488073972035715318447419e3);
471 try expectEqual(log10_f128(2.3695331993665660983204066767386505e2150), 2.1503746627979481420243846411400265e3);
472 try expectEqual(log10_f128(1.8071775728314983136779370752110857e612), 6.122570008283284411311428111991705e2);
473 try expectEqual(log10_f128(2.612170297226630737309271722008693e-2629), -2.628582998513179919647069989114319e3);
474 try expectEqual(log10_f128(8.485091636263895897993044621224502e-3748), -3.7470713434630800881474518447042895e3);
475 try expectEqual(log10_f128(4.3668077579803801413736022136116655e-4051), -4.0503598359268068567757367259544416e3);
476 try expectEqual(log10_f128(2.9321353260885285826237030859036923e4830), 4.830467184010313310864606285356782e3);
477 try expectEqual(log10_f128(6.6119754254652455408442826553161645e-1417), -1.416179668769227128601620567685071e3);
478 try expectEqual(log10_f128(5.2459104673488555418645321788108695e4178), 4.178719820874155944446586083585479e3);
479 try expectEqual(log10_f128(7.809812890804996586377267218360886e-418), -4.1710735937091966815220294599598215e2);
465480 // testing near 1
466 try expectEqual(log10q(1.0291437165967803055610652052109798e0), 1.2476026819466393459130418401605807e-2);
467 try expectEqual(log10q(1.043095786320424537962914257605007e0), 1.8324191034706598279642145362763252e-2);
468 try expectEqual(log10q(9.900264873754467234601150948947179e-1), -4.3531860417287584780652055666513634e-3);
469 try expectEqual(log10q(1.038295346547007736348611217636062e0), 1.6320907588397540309035279023485962e-2);
470 try expectEqual(log10q(9.821701941230028324703038578036285e-1), -7.813249520562034832371814409278784e-3);
471 try expectEqual(log10q(9.593555263530179895381522214847791e-1), -1.8020418356217558657107271163588764e-2);
481 try expectEqual(log10_f128(1.0291437165967803055610652052109798e0), 1.2476026819466393459130418401605807e-2);
482 try expectEqual(log10_f128(1.043095786320424537962914257605007e0), 1.8324191034706598279642145362763252e-2);
483 try expectEqual(log10_f128(9.900264873754467234601150948947179e-1), -4.3531860417287584780652055666513634e-3);
484 try expectEqual(log10_f128(1.038295346547007736348611217636062e0), 1.6320907588397540309035279023485962e-2);
485 try expectEqual(log10_f128(9.821701941230028324703038578036285e-1), -7.813249520562034832371814409278784e-3);
486 try expectEqual(log10_f128(9.593555263530179895381522214847791e-1), -1.8020418356217558657107271163588764e-2);
472487}
473488
474489test "log10q() boundary" {
475 try expectEqual(log10q(0x1.ffffffffffffffffffffffffffffp16383), 0x1.34413509f79fef311f12b35816f9p12); // Max input value
476 try expectEqual(log10q(0x1p-16494), -0x1.3653051d20c18a143b801b7c5661p12); // Min positive input value
477 try expect(math.isNan(log10q(-0x1p-16494))); // Min negative input value
478 try expectEqual(log10q(0x1.0000000000000000000000000001p0), 0x1.bcb7b1526e50e32a6ab7555f5a67p-114); // Last value before result reaches +0
479 try expectEqual(log10q(0x1.ffffffffffffffffffffffffffffp-1), -0x1.bcb7b1526e50e32a6ab7555f5a68p-115); // Last value before result reaches -0
480 try expectEqual(log10q(0x1p-16382), -0x1.343793004f503231a589bac27c38p12); // First subnormal
481 try expect(math.isNan(log10q(-0x1p-16382))); // First negative subnormal
490 try expectEqual(log10_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1.34413509f79fef311f12b35816f9p12); // Max input value
491 try expectEqual(log10_f128(0x1p-16494), -0x1.3653051d20c18a143b801b7c5661p12); // Min positive input value
492 try expect(math.isNan(log10_f128(-0x1p-16494))); // Min negative input value
493 try expectEqual(log10_f128(0x1.0000000000000000000000000001p0), 0x1.bcb7b1526e50e32a6ab7555f5a67p-114); // Last value before result reaches +0
494 try expectEqual(log10_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1.bcb7b1526e50e32a6ab7555f5a68p-115); // Last value before result reaches -0
495 try expectEqual(log10_f128(0x1p-16382), -0x1.343793004f503231a589bac27c38p12); // First subnormal
496 try expect(math.isNan(log10_f128(-0x1p-16382))); // First negative subnormal
482497}
lib/compiler_rt/log2.zig+105-90
......@@ -26,12 +26,18 @@ comptime {
2626 symbol(&log2l, "log2l");
2727}
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 {
3033 // TODO: more efficient implementation
31 return @floatCast(log2f(a));
34 return @floatCast(log2_f32(a));
3235}
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 {
3541 const ivln2hi: f32 = 1.4428710938e+00;
3642 const ivln2lo: f32 = -1.7605285393e-04;
3743 const Lg1: f32 = 0xaaaaaa.0p-24;
......@@ -87,7 +93,10 @@ pub fn log2f(x_: f32) callconv(.c) f32 {
8793 return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + @as(f32, @floatFromInt(k));
8894}
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 {
91100 const ivln2hi: f64 = 1.44269504072144627571e+00;
92101 const ivln2lo: f64 = 1.67517131648865118353e-10;
93102 const Lg1: f64 = 6.666666666666735130e-01;
......@@ -158,11 +167,17 @@ pub fn log2(x_: f64) callconv(.c) f64 {
158167 return val_lo + val_hi;
159168}
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 {
162174 // TODO: more efficient implementation
163 return @floatCast(log2q(a));
175 return @floatCast(log2_f128(a));
164176}
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}
166181/// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic"
167182/// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990
168183///
......@@ -175,7 +190,7 @@ pub fn __log2x(a: f80) callconv(.c) f80 {
175190///
176191/// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case):
177192/// <= 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 {
179194 const impl = @import("log_f128.zig");
180195
181196 if (impl.specialCases(x)) |y|
......@@ -351,117 +366,117 @@ pub fn log2q(x: f128) callconv(.c) f128 {
351366
352367pub fn log2l(x: c_longdouble) callconv(.c) c_longdouble {
353368 switch (@typeInfo(c_longdouble).float.bits) {
354 64 => return log2(x),
355 80 => return __log2x(x),
356 128 => return log2q(x),
357 else => @compileError("unreachable"),
369 64 => return log2_f64(x),
370 80 => return log2_f80(x),
371 128 => return log2_f128(x),
372 else => comptime unreachable,
358373 }
359374}
360375
361376test "log2f() special" {
362 try expectEqual(log2f(0.0), -math.inf(f32));
363 try expectEqual(log2f(-0.0), -math.inf(f32));
364 try expect(math.isPositiveZero(log2f(1.0)));
365 try expectEqual(log2f(2.0), 1.0);
366 try expectEqual(log2f(math.inf(f32)), math.inf(f32));
367 try expect(math.isNan(log2f(-1.0)));
368 try expect(math.isNan(log2f(-math.inf(f32))));
369 try expect(math.isNan(log2f(math.nan(f32))));
370 try expect(math.isNan(log2f(math.snan(f32))));
377 try expectEqual(log2_f32(0.0), -math.inf(f32));
378 try expectEqual(log2_f32(-0.0), -math.inf(f32));
379 try expect(math.isPositiveZero(log2_f32(1.0)));
380 try expectEqual(log2_f32(2.0), 1.0);
381 try expectEqual(log2_f32(math.inf(f32)), math.inf(f32));
382 try expect(math.isNan(log2_f32(-1.0)));
383 try expect(math.isNan(log2_f32(-math.inf(f32))));
384 try expect(math.isNan(log2_f32(math.nan(f32))));
385 try expect(math.isNan(log2_f32(math.snan(f32))));
371386}
372387
373388test "log2f() sanity" {
374 try expect(math.isNan(log2f(-0x1.0223a0p+3)));
375 try expectEqual(log2f(0x1.161868p+2), 0x1.0f49acp+1);
376 try expect(math.isNan(log2f(-0x1.0c34b4p+3)));
377 try expect(math.isNan(log2f(-0x1.a206f0p+2)));
378 try expectEqual(log2f(0x1.288bbcp+3), 0x1.9b2676p+1);
379 try expectEqual(log2f(0x1.52efd0p-1), -0x1.30b494p-1); // Disagrees with GCC in last bit
380 try expect(math.isNan(log2f(-0x1.a05cc8p-2)));
381 try expectEqual(log2f(0x1.1f9efap-1), -0x1.a9f89ap-1);
382 try expectEqual(log2f(0x1.8c5db0p-1), -0x1.7a2c96p-2);
383 try expect(math.isNan(log2f(-0x1.5b86eap-1)));
389 try expect(math.isNan(log2_f32(-0x1.0223a0p+3)));
390 try expectEqual(log2_f32(0x1.161868p+2), 0x1.0f49acp+1);
391 try expect(math.isNan(log2_f32(-0x1.0c34b4p+3)));
392 try expect(math.isNan(log2_f32(-0x1.a206f0p+2)));
393 try expectEqual(log2_f32(0x1.288bbcp+3), 0x1.9b2676p+1);
394 try expectEqual(log2_f32(0x1.52efd0p-1), -0x1.30b494p-1); // Disagrees with GCC in last bit
395 try expect(math.isNan(log2_f32(-0x1.a05cc8p-2)));
396 try expectEqual(log2_f32(0x1.1f9efap-1), -0x1.a9f89ap-1);
397 try expectEqual(log2_f32(0x1.8c5db0p-1), -0x1.7a2c96p-2);
398 try expect(math.isNan(log2_f32(-0x1.5b86eap-1)));
384399}
385400
386401test "log2f() boundary" {
387 try expectEqual(log2f(0x1.fffffep+127), 0x1p+7); // Max input value
388 try expectEqual(log2f(0x1p-149), -0x1.2ap+7); // Min positive input value
389 try expect(math.isNan(log2f(-0x1p-149))); // Min negative input value
390 try expectEqual(log2f(0x1.000002p+0), 0x1.715474p-23); // Last value before result reaches +0
391 try expectEqual(log2f(0x1.fffffep-1), -0x1.715478p-24); // Last value before result reaches -0
392 try expectEqual(log2f(0x1p-126), -0x1.f8p+6); // First subnormal
393 try expect(math.isNan(log2f(-0x1p-126))); // First negative subnormal
402 try expectEqual(log2_f32(0x1.fffffep+127), 0x1p+7); // Max input value
403 try expectEqual(log2_f32(0x1p-149), -0x1.2ap+7); // Min positive input value
404 try expect(math.isNan(log2_f32(-0x1p-149))); // Min negative input value
405 try expectEqual(log2_f32(0x1.000002p+0), 0x1.715474p-23); // Last value before result reaches +0
406 try expectEqual(log2_f32(0x1.fffffep-1), -0x1.715478p-24); // Last value before result reaches -0
407 try expectEqual(log2_f32(0x1p-126), -0x1.f8p+6); // First subnormal
408 try expect(math.isNan(log2_f32(-0x1p-126))); // First negative subnormal
394409
395410}
396411
397412test "log2() special" {
398 try expectEqual(log2(0.0), -math.inf(f64));
399 try expectEqual(log2(-0.0), -math.inf(f64));
400 try expect(math.isPositiveZero(log2(1.0)));
401 try expectEqual(log2(2.0), 1.0);
402 try expectEqual(log2(math.inf(f64)), math.inf(f64));
403 try expect(math.isNan(log2(-1.0)));
404 try expect(math.isNan(log2(-math.inf(f64))));
405 try expect(math.isNan(log2(math.nan(f64))));
406 try expect(math.isNan(log2(math.snan(f64))));
413 try expectEqual(log2_f64(0.0), -math.inf(f64));
414 try expectEqual(log2_f64(-0.0), -math.inf(f64));
415 try expect(math.isPositiveZero(log2_f64(1.0)));
416 try expectEqual(log2_f64(2.0), 1.0);
417 try expectEqual(log2_f64(math.inf(f64)), math.inf(f64));
418 try expect(math.isNan(log2_f64(-1.0)));
419 try expect(math.isNan(log2_f64(-math.inf(f64))));
420 try expect(math.isNan(log2_f64(math.nan(f64))));
421 try expect(math.isNan(log2_f64(math.snan(f64))));
407422}
408423
409424test "log2() sanity" {
410 try expect(math.isNan(log2(-0x1.02239f3c6a8f1p+3)));
411 try expectEqual(log2(0x1.161868e18bc67p+2), 0x1.0f49ac3838580p+1);
412 try expect(math.isNan(log2(-0x1.0c34b3e01e6e7p+3)));
413 try expect(math.isNan(log2(-0x1.a206f0a19dcc4p+2)));
414 try expectEqual(log2(0x1.288bbb0d6a1e6p+3), 0x1.9b26760c2a57ep+1);
415 try expectEqual(log2(0x1.52efd0cd80497p-1), -0x1.30b490ef684c7p-1);
416 try expect(math.isNan(log2(-0x1.a05cc754481d1p-2)));
417 try expectEqual(log2(0x1.1f9ef934745cbp-1), -0x1.a9f89b5f5acb8p-1);
418 try expectEqual(log2(0x1.8c5db097f7442p-1), -0x1.7a2c947173f06p-2);
419 try expect(math.isNan(log2(-0x1.5b86ea8118a0ep-1)));
425 try expect(math.isNan(log2_f64(-0x1.02239f3c6a8f1p+3)));
426 try expectEqual(log2_f64(0x1.161868e18bc67p+2), 0x1.0f49ac3838580p+1);
427 try expect(math.isNan(log2_f64(-0x1.0c34b3e01e6e7p+3)));
428 try expect(math.isNan(log2_f64(-0x1.a206f0a19dcc4p+2)));
429 try expectEqual(log2_f64(0x1.288bbb0d6a1e6p+3), 0x1.9b26760c2a57ep+1);
430 try expectEqual(log2_f64(0x1.52efd0cd80497p-1), -0x1.30b490ef684c7p-1);
431 try expect(math.isNan(log2_f64(-0x1.a05cc754481d1p-2)));
432 try expectEqual(log2_f64(0x1.1f9ef934745cbp-1), -0x1.a9f89b5f5acb8p-1);
433 try expectEqual(log2_f64(0x1.8c5db097f7442p-1), -0x1.7a2c947173f06p-2);
434 try expect(math.isNan(log2_f64(-0x1.5b86ea8118a0ep-1)));
420435}
421436
422437test "log2() boundary" {
423 try expectEqual(log2(0x1.fffffffffffffp+1023), 0x1p+10); // Max input value
424 try expectEqual(log2(0x1p-1074), -0x1.0c8p+10); // Min positive input value
425 try expect(math.isNan(log2(-0x1p-1074))); // Min negative input value
426 try expectEqual(log2(0x1.0000000000001p+0), 0x1.71547652b82fdp-52); // Last value before result reaches +0
427 try expectEqual(log2(0x1.fffffffffffffp-1), -0x1.71547652b82fep-53); // Last value before result reaches -0
428 try expectEqual(log2(0x1p-1022), -0x1.ffp+9); // First subnormal
429 try expect(math.isNan(log2(-0x1p-1022))); // First negative subnormal
438 try expectEqual(log2_f64(0x1.fffffffffffffp+1023), 0x1p+10); // Max input value
439 try expectEqual(log2_f64(0x1p-1074), -0x1.0c8p+10); // Min positive input value
440 try expect(math.isNan(log2_f64(-0x1p-1074))); // Min negative input value
441 try expectEqual(log2_f64(0x1.0000000000001p+0), 0x1.71547652b82fdp-52); // Last value before result reaches +0
442 try expectEqual(log2_f64(0x1.fffffffffffffp-1), -0x1.71547652b82fep-53); // Last value before result reaches -0
443 try expectEqual(log2_f64(0x1p-1022), -0x1.ffp+9); // First subnormal
444 try expect(math.isNan(log2_f64(-0x1p-1022))); // First negative subnormal
430445}
431446
432447test "log2q() special" {
433 try expectEqual(log2q(0.0), -math.inf(f128));
434 try expectEqual(log2q(-0.0), -math.inf(f128));
435 try expect(math.isPositiveZero(log2q(1.0)));
436 try expectEqual(log2q(2.0), 1.0);
437 try expectEqual(log2q(math.inf(f128)), math.inf(f128));
438 try expect(math.isNan(log2q(-1.0)));
439 try expect(math.isNan(log2q(-math.inf(f128))));
440 try expect(math.isNan(log2q(math.nan(f128))));
441 try expect(math.isNan(log2q(math.snan(f128))));
448 try expectEqual(log2_f128(0.0), -math.inf(f128));
449 try expectEqual(log2_f128(-0.0), -math.inf(f128));
450 try expect(math.isPositiveZero(log2_f128(1.0)));
451 try expectEqual(log2_f128(2.0), 1.0);
452 try expectEqual(log2_f128(math.inf(f128)), math.inf(f128));
453 try expect(math.isNan(log2_f128(-1.0)));
454 try expect(math.isNan(log2_f128(-math.inf(f128))));
455 try expect(math.isNan(log2_f128(math.nan(f128))));
456 try expect(math.isNan(log2_f128(math.snan(f128))));
442457}
443458
444459test "log2q() boundary" {
445 try expectEqual(log2q(0x1.ffffffffffffffffffffffffffffp16383), 0x1p14); // Max input value
446 try expectEqual(log2q(0x1p-16494), -0x1.01b8p14); // Min positive input value
447 try expect(math.isNan(log2q(-0x1p-16494))); // Min negative input value
448 try expectEqual(log2q(0x1.0000000000000000000000000001p0), 0x1.71547652b82fe1777d0ffda0d23ap-112); // Last value before result reaches +0
449 try expectEqual(log2q(0x1.ffffffffffffffffffffffffffffp-1), -0x1.71547652b82fe1777d0ffda0d23bp-113); // Last value before result reaches -0
450 try expectEqual(log2q(0x1p-16382), -0x1.fffp13); // First subnormal
451 try expect(math.isNan(log2q(-0x1p-16382))); // First negative subnormal
460 try expectEqual(log2_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1p14); // Max input value
461 try expectEqual(log2_f128(0x1p-16494), -0x1.01b8p14); // Min positive input value
462 try expect(math.isNan(log2_f128(-0x1p-16494))); // Min negative input value
463 try expectEqual(log2_f128(0x1.0000000000000000000000000001p0), 0x1.71547652b82fe1777d0ffda0d23ap-112); // Last value before result reaches +0
464 try expectEqual(log2_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1.71547652b82fe1777d0ffda0d23bp-113); // Last value before result reaches -0
465 try expectEqual(log2_f128(0x1p-16382), -0x1.fffp13); // First subnormal
466 try expect(math.isNan(log2_f128(-0x1p-16382))); // First negative subnormal
452467}
453468
454469test "log2q() sanity" {
455 try expectEqual(log2q(8.0965013884643408203125e11), 3.955850767769801288865582596068254e1);
456 try expectEqual(log2q(8.346531942223744e15), 5.28900982928636641107356163006646e1);
457 try expectEqual(log2q(9.707809913413123613777865431464565e-20), -6.315941603809020445822192336703809e1);
458 try expectEqual(log2q(1.9179565888043380306021427656243352e-24), -7.878670421065570557450089031998522e1);
459 try expectEqual(log2q(2.5260048200126556877075044745936796e-25), -8.17113449801679676275805009400338e1);
460 try expectEqual(log2q(3.1170134002568967640399932861328125e7), 2.489366102143423848582774267206741e1);
470 try expectEqual(log2_f128(8.0965013884643408203125e11), 3.955850767769801288865582596068254e1);
471 try expectEqual(log2_f128(8.346531942223744e15), 5.28900982928636641107356163006646e1);
472 try expectEqual(log2_f128(9.707809913413123613777865431464565e-20), -6.315941603809020445822192336703809e1);
473 try expectEqual(log2_f128(1.9179565888043380306021427656243352e-24), -7.878670421065570557450089031998522e1);
474 try expectEqual(log2_f128(2.5260048200126556877075044745936796e-25), -8.17113449801679676275805009400338e1);
475 try expectEqual(log2_f128(3.1170134002568967640399932861328125e7), 2.489366102143423848582774267206741e1);
461476 // test near 1
462 try expectEqual(log2q(1.026586845186097528392910049888087e0), 3.7855678902522753591699367969189364e-2);
463 try expectEqual(log2q(1.0005582850578053877743656130405725e0), 8.052103367568488432896147152682078e-4);
464 try expectEqual(log2q(1.0370174103591254835765589348284266e0), 5.244011558596899945639244281954306e-2);
465 try expectEqual(log2q(1.0429996503525671713075162472250667e0), 6.073867421942172944687194557176633e-2);
466 try expectEqual(log2q(1.0383384027961064621892184334228659e0), 5.4276706191956281784022630732940314e-2);
477 try expectEqual(log2_f128(1.026586845186097528392910049888087e0), 3.7855678902522753591699367969189364e-2);
478 try expectEqual(log2_f128(1.0005582850578053877743656130405725e0), 8.052103367568488432896147152682078e-4);
479 try expectEqual(log2_f128(1.0370174103591254835765589348284266e0), 5.244011558596899945639244281954306e-2);
480 try expectEqual(log2_f128(1.0429996503525671713075162472250667e0), 6.073867421942172944687194557176633e-2);
481 try expectEqual(log2_f128(1.0383384027961064621892184334228659e0), 5.4276706191956281784022630732940314e-2);
467482}
lib/compiler_rt/mulc3.zig+75-10
......@@ -3,19 +3,80 @@ const isNan = std.math.isNan;
33const isInf = std.math.isInf;
44const copysign = std.math.copysign;
55
6pub fn Complex(comptime T: type) type {
7 return extern struct {
8 real: T,
9 imag: T,
10 };
6const compiler_rt = @import("../compiler_rt.zig");
7const symbol = compiler_rt.symbol;
8const Complex = compiler_rt.Complex;
9
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);
1172}
1273
1374/// 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) {
15 var a = a_in;
16 var b = b_in;
17 var c = c_in;
18 var d = d_in;
75inline fn mulc3(comptime T: type, lhs: Complex(T), rhs: Complex(T)) Complex(T) {
76 var a = lhs.real;
77 var b = lhs.imag;
78 var c = rhs.real;
79 var d = rhs.imag;
1980
2081 const ac = a * c;
2182 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
77138 }
78139 return z;
79140}
141
142test {
143 _ = @import("mulc3_test.zig");
144}
lib/compiler_rt/mulc3_test.zig+23-42
......@@ -2,64 +2,45 @@ const std = @import("std");
22const math = std.math;
33const expect = std.testing.expect;
44
5const Complex = @import("./mulc3.zig").Complex;
6const __mulhc3 = @import("./mulhc3.zig").__mulhc3;
7const __mulsc3 = @import("./mulsc3.zig").__mulsc3;
8const __muldc3 = @import("./muldc3.zig").__muldc3;
9const __mulxc3 = @import("./mulxc3.zig").__mulxc3;
10const __multc3 = @import("./multc3.zig").__multc3;
5const Complex = @import("../compiler_rt.zig").Complex;
6const impl = @import("mulc3.zig");
7const mul_cf16 = impl.mul_cf16;
8const mul_cf32 = impl.mul_cf32;
9const mul_cf64 = impl.mul_cf64;
10const mul_cf80 = impl.mul_cf80;
11const mul_cf128 = impl.mul_cf128;
1112
1213test "mulc3" {
13 try testMul(f16, __mulhc3);
14 try testMul(f32, __mulsc3);
15 try testMul(f64, __muldc3);
16 try testMul(f80, __mulxc3);
17 try testMul(f128, __multc3);
14 try testMul(f16, mul_cf16);
15 try testMul(f32, mul_cf32);
16 try testMul(f64, mul_cf64);
17 try testMul(f80, mul_cf80);
18 try testMul(f128, mul_cf128);
1819}
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 {
2122 {
22 const a: T = 1.0;
23 const b: T = 0.0;
24 const c: T = -1.0;
25 const d: T = 0.0;
26
27 const result = f(a, b, c, d);
23 const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -1.0, .imag = 0.0 });
2824 try expect(result.real == -1.0);
29 try expect(result.imag == 0.0);
25 try expect(math.isPositiveZero(result.imag));
3026 }
3127 {
32 const a: T = 1.0;
33 const b: T = 0.0;
34 const c: T = -4.0;
35 const d: T = 0.0;
36
37 const result = f(a, b, c, d);
28 const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -4.0, .imag = 0.0 });
3829 try expect(result.real == -4.0);
39 try expect(result.imag == 0.0);
30 try expect(math.isPositiveZero(result.imag));
4031 }
4132 {
4233 // if one operand is an infinity and the other operand is a nonzero finite number or an infinity,
4334 // then the result of the * operator is an infinity;
44 const a: T = math.inf(T);
45 const b: T = -math.inf(T);
46 const c: T = 1.0;
47 const d: T = 0.0;
48
49 const result = f(a, b, c, d);
50 try expect(result.real == math.inf(T));
51 try expect(result.imag == -math.inf(T));
35 const result = f(.{ .real = math.inf(T), .imag = -math.inf(T) }, .{ .real = 1.0, .imag = 0.0 });
36 try expect(math.isPositiveInf(result.real));
37 try expect(math.isNegativeInf(result.imag));
5238 }
5339 {
5440 // if one operand is an infinity and the other operand is a nonzero finite number or an infinity,
5541 // then the result of the * operator is an infinity;
56 const a: T = math.inf(T);
57 const b: T = -1.0;
58 const c: T = 1.0;
59 const d: T = math.inf(T);
60
61 const result = f(a, b, c, d);
62 try expect(result.real == math.inf(T));
63 try expect(result.imag == math.inf(T));
42 const result = f(.{ .real = math.inf(T), .imag = -1.0 }, .{ .real = 1.0, .imag = math.inf(T) });
43 try expect(math.isPositiveInf(result.real));
44 try expect(math.isPositiveInf(result.imag));
6445 }
6546}
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");
22const math = std.math;
33const builtin = @import("builtin");
44const 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
672/// Ported from:
773/// 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 {
975 @setRuntimeSafety(compiler_rt.test_safety);
1076 const typeWidth = @typeInfo(T).float.bits;
1177 const significandBits = math.floatMantissaBits(T);
lib/compiler_rt/mulf3_test.zig+48-46
......@@ -7,10 +7,12 @@ const math = std.math;
77const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64);
88const inf128: f128 = @bitCast(@as(u128, 0x7fff000000000000) << 64);
99
10const __multf3 = @import("multf3.zig").__multf3;
11const __mulxf3 = @import("mulxf3.zig").__mulxf3;
12const __muldf3 = @import("muldf3.zig").__muldf3;
13const __mulsf3 = @import("mulsf3.zig").__mulsf3;
10const impl = @import("mulf3.zig");
11const mul_f16 = impl.mul_f16;
12const mul_f32 = impl.mul_f32;
13const mul_f64 = impl.mul_f64;
14const mul_f80 = impl.mul_f80;
15const mul_f128 = impl.mul_f128;
1416
1517// return true if equal
1618// use two 64-bit integers instead of one 128-bit integer
......@@ -34,8 +36,8 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {
3436 return false;
3537}
3638
37fn test__multf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {
38 const x = __multf3(a, b);
39fn test_mul_f128(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {
40 const x = mul_f128(a, b);
3941
4042 if (compareResultLD(x, expected_hi, expected_lo))
4143 return;
......@@ -49,68 +51,68 @@ fn makeNaN128(rand: u64) f128 {
4951}
5052test "multf3" {
5153 // 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
5456 // NaN * any = NaN
5557 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);
5759 // 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
6062 // any * any
61 try test__multf3(
63 try test_mul_f128(
6264 @as(f128, @bitCast(@as(u128, 0x40042eab345678439abcdefea5678234))),
6365 @as(f128, @bitCast(@as(u128, 0x3ffeedcb34a235253948765432134675))),
6466 0x400423e7f9e3c9fc,
6567 0xd906c2c2a85777c4,
6668 );
6769
68 try test__multf3(
70 try test_mul_f128(
6971 @as(f128, @bitCast(@as(u128, 0x3fcd353e45674d89abacc3a2ebf3ff50))),
7072 @as(f128, @bitCast(@as(u128, 0x3ff6ed8764648369535adf4be3214568))),
7173 0x3fc52a163c6223fc,
7274 0xc94c4bf0430768b4,
7375 );
7476
75 try test__multf3(
77 try test_mul_f128(
7678 0x1.234425696abcad34a35eeffefdcbap+456,
7779 0x451.ed98d76e5d46e5f24323dff21ffp+600,
7880 0x44293a91de5e0e94,
7981 0xe8ed17cc2cdf64ac,
8082 );
8183
82 try test__multf3(
84 try test_mul_f128(
8385 @as(f128, @bitCast(@as(u128, 0x3f154356473c82a9fabf2d22ace345df))),
8486 @as(f128, @bitCast(@as(u128, 0x3e38eda98765476743ab21da23d45679))),
8587 0x3d4f37c1a3137cae,
8688 0xfc6807048bc2836a,
8789 );
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
9193 // Denormal operands.
92 try test__multf3(
94 try test_mul_f128(
9395 0x0.0000000000000000000000000001p-16382,
9496 0x1p16383,
9597 0x3f90000000000000,
9698 0x0,
9799 );
98 try test__multf3(
100 try test_mul_f128(
99101 0x1p16383,
100102 0x0.0000000000000000000000000001p-16382,
101103 0x3f90000000000000,
102104 0x0,
103105 );
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);
106 try test__multf3(0x1.0000_0000_0000_0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0003);
107 try test__multf3(2.0, math.floatTrueMin(f128), 0x0000_0000_0000_0000, 0x0000_0000_0000_0002);
107 try test_mul_f128(0x1.0000_0000_0000_0000_0000_0000_0001p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0002);
108 try test_mul_f128(0x1.0000_0000_0000_0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0003);
109 try test_mul_f128(2.0, math.floatTrueMin(f128), 0x0000_0000_0000_0000, 0x0000_0000_0000_0002);
108110}
109111
110112const 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 {
113 const x = __mulxf3(a, b);
114fn test_mul_f80(a: f80, b: f80, expected: u80) !void {
115 const x = mul_f80(a, b);
114116 const rep: u80 = @bitCast(x);
115117
116118 if (rep == expected)
......@@ -124,47 +126,47 @@ fn test__mulxf3(a: f80, b: f80, expected: u80) !void {
124126
125127test "mulxf3" {
126128 // NaN * any = NaN
127 try test__mulxf3(qnan80, 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
128 try test__mulxf3(@as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
129 try test_mul_f80(qnan80, 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
130 try test_mul_f80(@as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
129131
130132 // any * NaN = NaN
131 try test__mulxf3(0x1.23456789abcdefp+5, qnan80, @as(u80, @bitCast(qnan80)));
132 try test__mulxf3(0x1.23456789abcdefp+5, @as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), @as(u80, @bitCast(qnan80)));
133 try test_mul_f80(0x1.23456789abcdefp+5, qnan80, @as(u80, @bitCast(qnan80)));
134 try test_mul_f80(0x1.23456789abcdefp+5, @as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), @as(u80, @bitCast(qnan80)));
133135
134136 // 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
137139 // 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
140142 // 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
143145 // 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
146148 // -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
149151 // 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
152154 // 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
155157 // any * any
156 try test__mulxf3(0x1.0p+0, 0x1.dcba987654321p+5, 0x4004_ee5d_4c3b_2a19_0800);
157 try test__mulxf3(0x1.0000_0000_0000_0004p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0003); // exact
158
159 try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.0p+5, 0x4004_8000_0000_0000_0001); // exact
160 try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.7ffep+5, 0x4004_BFFF_0000_0000_0001); // round down
161 try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0002); // round up to even
162 try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.8002p+5, 0x4004_C001_0000_0000_0002); // round up
163 try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.0p+6, 0x4005_8000_0000_0000_0001); // exact
164
165 try test__mulxf3(0x1.0000_0001p+0, 0x1.0000_0001p+0, 0x3FFF_8000_0001_0000_0000); // round down to even
166 try test__mulxf3(0x1.0000_0001p+0, 0x1.0000_0001_0002p+0, 0x3FFF_8000_0001_0001_0001); // round up
167 try test__mulxf3(0x0.8000_0000_0000_0000p-16382, 2.0, 0x0001_8000_0000_0000_0000); // denormal -> normal
168 try test__mulxf3(0x0.7fff_ffff_ffff_fffep-16382, 0x2.0000_0000_0000_0008p0, 0x0001_8000_0000_0000_0000); // denormal -> normal
169 try test__mulxf3(0x0.7fff_ffff_ffff_fffep-16382, 0x1.0000_0000_0000_0000p0, 0x0000_3FFF_FFFF_FFFF_FFFF); // denormal -> denormal
158 try test_mul_f80(0x1.0p+0, 0x1.dcba987654321p+5, 0x4004_ee5d_4c3b_2a19_0800);
159 try test_mul_f80(0x1.0000_0000_0000_0004p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0003); // exact
160
161 try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.0p+5, 0x4004_8000_0000_0000_0001); // exact
162 try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.7ffep+5, 0x4004_BFFF_0000_0000_0001); // round down
163 try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0002); // round up to even
164 try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.8002p+5, 0x4004_C001_0000_0000_0002); // round up
165 try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.0p+6, 0x4005_8000_0000_0000_0001); // exact
166
167 try test_mul_f80(0x1.0000_0001p+0, 0x1.0000_0001p+0, 0x3FFF_8000_0001_0000_0000); // round down to even
168 try test_mul_f80(0x1.0000_0001p+0, 0x1.0000_0001_0002p+0, 0x3FFF_8000_0001_0001_0001); // round up
169 try test_mul_f80(0x0.8000_0000_0000_0000p-16382, 2.0, 0x0001_8000_0000_0000_0000); // denormal -> normal
170 try test_mul_f80(0x0.7fff_ffff_ffff_fffep-16382, 0x2.0000_0000_0000_0008p0, 0x0001_8000_0000_0000_0000); // denormal -> normal
171 try test_mul_f80(0x0.7fff_ffff_ffff_fffep-16382, 0x1.0000_0000_0000_0000p0, 0x0000_3FFF_FFFF_FFFF_FFFF); // denormal -> denormal
170172}
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 @@
11const testing = @import("std").testing;
22
33const mulv = @import("mulo.zig");
4const symbol = @import("../compiler_rt.zig").symbol;
4const compiler_rt = @import("../compiler_rt.zig");
5const symbol = compiler_rt.symbol;
56
67comptime {
78 symbol(&__mulvsi3, "__mulvsi3");
......@@ -10,7 +11,7 @@ comptime {
1011pub fn __mulvsi3(a: i32, b: i32) callconv(.c) i32 {
1112 var overflow: c_int = 0;
1213 const sum = mulv.__mulosi4(a, b, &overflow);
13 if (overflow != 0) @panic("compiler-rt: integer overflow");
14 if (overflow != 0) @panic("integer overflow");
1415 return sum;
1516}
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 {
3333 };
3434 const N: UT = @bitSizeOf(ST);
3535 const min: ST = @as(ST, @bitCast((@as(UT, 1) << (N - 1))));
36 if (a == min)
37 @panic("compiler_rt negv: overflow");
36 if (a == min) @panic("integer overflow");
3837 return -a;
3938}
4039
lib/compiler_rt/os_version_check.zig-1
......@@ -3,7 +3,6 @@ const testing = std.testing;
33const builtin = @import("builtin");
44const compiler_rt = @import("../compiler_rt.zig");
55const symbol = compiler_rt.symbol;
6const panic = @import("../compiler_rt.zig").panic;
76
87const have_availability_version_check = builtin.os.tag.isDarwin() and
98 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 @@
11//! parity - if number of bits set is even => 0, else => 1
22//! - 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
56comptime {
67 symbol(&__paritysi2, "__paritysi2");
lib/compiler_rt/popcount.zig+2-1
......@@ -6,7 +6,8 @@
66//! TAOCP: Combinational Algorithms, Bitwise Tricks And Techniques,
77//! 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
1112comptime {
1213 symbol(&__popcountsi2, "__popcountsi2");
lib/compiler_rt/powiXf2.zig+28-11
......@@ -4,16 +4,18 @@
44//! error propagation and this method is optimized for performance, not accuracy.
55
66const compiler_rt = @import("../compiler_rt.zig");
7const symbol = @import("../compiler_rt.zig").symbol;
7const symbol = compiler_rt.symbol;
88
99comptime {
1010 symbol(&__powihf2, "__powihf2");
1111 symbol(&__powisf2, "__powisf2");
1212 symbol(&__powidf2, "__powidf2");
13 if (compiler_rt.want_ppc_abi)
14 symbol(&__powitf2, "__powikf2");
15 symbol(&__powitf2, "__powitf2");
1613 symbol(&__powixf2, "__powixf2");
14 if (compiler_rt.want_ppc_abi) {
15 symbol(&__powitf2, "__powikf2");
16 } else {
17 symbol(&__powitf2, "__powitf2");
18 }
1719}
1820
1921inline 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 {
3234 return if (is_recip) 1 / r else r;
3335}
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 {
3641 return powiXf2(f16, a, b);
3742}
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 {
4048 return powiXf2(f32, a, b);
4149}
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 {
4455 return powiXf2(f64, a, b);
4556}
4657
47pub fn __powitf2(a: f128, b: i32) callconv(.c) f128 {
48 return powiXf2(f128, a, b);
58fn __powixf2(a: compiler_rt.f80.Abi, b: i32) callconv(.c) compiler_rt.f80.Abi {
59 return compiler_rt.f80.toAbi(powi_f80(compiler_rt.f80.fromAbi(a), b));
4960}
50
51pub fn __powixf2(a: f80, b: i32) callconv(.c) f80 {
61pub fn powi_f80(a: f80, b: i32) f80 {
5262 return powiXf2(f80, a, b);
5363}
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
5572test {
5673 _ = @import("powiXf2_test.zig");
5774}
lib/compiler_rt/powiXf2_test.zig+531-525
......@@ -2,562 +2,568 @@
22// powisf2_test.c, powidf2_test.c, powitf2_test.c, powixf2_test.c
33// powihf2 adapted from powisf2 tests
44
5const powiXf2 = @import("powiXf2.zig");
65const std = @import("std");
7const builtin = @import("builtin");
86const testing = std.testing;
97const math = std.math;
108
11fn test__powihf2(a: f16, b: i32, expected: f16) !void {
12 const result = powiXf2.__powihf2(a, b);
9const impl = @import("powiXf2.zig");
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);
1319 try testing.expectEqual(expected, result);
1420}
1521
16fn test__powisf2(a: f32, b: i32, expected: f32) !void {
17 const result = powiXf2.__powisf2(a, b);
22fn test_powi_f32(a: f32, b: i32, expected: f32) !void {
23 const result = powi_f32(a, b);
1824 try testing.expectEqual(expected, result);
1925}
2026
21fn test__powidf2(a: f64, b: i32, expected: f64) !void {
22 const result = powiXf2.__powidf2(a, b);
27fn test_powi_f64(a: f64, b: i32, expected: f64) !void {
28 const result = powi_f64(a, b);
2329 try testing.expectEqual(expected, result);
2430}
2531
26fn test__powitf2(a: f128, b: i32, expected: f128) !void {
27 const result = powiXf2.__powitf2(a, b);
32fn test_powi_f80(a: f80, b: i32, expected: f80) !void {
33 const result = powi_f80(a, b);
2834 try testing.expectEqual(expected, result);
2935}
3036
31fn test__powixf2(a: f80, b: i32, expected: f80) !void {
32 const result = powiXf2.__powixf2(a, b);
37fn test_powi_f128(a: f128, b: i32, expected: f128) !void {
38 const result = powi_f128(a, b);
3339 try testing.expectEqual(expected, result);
3440}
3541
36test "powihf2" {
42test powi_f16 {
3743 const inf_f16 = math.inf(f16);
38 try test__powisf2(0, 0, 1);
39 try test__powihf2(1, 0, 1);
40 try test__powihf2(1.5, 0, 1);
41 try test__powihf2(2, 0, 1);
42 try test__powihf2(inf_f16, 0, 1);
43
44 try test__powihf2(-0.0, 0, 1);
45 try test__powihf2(-1, 0, 1);
46 try test__powihf2(-1.5, 0, 1);
47 try test__powihf2(-2, 0, 1);
48 try test__powihf2(-inf_f16, 0, 1);
49
50 try test__powihf2(0, 1, 0);
51 try test__powihf2(0, 2, 0);
52 try test__powihf2(0, 3, 0);
53 try test__powihf2(0, 4, 0);
54 try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
55 try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
56
57 try test__powihf2(-0.0, 1, -0.0);
58 try test__powihf2(-0.0, 2, 0);
59 try test__powihf2(-0.0, 3, -0.0);
60 try test__powihf2(-0.0, 4, 0);
61 try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
62 try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
63
64 try test__powihf2(1, 1, 1);
65 try test__powihf2(1, 2, 1);
66 try test__powihf2(1, 3, 1);
67 try test__powihf2(1, 4, 1);
68 try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
69 try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
70
71 try test__powihf2(inf_f16, 1, inf_f16);
72 try test__powihf2(inf_f16, 2, inf_f16);
73 try test__powihf2(inf_f16, 3, inf_f16);
74 try test__powihf2(inf_f16, 4, inf_f16);
75 try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16);
76 try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f16);
77
78 try test__powihf2(-inf_f16, 1, -inf_f16);
79 try test__powihf2(-inf_f16, 2, inf_f16);
80 try test__powihf2(-inf_f16, 3, -inf_f16);
81 try test__powihf2(-inf_f16, 4, inf_f16);
82 try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16);
83 try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f16);
44 try test_powi_f16(0, 0, 1);
45 try test_powi_f16(1, 0, 1);
46 try test_powi_f16(1.5, 0, 1);
47 try test_powi_f16(2, 0, 1);
48 try test_powi_f16(inf_f16, 0, 1);
49
50 try test_powi_f16(-0.0, 0, 1);
51 try test_powi_f16(-1, 0, 1);
52 try test_powi_f16(-1.5, 0, 1);
53 try test_powi_f16(-2, 0, 1);
54 try test_powi_f16(-inf_f16, 0, 1);
55
56 try test_powi_f16(0, 1, 0);
57 try test_powi_f16(0, 2, 0);
58 try test_powi_f16(0, 3, 0);
59 try test_powi_f16(0, 4, 0);
60 try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
61 try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
62
63 try test_powi_f16(-0.0, 1, -0.0);
64 try test_powi_f16(-0.0, 2, 0);
65 try test_powi_f16(-0.0, 3, -0.0);
66 try test_powi_f16(-0.0, 4, 0);
67 try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
68 try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
69
70 try test_powi_f16(1, 1, 1);
71 try test_powi_f16(1, 2, 1);
72 try test_powi_f16(1, 3, 1);
73 try test_powi_f16(1, 4, 1);
74 try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
75 try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
76
77 try test_powi_f16(inf_f16, 1, inf_f16);
78 try test_powi_f16(inf_f16, 2, inf_f16);
79 try test_powi_f16(inf_f16, 3, inf_f16);
80 try test_powi_f16(inf_f16, 4, inf_f16);
81 try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16);
82 try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f16);
83
84 try test_powi_f16(-inf_f16, 1, -inf_f16);
85 try test_powi_f16(-inf_f16, 2, inf_f16);
86 try test_powi_f16(-inf_f16, 3, -inf_f16);
87 try test_powi_f16(-inf_f16, 4, inf_f16);
88 try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16);
89 try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f16);
8490 //
85 try test__powihf2(0, -1, inf_f16);
86 try test__powihf2(0, -2, inf_f16);
87 try test__powihf2(0, -3, inf_f16);
88 try test__powihf2(0, -4, inf_f16);
89 try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // 0 ^ anything = +inf
90 try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f16);
91 try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16);
92
93 try test__powihf2(-0.0, -1, -inf_f16);
94 try test__powihf2(-0.0, -2, inf_f16);
95 try test__powihf2(-0.0, -3, -inf_f16);
96 try test__powihf2(-0.0, -4, inf_f16);
97 try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // -0 ^ anything even = +inf
98 try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f16); // -0 ^ anything odd = -inf
99 try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16);
100
101 try test__powihf2(1, -1, 1);
102 try test__powihf2(1, -2, 1);
103 try test__powihf2(1, -3, 1);
104 try test__powihf2(1, -4, 1);
105 try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); // 1.0 ^ anything = 1
106 try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
107 try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
108
109 try test__powihf2(inf_f16, -1, 0);
110 try test__powihf2(inf_f16, -2, 0);
111 try test__powihf2(inf_f16, -3, 0);
112 try test__powihf2(inf_f16, -4, 0);
113 try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
114 try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
115 try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
91 try test_powi_f16(0, -1, inf_f16);
92 try test_powi_f16(0, -2, inf_f16);
93 try test_powi_f16(0, -3, inf_f16);
94 try test_powi_f16(0, -4, inf_f16);
95 try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // 0 ^ anything = +inf
96 try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f16);
97 try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16);
98
99 try test_powi_f16(-0.0, -1, -inf_f16);
100 try test_powi_f16(-0.0, -2, inf_f16);
101 try test_powi_f16(-0.0, -3, -inf_f16);
102 try test_powi_f16(-0.0, -4, inf_f16);
103 try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // -0 ^ anything even = +inf
104 try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f16); // -0 ^ anything odd = -inf
105 try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16);
106
107 try test_powi_f16(1, -1, 1);
108 try test_powi_f16(1, -2, 1);
109 try test_powi_f16(1, -3, 1);
110 try test_powi_f16(1, -4, 1);
111 try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); // 1.0 ^ anything = 1
112 try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
113 try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
114
115 try test_powi_f16(inf_f16, -1, 0);
116 try test_powi_f16(inf_f16, -2, 0);
117 try test_powi_f16(inf_f16, -3, 0);
118 try test_powi_f16(inf_f16, -4, 0);
119 try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
120 try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
121 try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
116122 //
117 try test__powihf2(-inf_f16, -1, -0.0);
118 try test__powihf2(-inf_f16, -2, 0);
119 try test__powihf2(-inf_f16, -3, -0.0);
120 try test__powihf2(-inf_f16, -4, 0);
121 try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
122 try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
123 try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
124
125 try test__powihf2(2, 10, 1024.0);
126 try test__powihf2(-2, 10, 1024.0);
127 try test__powihf2(2, -10, 1.0 / 1024.0);
128 try test__powihf2(-2, -10, 1.0 / 1024.0);
129
130 try test__powihf2(2, 14, 16384.0);
131 try test__powihf2(-2, 14, 16384.0);
132 try test__powihf2(2, 15, 32768.0);
133 try test__powihf2(-2, 15, -32768.0);
134 try test__powihf2(2, 16, inf_f16);
135 try test__powihf2(-2, 16, inf_f16);
136
137 try test__powihf2(2, -13, 1.0 / 8192.0);
138 try test__powihf2(-2, -13, -1.0 / 8192.0);
139 try test__powihf2(2, -15, 1.0 / 32768.0);
140 try test__powihf2(-2, -15, -1.0 / 32768.0);
141 try test__powihf2(2, -16, 0.0); // expected = 0.0 = 1/(-2**16)
142 try test__powihf2(-2, -16, 0.0); // expected = 0.0 = 1/(2**16)
123 try test_powi_f16(-inf_f16, -1, -0.0);
124 try test_powi_f16(-inf_f16, -2, 0);
125 try test_powi_f16(-inf_f16, -3, -0.0);
126 try test_powi_f16(-inf_f16, -4, 0);
127 try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
128 try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
129 try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
130
131 try test_powi_f16(2, 10, 1024.0);
132 try test_powi_f16(-2, 10, 1024.0);
133 try test_powi_f16(2, -10, 1.0 / 1024.0);
134 try test_powi_f16(-2, -10, 1.0 / 1024.0);
135
136 try test_powi_f16(2, 14, 16384.0);
137 try test_powi_f16(-2, 14, 16384.0);
138 try test_powi_f16(2, 15, 32768.0);
139 try test_powi_f16(-2, 15, -32768.0);
140 try test_powi_f16(2, 16, inf_f16);
141 try test_powi_f16(-2, 16, inf_f16);
142
143 try test_powi_f16(2, -13, 1.0 / 8192.0);
144 try test_powi_f16(-2, -13, -1.0 / 8192.0);
145 try test_powi_f16(2, -15, 1.0 / 32768.0);
146 try test_powi_f16(-2, -15, -1.0 / 32768.0);
147 try test_powi_f16(2, -16, 0.0); // expected = 0.0 = 1/(-2**16)
148 try test_powi_f16(-2, -16, 0.0); // expected = 0.0 = 1/(2**16)
143149}
144150
145test "powisf2" {
151test powi_f32 {
146152 const inf_f32 = math.inf(f32);
147 try test__powisf2(0, 0, 1);
148 try test__powisf2(1, 0, 1);
149 try test__powisf2(1.5, 0, 1);
150 try test__powisf2(2, 0, 1);
151 try test__powisf2(inf_f32, 0, 1);
152
153 try test__powisf2(-0.0, 0, 1);
154 try test__powisf2(-1, 0, 1);
155 try test__powisf2(-1.5, 0, 1);
156 try test__powisf2(-2, 0, 1);
157 try test__powisf2(-inf_f32, 0, 1);
158
159 try test__powisf2(0, 1, 0);
160 try test__powisf2(0, 2, 0);
161 try test__powisf2(0, 3, 0);
162 try test__powisf2(0, 4, 0);
163 try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
164 try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
165
166 try test__powisf2(-0.0, 1, -0.0);
167 try test__powisf2(-0.0, 2, 0);
168 try test__powisf2(-0.0, 3, -0.0);
169 try test__powisf2(-0.0, 4, 0);
170 try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
171 try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
172
173 try test__powisf2(1, 1, 1);
174 try test__powisf2(1, 2, 1);
175 try test__powisf2(1, 3, 1);
176 try test__powisf2(1, 4, 1);
177 try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
178 try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
179
180 try test__powisf2(inf_f32, 1, inf_f32);
181 try test__powisf2(inf_f32, 2, inf_f32);
182 try test__powisf2(inf_f32, 3, inf_f32);
183 try test__powisf2(inf_f32, 4, inf_f32);
184 try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32);
185 try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f32);
186
187 try test__powisf2(-inf_f32, 1, -inf_f32);
188 try test__powisf2(-inf_f32, 2, inf_f32);
189 try test__powisf2(-inf_f32, 3, -inf_f32);
190 try test__powisf2(-inf_f32, 4, inf_f32);
191 try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32);
192 try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f32);
193
194 try test__powisf2(0, -1, inf_f32);
195 try test__powisf2(0, -2, inf_f32);
196 try test__powisf2(0, -3, inf_f32);
197 try test__powisf2(0, -4, inf_f32);
198 try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32);
199 try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f32);
200 try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32);
201
202 try test__powisf2(-0.0, -1, -inf_f32);
203 try test__powisf2(-0.0, -2, inf_f32);
204 try test__powisf2(-0.0, -3, -inf_f32);
205 try test__powisf2(-0.0, -4, inf_f32);
206 try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32);
207 try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f32);
208 try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32);
209
210 try test__powisf2(1, -1, 1);
211 try test__powisf2(1, -2, 1);
212 try test__powisf2(1, -3, 1);
213 try test__powisf2(1, -4, 1);
214 try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
215 try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
216 try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
217
218 try test__powisf2(inf_f32, -1, 0);
219 try test__powisf2(inf_f32, -2, 0);
220 try test__powisf2(inf_f32, -3, 0);
221 try test__powisf2(inf_f32, -4, 0);
222 try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
223 try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
224 try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
225
226 try test__powisf2(-inf_f32, -1, -0.0);
227 try test__powisf2(-inf_f32, -2, 0);
228 try test__powisf2(-inf_f32, -3, -0.0);
229 try test__powisf2(-inf_f32, -4, 0);
230 try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
231 try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
232 try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
233
234 try test__powisf2(2.0, 10, 1024.0);
235 try test__powisf2(-2, 10, 1024.0);
236 try test__powisf2(2, -10, 1.0 / 1024.0);
237 try test__powisf2(-2, -10, 1.0 / 1024.0);
153 try test_powi_f32(0, 0, 1);
154 try test_powi_f32(1, 0, 1);
155 try test_powi_f32(1.5, 0, 1);
156 try test_powi_f32(2, 0, 1);
157 try test_powi_f32(inf_f32, 0, 1);
158
159 try test_powi_f32(-0.0, 0, 1);
160 try test_powi_f32(-1, 0, 1);
161 try test_powi_f32(-1.5, 0, 1);
162 try test_powi_f32(-2, 0, 1);
163 try test_powi_f32(-inf_f32, 0, 1);
164
165 try test_powi_f32(0, 1, 0);
166 try test_powi_f32(0, 2, 0);
167 try test_powi_f32(0, 3, 0);
168 try test_powi_f32(0, 4, 0);
169 try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
170 try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
171
172 try test_powi_f32(-0.0, 1, -0.0);
173 try test_powi_f32(-0.0, 2, 0);
174 try test_powi_f32(-0.0, 3, -0.0);
175 try test_powi_f32(-0.0, 4, 0);
176 try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
177 try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
178
179 try test_powi_f32(1, 1, 1);
180 try test_powi_f32(1, 2, 1);
181 try test_powi_f32(1, 3, 1);
182 try test_powi_f32(1, 4, 1);
183 try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
184 try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
185
186 try test_powi_f32(inf_f32, 1, inf_f32);
187 try test_powi_f32(inf_f32, 2, inf_f32);
188 try test_powi_f32(inf_f32, 3, inf_f32);
189 try test_powi_f32(inf_f32, 4, inf_f32);
190 try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32);
191 try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f32);
192
193 try test_powi_f32(-inf_f32, 1, -inf_f32);
194 try test_powi_f32(-inf_f32, 2, inf_f32);
195 try test_powi_f32(-inf_f32, 3, -inf_f32);
196 try test_powi_f32(-inf_f32, 4, inf_f32);
197 try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32);
198 try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f32);
199
200 try test_powi_f32(0, -1, inf_f32);
201 try test_powi_f32(0, -2, inf_f32);
202 try test_powi_f32(0, -3, inf_f32);
203 try test_powi_f32(0, -4, inf_f32);
204 try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32);
205 try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f32);
206 try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32);
207
208 try test_powi_f32(-0.0, -1, -inf_f32);
209 try test_powi_f32(-0.0, -2, inf_f32);
210 try test_powi_f32(-0.0, -3, -inf_f32);
211 try test_powi_f32(-0.0, -4, inf_f32);
212 try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32);
213 try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f32);
214 try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32);
215
216 try test_powi_f32(1, -1, 1);
217 try test_powi_f32(1, -2, 1);
218 try test_powi_f32(1, -3, 1);
219 try test_powi_f32(1, -4, 1);
220 try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
221 try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
222 try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
223
224 try test_powi_f32(inf_f32, -1, 0);
225 try test_powi_f32(inf_f32, -2, 0);
226 try test_powi_f32(inf_f32, -3, 0);
227 try test_powi_f32(inf_f32, -4, 0);
228 try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
229 try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
230 try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
231
232 try test_powi_f32(-inf_f32, -1, -0.0);
233 try test_powi_f32(-inf_f32, -2, 0);
234 try test_powi_f32(-inf_f32, -3, -0.0);
235 try test_powi_f32(-inf_f32, -4, 0);
236 try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
237 try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
238 try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
239
240 try test_powi_f32(2.0, 10, 1024.0);
241 try test_powi_f32(-2, 10, 1024.0);
242 try test_powi_f32(2, -10, 1.0 / 1024.0);
243 try test_powi_f32(-2, -10, 1.0 / 1024.0);
238244 //
239 try test__powisf2(2, 19, 524288.0);
240 try test__powisf2(-2, 19, -524288.0);
241 try test__powisf2(2, -19, 1.0 / 524288.0);
242 try test__powisf2(-2, -19, -1.0 / 524288.0);
243
244 try test__powisf2(2, 31, 2147483648.0);
245 try test__powisf2(-2, 31, -2147483648.0);
246 try test__powisf2(2, -31, 1.0 / 2147483648.0);
247 try test__powisf2(-2, -31, -1.0 / 2147483648.0);
245 try test_powi_f32(2, 19, 524288.0);
246 try test_powi_f32(-2, 19, -524288.0);
247 try test_powi_f32(2, -19, 1.0 / 524288.0);
248 try test_powi_f32(-2, -19, -1.0 / 524288.0);
249
250 try test_powi_f32(2, 31, 2147483648.0);
251 try test_powi_f32(-2, 31, -2147483648.0);
252 try test_powi_f32(2, -31, 1.0 / 2147483648.0);
253 try test_powi_f32(-2, -31, -1.0 / 2147483648.0);
248254}
249255
250test "powidf2" {
256test powi_f64 {
251257 const inf_f64 = math.inf(f64);
252 try test__powidf2(0, 0, 1);
253 try test__powidf2(1, 0, 1);
254 try test__powidf2(1.5, 0, 1);
255 try test__powidf2(2, 0, 1);
256 try test__powidf2(inf_f64, 0, 1);
257
258 try test__powidf2(-0.0, 0, 1);
259 try test__powidf2(-1, 0, 1);
260 try test__powidf2(-1.5, 0, 1);
261 try test__powidf2(-2, 0, 1);
262 try test__powidf2(-inf_f64, 0, 1);
263
264 try test__powidf2(0, 1, 0);
265 try test__powidf2(0, 2, 0);
266 try test__powidf2(0, 3, 0);
267 try test__powidf2(0, 4, 0);
268 try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
269 try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
270
271 try test__powidf2(-0.0, 1, -0.0);
272 try test__powidf2(-0.0, 2, 0);
273 try test__powidf2(-0.0, 3, -0.0);
274 try test__powidf2(-0.0, 4, 0);
275 try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
276 try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
277
278 try test__powidf2(1, 1, 1);
279 try test__powidf2(1, 2, 1);
280 try test__powidf2(1, 3, 1);
281 try test__powidf2(1, 4, 1);
282 try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
283 try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
284
285 try test__powidf2(inf_f64, 1, inf_f64);
286 try test__powidf2(inf_f64, 2, inf_f64);
287 try test__powidf2(inf_f64, 3, inf_f64);
288 try test__powidf2(inf_f64, 4, inf_f64);
289 try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64);
290 try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f64);
291
292 try test__powidf2(-inf_f64, 1, -inf_f64);
293 try test__powidf2(-inf_f64, 2, inf_f64);
294 try test__powidf2(-inf_f64, 3, -inf_f64);
295 try test__powidf2(-inf_f64, 4, inf_f64);
296 try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64);
297 try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f64);
298
299 try test__powidf2(0, -1, inf_f64);
300 try test__powidf2(0, -2, inf_f64);
301 try test__powidf2(0, -3, inf_f64);
302 try test__powidf2(0, -4, inf_f64);
303 try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64);
304 try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f64);
305 try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64);
306
307 try test__powidf2(-0.0, -1, -inf_f64);
308 try test__powidf2(-0.0, -2, inf_f64);
309 try test__powidf2(-0.0, -3, -inf_f64);
310 try test__powidf2(-0.0, -4, inf_f64);
311 try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64);
312 try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f64);
313 try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64);
314
315 try test__powidf2(1, -1, 1);
316 try test__powidf2(1, -2, 1);
317 try test__powidf2(1, -3, 1);
318 try test__powidf2(1, -4, 1);
319 try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
320 try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
321 try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
322
323 try test__powidf2(inf_f64, -1, 0);
324 try test__powidf2(inf_f64, -2, 0);
325 try test__powidf2(inf_f64, -3, 0);
326 try test__powidf2(inf_f64, -4, 0);
327 try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
328 try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
329 try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
330
331 try test__powidf2(-inf_f64, -1, -0.0);
332 try test__powidf2(-inf_f64, -2, 0);
333 try test__powidf2(-inf_f64, -3, -0.0);
334 try test__powidf2(-inf_f64, -4, 0);
335 try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
336 try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
337 try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
338
339 try test__powidf2(2, 10, 1024.0);
340 try test__powidf2(-2, 10, 1024.0);
341 try test__powidf2(2, -10, 1.0 / 1024.0);
342 try test__powidf2(-2, -10, 1.0 / 1024.0);
343
344 try test__powidf2(2, 19, 524288.0);
345 try test__powidf2(-2, 19, -524288.0);
346 try test__powidf2(2, -19, 1.0 / 524288.0);
347 try test__powidf2(-2, -19, -1.0 / 524288.0);
348
349 try test__powidf2(2, 31, 2147483648.0);
350 try test__powidf2(-2, 31, -2147483648.0);
351 try test__powidf2(2, -31, 1.0 / 2147483648.0);
352 try test__powidf2(-2, -31, -1.0 / 2147483648.0);
258 try test_powi_f64(0, 0, 1);
259 try test_powi_f64(1, 0, 1);
260 try test_powi_f64(1.5, 0, 1);
261 try test_powi_f64(2, 0, 1);
262 try test_powi_f64(inf_f64, 0, 1);
263
264 try test_powi_f64(-0.0, 0, 1);
265 try test_powi_f64(-1, 0, 1);
266 try test_powi_f64(-1.5, 0, 1);
267 try test_powi_f64(-2, 0, 1);
268 try test_powi_f64(-inf_f64, 0, 1);
269
270 try test_powi_f64(0, 1, 0);
271 try test_powi_f64(0, 2, 0);
272 try test_powi_f64(0, 3, 0);
273 try test_powi_f64(0, 4, 0);
274 try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
275 try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
276
277 try test_powi_f64(-0.0, 1, -0.0);
278 try test_powi_f64(-0.0, 2, 0);
279 try test_powi_f64(-0.0, 3, -0.0);
280 try test_powi_f64(-0.0, 4, 0);
281 try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
282 try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
283
284 try test_powi_f64(1, 1, 1);
285 try test_powi_f64(1, 2, 1);
286 try test_powi_f64(1, 3, 1);
287 try test_powi_f64(1, 4, 1);
288 try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
289 try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
290
291 try test_powi_f64(inf_f64, 1, inf_f64);
292 try test_powi_f64(inf_f64, 2, inf_f64);
293 try test_powi_f64(inf_f64, 3, inf_f64);
294 try test_powi_f64(inf_f64, 4, inf_f64);
295 try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64);
296 try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f64);
297
298 try test_powi_f64(-inf_f64, 1, -inf_f64);
299 try test_powi_f64(-inf_f64, 2, inf_f64);
300 try test_powi_f64(-inf_f64, 3, -inf_f64);
301 try test_powi_f64(-inf_f64, 4, inf_f64);
302 try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64);
303 try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f64);
304
305 try test_powi_f64(0, -1, inf_f64);
306 try test_powi_f64(0, -2, inf_f64);
307 try test_powi_f64(0, -3, inf_f64);
308 try test_powi_f64(0, -4, inf_f64);
309 try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64);
310 try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f64);
311 try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64);
312
313 try test_powi_f64(-0.0, -1, -inf_f64);
314 try test_powi_f64(-0.0, -2, inf_f64);
315 try test_powi_f64(-0.0, -3, -inf_f64);
316 try test_powi_f64(-0.0, -4, inf_f64);
317 try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64);
318 try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f64);
319 try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64);
320
321 try test_powi_f64(1, -1, 1);
322 try test_powi_f64(1, -2, 1);
323 try test_powi_f64(1, -3, 1);
324 try test_powi_f64(1, -4, 1);
325 try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
326 try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
327 try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
328
329 try test_powi_f64(inf_f64, -1, 0);
330 try test_powi_f64(inf_f64, -2, 0);
331 try test_powi_f64(inf_f64, -3, 0);
332 try test_powi_f64(inf_f64, -4, 0);
333 try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
334 try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
335 try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
336
337 try test_powi_f64(-inf_f64, -1, -0.0);
338 try test_powi_f64(-inf_f64, -2, 0);
339 try test_powi_f64(-inf_f64, -3, -0.0);
340 try test_powi_f64(-inf_f64, -4, 0);
341 try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
342 try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
343 try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
344
345 try test_powi_f64(2, 10, 1024.0);
346 try test_powi_f64(-2, 10, 1024.0);
347 try test_powi_f64(2, -10, 1.0 / 1024.0);
348 try test_powi_f64(-2, -10, 1.0 / 1024.0);
349
350 try test_powi_f64(2, 19, 524288.0);
351 try test_powi_f64(-2, 19, -524288.0);
352 try test_powi_f64(2, -19, 1.0 / 524288.0);
353 try test_powi_f64(-2, -19, -1.0 / 524288.0);
354
355 try test_powi_f64(2, 31, 2147483648.0);
356 try test_powi_f64(-2, 31, -2147483648.0);
357 try test_powi_f64(2, -31, 1.0 / 2147483648.0);
358 try test_powi_f64(-2, -31, -1.0 / 2147483648.0);
353359}
354360
355test "powitf2" {
356 const inf_f128 = math.inf(f128);
357 try test__powitf2(0, 0, 1);
358 try test__powitf2(1, 0, 1);
359 try test__powitf2(1.5, 0, 1);
360 try test__powitf2(2, 0, 1);
361 try test__powitf2(inf_f128, 0, 1);
362
363 try test__powitf2(-0.0, 0, 1);
364 try test__powitf2(-1, 0, 1);
365 try test__powitf2(-1.5, 0, 1);
366 try test__powitf2(-2, 0, 1);
367 try test__powitf2(-inf_f128, 0, 1);
368
369 try test__powitf2(0, 1, 0);
370 try test__powitf2(0, 2, 0);
371 try test__powitf2(0, 3, 0);
372 try test__powitf2(0, 4, 0);
373 try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
374 try test__powitf2(0, 0x7FFFFFFF, 0);
375
376 try test__powitf2(-0.0, 1, -0.0);
377 try test__powitf2(-0.0, 2, 0);
378 try test__powitf2(-0.0, 3, -0.0);
379 try test__powitf2(-0.0, 4, 0);
380 try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
381 try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
382
383 try test__powitf2(1, 1, 1);
384 try test__powitf2(1, 2, 1);
385 try test__powitf2(1, 3, 1);
386 try test__powitf2(1, 4, 1);
387 try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
388 try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
389
390 try test__powitf2(inf_f128, 1, inf_f128);
391 try test__powitf2(inf_f128, 2, inf_f128);
392 try test__powitf2(inf_f128, 3, inf_f128);
393 try test__powitf2(inf_f128, 4, inf_f128);
394 try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128);
395 try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f128);
396
397 try test__powitf2(-inf_f128, 1, -inf_f128);
398 try test__powitf2(-inf_f128, 2, inf_f128);
399 try test__powitf2(-inf_f128, 3, -inf_f128);
400 try test__powitf2(-inf_f128, 4, inf_f128);
401 try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128);
402 try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f128);
403
404 try test__powitf2(0, -1, inf_f128);
405 try test__powitf2(0, -2, inf_f128);
406 try test__powitf2(0, -3, inf_f128);
407 try test__powitf2(0, -4, inf_f128);
408 try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128);
409 try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f128);
410 try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128);
411
412 try test__powitf2(-0.0, -1, -inf_f128);
413 try test__powitf2(-0.0, -2, inf_f128);
414 try test__powitf2(-0.0, -3, -inf_f128);
415 try test__powitf2(-0.0, -4, inf_f128);
416 try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128);
417 try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f128);
418 try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128);
419
420 try test__powitf2(1, -1, 1);
421 try test__powitf2(1, -2, 1);
422 try test__powitf2(1, -3, 1);
423 try test__powitf2(1, -4, 1);
424 try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
425 try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
426 try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
427
428 try test__powitf2(inf_f128, -1, 0);
429 try test__powitf2(inf_f128, -2, 0);
430 try test__powitf2(inf_f128, -3, 0);
431 try test__powitf2(inf_f128, -4, 0);
432 try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
433 try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
434 try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
435
436 try test__powitf2(-inf_f128, -1, -0.0);
437 try test__powitf2(-inf_f128, -2, 0);
438 try test__powitf2(-inf_f128, -3, -0.0);
439 try test__powitf2(-inf_f128, -4, 0);
440 try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
441 try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
442 try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
443
444 try test__powitf2(2, 10, 1024.0);
445 try test__powitf2(-2, 10, 1024.0);
446 try test__powitf2(2, -10, 1.0 / 1024.0);
447 try test__powitf2(-2, -10, 1.0 / 1024.0);
448
449 try test__powitf2(2, 19, 524288.0);
450 try test__powitf2(-2, 19, -524288.0);
451 try test__powitf2(2, -19, 1.0 / 524288.0);
452 try test__powitf2(-2, -19, -1.0 / 524288.0);
453
454 try test__powitf2(2, 31, 2147483648.0);
455 try test__powitf2(-2, 31, -2147483648.0);
456 try test__powitf2(2, -31, 1.0 / 2147483648.0);
457 try test__powitf2(-2, -31, -1.0 / 2147483648.0);
361test powi_f80 {
362 const inf_f80 = math.inf(f80);
363 try test_powi_f80(0, 0, 1);
364 try test_powi_f80(1, 0, 1);
365 try test_powi_f80(1.5, 0, 1);
366 try test_powi_f80(2, 0, 1);
367 try test_powi_f80(inf_f80, 0, 1);
368
369 try test_powi_f80(-0.0, 0, 1);
370 try test_powi_f80(-1, 0, 1);
371 try test_powi_f80(-1.5, 0, 1);
372 try test_powi_f80(-2, 0, 1);
373 try test_powi_f80(-inf_f80, 0, 1);
374
375 try test_powi_f80(0, 1, 0);
376 try test_powi_f80(0, 2, 0);
377 try test_powi_f80(0, 3, 0);
378 try test_powi_f80(0, 4, 0);
379 try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
380 try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
381
382 try test_powi_f80(-0.0, 1, -0.0);
383 try test_powi_f80(-0.0, 2, 0);
384 try test_powi_f80(-0.0, 3, -0.0);
385 try test_powi_f80(-0.0, 4, 0);
386 try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
387 try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
388
389 try test_powi_f80(1, 1, 1);
390 try test_powi_f80(1, 2, 1);
391 try test_powi_f80(1, 3, 1);
392 try test_powi_f80(1, 4, 1);
393 try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
394 try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
395
396 try test_powi_f80(inf_f80, 1, inf_f80);
397 try test_powi_f80(inf_f80, 2, inf_f80);
398 try test_powi_f80(inf_f80, 3, inf_f80);
399 try test_powi_f80(inf_f80, 4, inf_f80);
400 try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80);
401 try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f80);
402
403 try test_powi_f80(-inf_f80, 1, -inf_f80);
404 try test_powi_f80(-inf_f80, 2, inf_f80);
405 try test_powi_f80(-inf_f80, 3, -inf_f80);
406 try test_powi_f80(-inf_f80, 4, inf_f80);
407 try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80);
408 try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f80);
409
410 try test_powi_f80(0, -1, inf_f80);
411 try test_powi_f80(0, -2, inf_f80);
412 try test_powi_f80(0, -3, inf_f80);
413 try test_powi_f80(0, -4, inf_f80);
414 try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80);
415 try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f80);
416 try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80);
417
418 try test_powi_f80(-0.0, -1, -inf_f80);
419 try test_powi_f80(-0.0, -2, inf_f80);
420 try test_powi_f80(-0.0, -3, -inf_f80);
421 try test_powi_f80(-0.0, -4, inf_f80);
422 try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80);
423 try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f80);
424 try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80);
425
426 try test_powi_f80(1, -1, 1);
427 try test_powi_f80(1, -2, 1);
428 try test_powi_f80(1, -3, 1);
429 try test_powi_f80(1, -4, 1);
430 try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
431 try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
432 try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
433
434 try test_powi_f80(inf_f80, -1, 0);
435 try test_powi_f80(inf_f80, -2, 0);
436 try test_powi_f80(inf_f80, -3, 0);
437 try test_powi_f80(inf_f80, -4, 0);
438 try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
439 try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
440 try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
441
442 try test_powi_f80(-inf_f80, -1, -0.0);
443 try test_powi_f80(-inf_f80, -2, 0);
444 try test_powi_f80(-inf_f80, -3, -0.0);
445 try test_powi_f80(-inf_f80, -4, 0);
446 try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
447 try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
448 try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
449
450 try test_powi_f80(2, 10, 1024.0);
451 try test_powi_f80(-2, 10, 1024.0);
452 try test_powi_f80(2, -10, 1.0 / 1024.0);
453 try test_powi_f80(-2, -10, 1.0 / 1024.0);
454
455 try test_powi_f80(2, 19, 524288.0);
456 try test_powi_f80(-2, 19, -524288.0);
457 try test_powi_f80(2, -19, 1.0 / 524288.0);
458 try test_powi_f80(-2, -19, -1.0 / 524288.0);
459
460 try test_powi_f80(2, 31, 2147483648.0);
461 try test_powi_f80(-2, 31, -2147483648.0);
462 try test_powi_f80(2, -31, 1.0 / 2147483648.0);
463 try test_powi_f80(-2, -31, -1.0 / 2147483648.0);
458464}
459465
460test "powixf2" {
461 const inf_f80 = math.inf(f80);
462 try test__powixf2(0, 0, 1);
463 try test__powixf2(1, 0, 1);
464 try test__powixf2(1.5, 0, 1);
465 try test__powixf2(2, 0, 1);
466 try test__powixf2(inf_f80, 0, 1);
467
468 try test__powixf2(-0.0, 0, 1);
469 try test__powixf2(-1, 0, 1);
470 try test__powixf2(-1.5, 0, 1);
471 try test__powixf2(-2, 0, 1);
472 try test__powixf2(-inf_f80, 0, 1);
473
474 try test__powixf2(0, 1, 0);
475 try test__powixf2(0, 2, 0);
476 try test__powixf2(0, 3, 0);
477 try test__powixf2(0, 4, 0);
478 try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
479 try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
480
481 try test__powixf2(-0.0, 1, -0.0);
482 try test__powixf2(-0.0, 2, 0);
483 try test__powixf2(-0.0, 3, -0.0);
484 try test__powixf2(-0.0, 4, 0);
485 try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
486 try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
487
488 try test__powixf2(1, 1, 1);
489 try test__powixf2(1, 2, 1);
490 try test__powixf2(1, 3, 1);
491 try test__powixf2(1, 4, 1);
492 try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
493 try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
494
495 try test__powixf2(inf_f80, 1, inf_f80);
496 try test__powixf2(inf_f80, 2, inf_f80);
497 try test__powixf2(inf_f80, 3, inf_f80);
498 try test__powixf2(inf_f80, 4, inf_f80);
499 try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80);
500 try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f80);
501
502 try test__powixf2(-inf_f80, 1, -inf_f80);
503 try test__powixf2(-inf_f80, 2, inf_f80);
504 try test__powixf2(-inf_f80, 3, -inf_f80);
505 try test__powixf2(-inf_f80, 4, inf_f80);
506 try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80);
507 try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f80);
508
509 try test__powixf2(0, -1, inf_f80);
510 try test__powixf2(0, -2, inf_f80);
511 try test__powixf2(0, -3, inf_f80);
512 try test__powixf2(0, -4, inf_f80);
513 try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80);
514 try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f80);
515 try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80);
516
517 try test__powixf2(-0.0, -1, -inf_f80);
518 try test__powixf2(-0.0, -2, inf_f80);
519 try test__powixf2(-0.0, -3, -inf_f80);
520 try test__powixf2(-0.0, -4, inf_f80);
521 try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80);
522 try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f80);
523 try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80);
524
525 try test__powixf2(1, -1, 1);
526 try test__powixf2(1, -2, 1);
527 try test__powixf2(1, -3, 1);
528 try test__powixf2(1, -4, 1);
529 try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
530 try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
531 try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
532
533 try test__powixf2(inf_f80, -1, 0);
534 try test__powixf2(inf_f80, -2, 0);
535 try test__powixf2(inf_f80, -3, 0);
536 try test__powixf2(inf_f80, -4, 0);
537 try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
538 try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
539 try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
540
541 try test__powixf2(-inf_f80, -1, -0.0);
542 try test__powixf2(-inf_f80, -2, 0);
543 try test__powixf2(-inf_f80, -3, -0.0);
544 try test__powixf2(-inf_f80, -4, 0);
545 try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
546 try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
547 try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
548
549 try test__powixf2(2, 10, 1024.0);
550 try test__powixf2(-2, 10, 1024.0);
551 try test__powixf2(2, -10, 1.0 / 1024.0);
552 try test__powixf2(-2, -10, 1.0 / 1024.0);
553
554 try test__powixf2(2, 19, 524288.0);
555 try test__powixf2(-2, 19, -524288.0);
556 try test__powixf2(2, -19, 1.0 / 524288.0);
557 try test__powixf2(-2, -19, -1.0 / 524288.0);
558
559 try test__powixf2(2, 31, 2147483648.0);
560 try test__powixf2(-2, 31, -2147483648.0);
561 try test__powixf2(2, -31, 1.0 / 2147483648.0);
562 try test__powixf2(-2, -31, -1.0 / 2147483648.0);
466test powi_f128 {
467 const inf_f128 = math.inf(f128);
468 try test_powi_f128(0, 0, 1);
469 try test_powi_f128(1, 0, 1);
470 try test_powi_f128(1.5, 0, 1);
471 try test_powi_f128(2, 0, 1);
472 try test_powi_f128(inf_f128, 0, 1);
473
474 try test_powi_f128(-0.0, 0, 1);
475 try test_powi_f128(-1, 0, 1);
476 try test_powi_f128(-1.5, 0, 1);
477 try test_powi_f128(-2, 0, 1);
478 try test_powi_f128(-inf_f128, 0, 1);
479
480 try test_powi_f128(0, 1, 0);
481 try test_powi_f128(0, 2, 0);
482 try test_powi_f128(0, 3, 0);
483 try test_powi_f128(0, 4, 0);
484 try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
485 try test_powi_f128(0, 0x7FFFFFFF, 0);
486
487 try test_powi_f128(-0.0, 1, -0.0);
488 try test_powi_f128(-0.0, 2, 0);
489 try test_powi_f128(-0.0, 3, -0.0);
490 try test_powi_f128(-0.0, 4, 0);
491 try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
492 try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
493
494 try test_powi_f128(1, 1, 1);
495 try test_powi_f128(1, 2, 1);
496 try test_powi_f128(1, 3, 1);
497 try test_powi_f128(1, 4, 1);
498 try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
499 try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
500
501 try test_powi_f128(inf_f128, 1, inf_f128);
502 try test_powi_f128(inf_f128, 2, inf_f128);
503 try test_powi_f128(inf_f128, 3, inf_f128);
504 try test_powi_f128(inf_f128, 4, inf_f128);
505 try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128);
506 try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f128);
507
508 try test_powi_f128(-inf_f128, 1, -inf_f128);
509 try test_powi_f128(-inf_f128, 2, inf_f128);
510 try test_powi_f128(-inf_f128, 3, -inf_f128);
511 try test_powi_f128(-inf_f128, 4, inf_f128);
512 try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128);
513 try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f128);
514
515 try test_powi_f128(0, -1, inf_f128);
516 try test_powi_f128(0, -2, inf_f128);
517 try test_powi_f128(0, -3, inf_f128);
518 try test_powi_f128(0, -4, inf_f128);
519 try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128);
520 try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f128);
521 try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128);
522
523 try test_powi_f128(-0.0, -1, -inf_f128);
524 try test_powi_f128(-0.0, -2, inf_f128);
525 try test_powi_f128(-0.0, -3, -inf_f128);
526 try test_powi_f128(-0.0, -4, inf_f128);
527 try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128);
528 try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f128);
529 try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128);
530
531 try test_powi_f128(1, -1, 1);
532 try test_powi_f128(1, -2, 1);
533 try test_powi_f128(1, -3, 1);
534 try test_powi_f128(1, -4, 1);
535 try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
536 try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
537 try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
538
539 try test_powi_f128(inf_f128, -1, 0);
540 try test_powi_f128(inf_f128, -2, 0);
541 try test_powi_f128(inf_f128, -3, 0);
542 try test_powi_f128(inf_f128, -4, 0);
543 try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
544 try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
545 try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
546
547 try test_powi_f128(-inf_f128, -1, -0.0);
548 try test_powi_f128(-inf_f128, -2, 0);
549 try test_powi_f128(-inf_f128, -3, -0.0);
550 try test_powi_f128(-inf_f128, -4, 0);
551 try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
552 try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
553 try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
554
555 try test_powi_f128(2, 10, 1024.0);
556 try test_powi_f128(-2, 10, 1024.0);
557 try test_powi_f128(2, -10, 1.0 / 1024.0);
558 try test_powi_f128(-2, -10, 1.0 / 1024.0);
559
560 try test_powi_f128(2, 19, 524288.0);
561 try test_powi_f128(-2, 19, -524288.0);
562 try test_powi_f128(2, -19, 1.0 / 524288.0);
563 try test_powi_f128(-2, -19, -1.0 / 524288.0);
564
565 try test_powi_f128(2, 31, 2147483648.0);
566 try test_powi_f128(-2, 31, -2147483648.0);
567 try test_powi_f128(2, -31, 1.0 / 2147483648.0);
568 try test_powi_f128(-2, -31, -1.0 / 2147483648.0);
563569}
lib/compiler_rt/round.zig+87-49
......@@ -18,19 +18,23 @@ comptime {
1818 symbol(&roundf, "roundf");
1919 symbol(&round, "round");
2020 symbol(&__roundx, "__roundx");
21 if (compiler_rt.want_ppc_abi) {
22 symbol(&roundq, "roundf128");
23 }
21 if (compiler_rt.want_ppc_abi) symbol(&roundq, "roundf128");
2422 symbol(&roundq, "roundq");
2523 symbol(&roundl, "roundl");
2624}
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 {
2930 // TODO: more efficient implementation
30 return @floatCast(roundf(x));
31 return @floatCast(round_f32(x));
3132}
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 {
3438 const f32_toint = 1.0 / math.floatEps(f32);
3539
3640 var x = x_;
......@@ -65,7 +69,10 @@ pub fn roundf(x_: f32) callconv(.c) f32 {
6569 }
6670}
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 {
6976 const f64_toint = 1.0 / math.floatEps(f64);
7077
7178 var x = x_;
......@@ -100,12 +107,18 @@ pub fn round(x_: f64) callconv(.c) f64 {
100107 }
101108}
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 {
104114 // TODO: more efficient implementation
105 return @floatCast(roundq(x));
115 return @floatCast(round_f128(x));
106116}
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 {
109122 const f128_toint = 1.0 / math.floatEps(f128);
110123
111124 var x = x_;
......@@ -142,54 +155,79 @@ pub fn roundq(x_: f128) callconv(.c) f128 {
142155
143156pub fn roundl(x: c_longdouble) callconv(.c) c_longdouble {
144157 switch (@typeInfo(c_longdouble).float.bits) {
145 64 => return round(x),
146 80 => return __roundx(x),
147 128 => return roundq(x),
148 else => @compileError("unreachable"),
158 64 => return round_f64(x),
159 80 => return round_f80(x),
160 128 => return round_f128(x),
161 else => comptime unreachable,
149162 }
150163}
151164
152test "round32" {
153 try expect(roundf(1.3) == 1.0);
154 try expect(roundf(-1.3) == -1.0);
155 try expect(roundf(0.2) == 0.0);
156 try expect(roundf(1.8) == 2.0);
157}
158
159test "round64" {
160 try expect(round(1.3) == 1.0);
161 try expect(round(-1.3) == -1.0);
162 try expect(round(0.2) == 0.0);
163 try expect(round(1.8) == 2.0);
165test round_f16 {
166 try expect(round_f16(1.3) == 1.0);
167 try expect(round_f16(-1.3) == -1.0);
168 try expect(round_f16(1.8) == 2.0);
169 try expect(round_f16(-1.8) == -2.0);
170 try expect(math.isPositiveZero(round_f16(0.2)));
171 try expect(math.isNegativeZero(round_f16(-0.2)));
172 try expect(math.isPositiveZero(round_f16(0.0)));
173 try expect(math.isNegativeZero(round_f16(-0.0)));
174 try expect(math.isPositiveInf(round_f16(math.inf(f32))));
175 try expect(math.isNegativeInf(round_f16(-math.inf(f32))));
176 try expect(math.isNan(round_f16(math.nan(f32))));
164177}
165178
166test "round128" {
167 try expect(roundq(1.3) == 1.0);
168 try expect(roundq(-1.3) == -1.0);
169 try expect(roundq(0.2) == 0.0);
170 try expect(roundq(1.8) == 2.0);
179test round_f32 {
180 try expect(round_f32(1.3) == 1.0);
181 try expect(round_f32(-1.3) == -1.0);
182 try expect(round_f32(1.8) == 2.0);
183 try expect(round_f32(-1.8) == -2.0);
184 try expect(math.isPositiveZero(round_f32(0.2)));
185 try expect(math.isNegativeZero(round_f32(-0.2)));
186 try expect(math.isPositiveZero(round_f32(0.0)));
187 try expect(math.isNegativeZero(round_f32(-0.0)));
188 try expect(math.isPositiveInf(round_f32(math.inf(f32))));
189 try expect(math.isNegativeInf(round_f32(-math.inf(f32))));
190 try expect(math.isNan(round_f32(math.nan(f32))));
171191}
172192
173test "round32.special" {
174 try expect(roundf(0.0) == 0.0);
175 try expect(roundf(-0.0) == -0.0);
176 try expect(math.isPositiveInf(roundf(math.inf(f32))));
177 try expect(math.isNegativeInf(roundf(-math.inf(f32))));
178 try expect(math.isNan(roundf(math.nan(f32))));
193test round_f64 {
194 try expect(round_f64(1.3) == 1.0);
195 try expect(round_f64(-1.3) == -1.0);
196 try expect(round_f64(1.8) == 2.0);
197 try expect(round_f64(-1.8) == -2.0);
198 try expect(math.isPositiveZero(round_f64(0.2)));
199 try expect(math.isNegativeZero(round_f64(-0.2)));
200 try expect(math.isPositiveZero(round_f64(0.0)));
201 try expect(math.isNegativeZero(round_f64(-0.0)));
202 try expect(math.isPositiveInf(round_f64(math.inf(f64))));
203 try expect(math.isNegativeInf(round_f64(-math.inf(f64))));
204 try expect(math.isNan(round_f64(math.nan(f64))));
179205}
180206
181test "round64.special" {
182 try expect(round(0.0) == 0.0);
183 try expect(round(-0.0) == -0.0);
184 try expect(math.isPositiveInf(round(math.inf(f64))));
185 try expect(math.isNegativeInf(round(-math.inf(f64))));
186 try expect(math.isNan(round(math.nan(f64))));
207test round_f80 {
208 try expect(round_f80(1.3) == 1.0);
209 try expect(round_f80(-1.3) == -1.0);
210 try expect(round_f80(1.8) == 2.0);
211 try expect(round_f80(-1.8) == -2.0);
212 try expect(math.isPositiveZero(round_f80(0.2)));
213 try expect(math.isNegativeZero(round_f80(-0.2)));
214 try expect(math.isPositiveZero(round_f80(0.0)));
215 try expect(math.isNegativeZero(round_f80(-0.0)));
216 try expect(math.isPositiveInf(round_f80(math.inf(f64))));
217 try expect(math.isNegativeInf(round_f80(-math.inf(f64))));
218 try expect(math.isNan(round_f80(math.nan(f64))));
187219}
188220
189test "round128.special" {
190 try expect(roundq(0.0) == 0.0);
191 try expect(roundq(-0.0) == -0.0);
192 try expect(math.isPositiveInf(roundq(math.inf(f128))));
193 try expect(math.isNegativeInf(roundq(-math.inf(f128))));
194 try expect(math.isNan(roundq(math.nan(f128))));
221test round_f128 {
222 try expect(round_f128(1.3) == 1.0);
223 try expect(round_f128(-1.3) == -1.0);
224 try expect(round_f128(1.8) == 2.0);
225 try expect(round_f128(-1.8) == -2.0);
226 try expect(math.isPositiveZero(round_f128(0.2)));
227 try expect(math.isNegativeZero(round_f128(-0.2)));
228 try expect(math.isPositiveZero(round_f128(0.0)));
229 try expect(math.isNegativeZero(round_f128(-0.0)));
230 try expect(math.isPositiveInf(round_f128(math.inf(f128))));
231 try expect(math.isNegativeInf(round_f128(-math.inf(f128))));
232 try expect(math.isNan(round_f128(math.nan(f128))));
195233}
lib/compiler_rt/sin.zig+65-49
......@@ -13,31 +13,37 @@ const expect = std.testing.expect;
1313const expectApproxEqAbs = std.testing.expectApproxEqAbs;
1414
1515const compiler_rt = @import("../compiler_rt.zig");
16const symbol = @import("../compiler_rt.zig").symbol;
16const symbol = compiler_rt.symbol;
1717const trig = @import("trig.zig");
1818const rem_pio2 = @import("rem_pio2.zig").rem_pio2;
1919const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f;
2020const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l;
2121
2222comptime {
23 symbol(&sinh, "__sinh");
24 symbol(&sinl, "__sinl");
23 symbol(&__sinh, "__sinh");
2524 symbol(&sinf, "sinf");
2625 symbol(&sin, "sin");
27 symbol(&sinx, "__sinx");
26 symbol(&__sinx, "__sinx");
2827 if (compiler_rt.want_ppc_abi) {
2928 symbol(&sinq, "sinf128");
3029 }
3130 symbol(&sinq, "sinq");
3231 symbol(&sinl, "sinl");
32 symbol(&sinl, "__sinl"); // required by musl
3333}
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 {
3639 // TODO: more efficient implementation
37 return @floatCast(sinf(x));
40 return @floatCast(sin_f32(x));
3841}
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 {
4147 // Small multiples of pi/2 rounded to double precision.
4248 const s1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18
4349 const s2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18
......@@ -98,7 +104,10 @@ pub fn sinf(x: f32) callconv(.c) f32 {
98104 };
99105}
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 {
102111 var ix = @as(u64, @bitCast(x)) >> 32;
103112 ix &= 0x7fffffff;
104113
......@@ -133,7 +142,10 @@ pub fn sin(x: f64) callconv(.c) f64 {
133142 };
134143}
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 {
137149 const se = ld.signExponent(x) & 0x7fff;
138150 if (se == 0x7fff) {
139151 return x - x;
......@@ -160,7 +172,10 @@ fn sinx(x: f80) callconv(.c) f80 {
160172 };
161173}
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 {
164179 const se = ld.signExponent(x) & 0x7fff;
165180 if (se == 0x7fff) {
166181 return x - x;
......@@ -189,20 +204,21 @@ pub fn sinq(x: f128) callconv(.c) f128 {
189204
190205pub fn sinl(x: c_longdouble) callconv(.c) c_longdouble {
191206 switch (@typeInfo(c_longdouble).float.bits) {
192 64 => return sin(x),
193 80 => return sinx(x),
194 128 => return sinq(x),
195 else => @compileError("unreachable"),
207 64 => return sin_f64(x),
208 80 => return sin_f80(x),
209 128 => return sin_f128(x),
210 else => comptime unreachable,
196211 }
197212}
198213
199214fn testSinSpecial(comptime T: type) !void {
200215 const f = switch (T) {
201 f32 => sinf,
202 f64 => sin,
203 f80 => sinx,
204 f128 => sinq,
205 else => @compileError("unimplemented"),
216 f16 => sin_f16,
217 f32 => sin_f32,
218 f64 => sin_f64,
219 f80 => sin_f80,
220 f128 => sin_f128,
221 else => comptime unreachable,
206222 };
207223
208224 try expect(math.isPositiveZero(f(0.0)));
......@@ -214,13 +230,13 @@ fn testSinSpecial(comptime T: type) !void {
214230
215231test "sin32.normal" {
216232 const epsilon = math.floatEps(f32);
217 try expectApproxEqAbs(@as(f32, 0.0), sinf(0.0), epsilon);
218 try expectApproxEqAbs(@as(f32, 0.19866933), sinf(0.2), epsilon);
219 try expectApproxEqAbs(@as(f32, 0.77851737), sinf(0.8923), epsilon);
220 try expectApproxEqAbs(@as(f32, 0.997495), sinf(1.5), epsilon);
221 try expectApproxEqAbs(@as(f32, -0.997495), sinf(-1.5), epsilon);
222 try expectApproxEqAbs(@as(f32, -0.24654257), sinf(37.45), epsilon);
223 try expectApproxEqAbs(@as(f32, 0.9161657), sinf(89.123), epsilon);
233 try expectApproxEqAbs(@as(f32, 0.0), sin_f32(0.0), epsilon);
234 try expectApproxEqAbs(@as(f32, 0.19866933), sin_f32(0.2), epsilon);
235 try expectApproxEqAbs(@as(f32, 0.77851737), sin_f32(0.8923), epsilon);
236 try expectApproxEqAbs(@as(f32, 0.997495), sin_f32(1.5), epsilon);
237 try expectApproxEqAbs(@as(f32, -0.997495), sin_f32(-1.5), epsilon);
238 try expectApproxEqAbs(@as(f32, -0.24654257), sin_f32(37.45), epsilon);
239 try expectApproxEqAbs(@as(f32, 0.9161657), sin_f32(89.123), epsilon);
224240}
225241
226242test "sin32.special" {
......@@ -229,13 +245,13 @@ test "sin32.special" {
229245
230246test "sin64.normal" {
231247 const epsilon = math.floatEps(f64);
232 try expectApproxEqAbs(@as(f64, 0.0), sin(0.0), epsilon);
233 try expectApproxEqAbs(@as(f64, 0.19866933079506122), sin(0.2), epsilon);
234 try expectApproxEqAbs(@as(f64, 0.7785173385577349), sin(0.8923), epsilon);
235 try expectApproxEqAbs(@as(f64, 0.9974949866040544), sin(1.5), epsilon);
236 try expectApproxEqAbs(@as(f64, -0.9974949866040544), sin(-1.5), epsilon);
237 try expectApproxEqAbs(@as(f64, -0.24654331551411082), sin(37.45), epsilon);
238 try expectApproxEqAbs(@as(f64, 0.9161652766622714), sin(89.123), epsilon);
248 try expectApproxEqAbs(@as(f64, 0.0), sin_f64(0.0), epsilon);
249 try expectApproxEqAbs(@as(f64, 0.19866933079506122), sin_f64(0.2), epsilon);
250 try expectApproxEqAbs(@as(f64, 0.7785173385577349), sin_f64(0.8923), epsilon);
251 try expectApproxEqAbs(@as(f64, 0.9974949866040544), sin_f64(1.5), epsilon);
252 try expectApproxEqAbs(@as(f64, -0.9974949866040544), sin_f64(-1.5), epsilon);
253 try expectApproxEqAbs(@as(f64, -0.24654331551411082), sin_f64(37.45), epsilon);
254 try expectApproxEqAbs(@as(f64, 0.9161652766622714), sin_f64(89.123), epsilon);
239255}
240256
241257test "sin64.special" {
......@@ -244,13 +260,13 @@ test "sin64.special" {
244260
245261test "sin80.normal" {
246262 const epsilon = math.floatEps(f80);
247 try expectApproxEqAbs(@as(f80, 0.0), sinx(0.0), epsilon);
248 try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), sinx(0.2), epsilon);
249 try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), sinx(0.8923), epsilon);
250 try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), sinx(1.5), epsilon);
251 try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), sinx(-1.5), epsilon);
252 try expectApproxEqAbs(@as(f80, -0.24654331551411356504), sinx(37.45), epsilon);
253 try expectApproxEqAbs(@as(f80, 0.91616527666226951006), sinx(89.123), epsilon);
263 try expectApproxEqAbs(@as(f80, 0.0), sin_f80(0.0), epsilon);
264 try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), sin_f80(0.2), epsilon);
265 try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), sin_f80(0.8923), epsilon);
266 try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), sin_f80(1.5), epsilon);
267 try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), sin_f80(-1.5), epsilon);
268 try expectApproxEqAbs(@as(f80, -0.24654331551411356504), sin_f80(37.45), epsilon);
269 try expectApproxEqAbs(@as(f80, 0.91616527666226951006), sin_f80(89.123), epsilon);
254270}
255271
256272test "sin80.special" {
......@@ -259,13 +275,13 @@ test "sin80.special" {
259275
260276test "sin128.normal" {
261277 const epsilon = math.floatEps(f128);
262 try expectApproxEqAbs(@as(f128, 0.0), sinq(0.0), epsilon);
263 try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), sinq(0.2), epsilon);
264 try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), sinq(0.8923), epsilon);
265 try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), sinq(1.5), epsilon);
266 try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), sinq(-1.5), epsilon);
267 try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), sinq(37.45), epsilon);
268 try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), sinq(89.123), epsilon);
278 try expectApproxEqAbs(@as(f128, 0.0), sin_f128(0.0), epsilon);
279 try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), sin_f128(0.2), epsilon);
280 try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), sin_f128(0.8923), epsilon);
281 try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), sin_f128(1.5), epsilon);
282 try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), sin_f128(-1.5), epsilon);
283 try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), sin_f128(37.45), epsilon);
284 try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), sin_f128(89.123), epsilon);
269285}
270286
271287test "sin128.special" {
......@@ -274,10 +290,10 @@ test "sin128.special" {
274290
275291test "sin32 #9901" {
276292 const float: f32 = @bitCast(@as(u32, 0b11100011111111110000000000000000));
277 _ = sinf(float);
293 _ = sin_f32(float);
278294}
279295
280296test "sin64 #9901" {
281297 const float: f64 = @bitCast(@as(u64, 0b1111111101000001000000001111110111111111100000000000000000000001));
282 _ = sin(float);
298 _ = sin_f64(float);
283299}
lib/compiler_rt/sincos.zig+124-177
......@@ -25,16 +25,23 @@ comptime {
2525 symbol(&sincosl, "sincosl");
2626}
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 } {
2934 // TODO: more efficient implementation
30 var big_sin: f32 = undefined;
31 var big_cos: f32 = undefined;
32 sincosf(x, &big_sin, &big_cos);
33 r_sin.* = @as(f16, @floatCast(big_sin));
34 r_cos.* = @as(f16, @floatCast(big_cos));
35 const s, const c = sincos_f32(x);
36 return .{ @floatCast(s), @floatCast(c) };
3537}
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 } {
3845 const sc1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18
3946 const sc2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18
4047 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 {
5663 mem.doNotOptimizeAway(x + 0x1p120);
5764 }
5865 }
59 r_sin.* = x;
60 r_cos.* = 1.0;
61 return;
66 return .{ x, 1.0 };
6267 }
63 r_sin.* = trig.sindf(x);
64 r_cos.* = trig.cosdf(x);
65 return;
68 return .{ trig.sindf(x), trig.cosdf(x) };
6669 }
6770
6871 // |x| ~<= 5*pi/4
......@@ -70,18 +73,16 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {
7073 // |x| ~<= 3pi/4
7174 if (ix <= 0x4016cbe3) {
7275 if (sign) {
73 r_sin.* = -trig.cosdf(x + sc1pio2);
74 r_cos.* = trig.sindf(x + sc1pio2);
76 return .{ -trig.cosdf(x + sc1pio2), trig.sindf(x + sc1pio2) };
7577 } else {
76 r_sin.* = trig.cosdf(sc1pio2 - x);
77 r_cos.* = trig.sindf(sc1pio2 - x);
78 return .{ trig.cosdf(sc1pio2 - x), trig.sindf(sc1pio2 - x) };
7879 }
79 return;
8080 }
8181 // -sin(x+c) is not correct if x+c could be 0: -0 vs +0
82 r_sin.* = -trig.sindf(if (sign) x + sc2pio2 else x - sc2pio2);
83 r_cos.* = -trig.cosdf(if (sign) x + sc2pio2 else x - sc2pio2);
84 return;
82 return .{
83 -trig.sindf(if (sign) x + sc2pio2 else x - sc2pio2),
84 -trig.cosdf(if (sign) x + sc2pio2 else x - sc2pio2),
85 };
8586 }
8687
8788 // |x| ~<= 9*pi/4
......@@ -89,25 +90,21 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {
8990 // |x| ~<= 7*pi/4
9091 if (ix <= 0x40afeddf) {
9192 if (sign) {
92 r_sin.* = trig.cosdf(x + sc3pio2);
93 r_cos.* = -trig.sindf(x + sc3pio2);
93 return .{ trig.cosdf(x + sc3pio2), -trig.sindf(x + sc3pio2) };
9494 } else {
95 r_sin.* = -trig.cosdf(x - sc3pio2);
96 r_cos.* = trig.sindf(x - sc3pio2);
95 return .{ -trig.cosdf(x - sc3pio2), trig.sindf(x - sc3pio2) };
9796 }
98 return;
9997 }
100 r_sin.* = trig.sindf(if (sign) x + sc4pio2 else x - sc4pio2);
101 r_cos.* = trig.cosdf(if (sign) x + sc4pio2 else x - sc4pio2);
102 return;
98 return .{
99 trig.sindf(if (sign) x + sc4pio2 else x - sc4pio2),
100 trig.cosdf(if (sign) x + sc4pio2 else x - sc4pio2),
101 };
103102 }
104103
105104 // sin(Inf or NaN) is NaN
106105 if (ix >= 0x7f800000) {
107106 const result = x - x;
108 r_sin.* = result;
109 r_cos.* = result;
110 return;
107 return .{ result, result };
111108 }
112109
113110 // general argument reduction needed
......@@ -115,27 +112,20 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {
115112 const n = rem_pio2f(x, &y);
116113 const s = trig.sindf(y);
117114 const c = trig.cosdf(y);
118 switch (n & 3) {
119 0 => {
120 r_sin.* = s;
121 r_cos.* = c;
122 },
123 1 => {
124 r_sin.* = c;
125 r_cos.* = -s;
126 },
127 2 => {
128 r_sin.* = -s;
129 r_cos.* = -c;
130 },
131 else => {
132 r_sin.* = -c;
133 r_cos.* = s;
134 },
135 }
115 return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) {
116 0 => .{ s, c },
117 1 => .{ c, -s },
118 2 => .{ -s, -c },
119 3 => .{ -c, s },
120 };
136121}
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 } {
139129 const ix = @as(u32, @truncate(@as(u64, @bitCast(x)) >> 32)) & 0x7fffffff;
140130
141131 // |x| ~< pi/4
......@@ -150,21 +140,15 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void {
150140 mem.doNotOptimizeAway(x + 0x1p120);
151141 }
152142 }
153 r_sin.* = x;
154 r_cos.* = 1.0;
155 return;
143 return .{ x, 1.0 };
156144 }
157 r_sin.* = trig.sin(x, 0.0, 0);
158 r_cos.* = trig.cos(x, 0.0);
159 return;
145 return .{ trig.sin(x, 0.0, 0), trig.cos(x, 0.0) };
160146 }
161147
162148 // sincos(Inf or NaN) is NaN
163149 if (ix >= 0x7ff00000) {
164150 const result = x - x;
165 r_sin.* = result;
166 r_cos.* = result;
167 return;
151 return .{ result, result };
168152 }
169153
170154 // argument reduction needed
......@@ -172,33 +156,24 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void {
172156 const n = rem_pio2(x, &y);
173157 const s = trig.sin(y[0], y[1], 1);
174158 const c = trig.cos(y[0], y[1]);
175 switch (n & 3) {
176 0 => {
177 r_sin.* = s;
178 r_cos.* = c;
179 },
180 1 => {
181 r_sin.* = c;
182 r_cos.* = -s;
183 },
184 2 => {
185 r_sin.* = -s;
186 r_cos.* = -c;
187 },
188 else => {
189 r_sin.* = -c;
190 r_cos.* = s;
191 },
192 }
159 return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) {
160 0 => .{ s, c },
161 1 => .{ c, -s },
162 2 => .{ -s, -c },
163 3 => .{ -c, s },
164 };
193165}
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 } {
196173 const se = ld.signExponent(x) & 0x7fff;
197174 if (se == 0x7fff) {
198175 const result = x - x;
199 r_sin.* = result;
200 r_cos.* = result;
201 return;
176 return .{ result, result };
202177 }
203178
204179 if (@abs(x) < trig.pi_4) {
......@@ -207,47 +182,34 @@ pub fn sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void {
207182 if (compiler_rt.want_float_exceptions and se == 0) {
208183 mem.doNotOptimizeAway(x * 0x1p-120);
209184 }
210 r_sin.* = x;
211185 // raise inexact if x!=0
212 r_cos.* = 1.0 + x;
213 return;
186 return .{ x, 1.0 + x };
214187 }
215 r_sin.* = trig.sinx(x, 0.0, 0);
216 r_cos.* = trig.cosx(x, 0.0);
217 return;
188 return .{ trig.sinx(x, 0.0, 0), trig.cosx(x, 0.0) };
218189 }
219190
220191 var y: [2]f80 = undefined;
221192 const n = rem_pio2l(f80, x, &y);
222193 const s = trig.sinx(y[0], y[1], 1);
223194 const c = trig.cosx(y[0], y[1]);
224 switch (n & 3) {
225 0 => {
226 r_sin.* = s;
227 r_cos.* = c;
228 },
229 1 => {
230 r_sin.* = c;
231 r_cos.* = -s;
232 },
233 2 => {
234 r_sin.* = -s;
235 r_cos.* = -c;
236 },
237 else => {
238 r_sin.* = -c;
239 r_cos.* = s;
240 },
241 }
195 return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) {
196 0 => .{ s, c },
197 1 => .{ c, -s },
198 2 => .{ -s, -c },
199 3 => .{ -c, s },
200 };
242201}
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 } {
245209 const se = ld.signExponent(x) & 0x7fff;
246210 if (se == 0x7fff) {
247211 const result = x - x;
248 r_sin.* = result;
249 r_cos.* = result;
250 return;
212 return .{ result, result };
251213 }
252214
253215 if (@abs(x) < trig.pi_4) {
......@@ -256,78 +218,63 @@ pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void {
256218 if (compiler_rt.want_float_exceptions and se == 0) {
257219 mem.doNotOptimizeAway(x * 0x1p-120);
258220 }
259 r_sin.* = x;
260221 // raise inexact if x!=0
261 r_cos.* = 1.0 + x;
262 return;
222 return .{ x, 1.0 + x };
263223 }
264 r_sin.* = trig.sinq(x, 0.0, 0);
265 r_cos.* = trig.cosq(x, 0.0);
266 return;
224 return .{ trig.sinq(x, 0.0, 0), trig.cosq(x, 0.0) };
267225 }
268226
269227 var y: [2]f128 = undefined;
270228 const n = rem_pio2l(f128, x, &y);
271229 const s = trig.sinq(y[0], y[1], 1);
272230 const c = trig.cosq(y[0], y[1]);
273 switch (n & 3) {
274 0 => {
275 r_sin.* = s;
276 r_cos.* = c;
277 },
278 1 => {
279 r_sin.* = c;
280 r_cos.* = -s;
281 },
282 2 => {
283 r_sin.* = -s;
284 r_cos.* = -c;
285 },
286 else => {
287 r_sin.* = -c;
288 r_cos.* = s;
289 },
290 }
231 return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) {
232 0 => .{ s, c },
233 1 => .{ c, -s },
234 2 => .{ -s, -c },
235 3 => .{ -c, s },
236 };
291237}
292238
293239pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.c) void {
294 switch (@typeInfo(c_longdouble).float.bits) {
295 64 => return sincos(x, r_sin, r_cos),
296 80 => return sincosx(x, r_sin, r_cos),
297 128 => return sincosq(x, r_sin, r_cos),
298 else => @compileError("unreachable"),
299 }
240 r_sin.*, r_cos.* = switch (@typeInfo(c_longdouble).float.bits) {
241 64 => sincos_f64(x),
242 80 => sincos_f80(x),
243 128 => sincos_f128(x),
244 else => comptime unreachable,
245 };
300246}
301247
302248fn testSincosSpecial(comptime T: type) !void {
303249 const f = switch (T) {
304 f32 => sincosf,
305 f64 => sincos,
306 f80 => sincosx,
307 f128 => sincosq,
250 f16 => sincos_f16,
251 f32 => sincos_f32,
252 f64 => sincos_f64,
253 f80 => sincos_f80,
254 f128 => sincos_f128,
308255 else => @compileError("unimplemented"),
309256 };
310257
311258 var s: T = undefined;
312259 var c: T = undefined;
313260
314 f(0.0, &s, &c);
261 s, c = f(0.0);
315262 try expect(math.isPositiveZero(s));
316263 try expect(c == 1.0);
317264
318 f(-0.0, &s, &c);
265 s, c = f(-0.0);
319266 try expect(math.isNegativeZero(s));
320267 try expect(c == 1.0);
321268
322 f(math.inf(T), &s, &c);
269 s, c = f(math.inf(T));
323270 try expect(math.isNan(s));
324271 try expect(math.isNan(c));
325272
326 f(-math.inf(T), &s, &c);
273 s, c = f(-math.inf(T));
327274 try expect(math.isNan(s));
328275 try expect(math.isNan(c));
329276
330 f(math.nan(T), &s, &c);
277 s, c = f(math.nan(T));
331278 try expect(math.isNan(s));
332279 try expect(math.isNan(c));
333280}
......@@ -337,31 +284,31 @@ test "sincos32.normal" {
337284 var s: f32 = undefined;
338285 var c: f32 = undefined;
339286
340 sincosf(0.0, &s, &c);
287 s, c = sincos_f32(0.0);
341288 try expectApproxEqAbs(@as(f32, 0.0), s, epsilon);
342289 try expectApproxEqAbs(@as(f32, 1.0), c, epsilon);
343290
344 sincosf(0.2, &s, &c);
291 s, c = sincos_f32(0.2);
345292 try expectApproxEqAbs(@as(f32, 0.19866933), s, epsilon);
346293 try expectApproxEqAbs(@as(f32, 0.9800666), c, epsilon);
347294
348 sincosf(0.8923, &s, &c);
295 s, c = sincos_f32(0.8923);
349296 try expectApproxEqAbs(@as(f32, 0.77851737), s, epsilon);
350297 try expectApproxEqAbs(@as(f32, 0.6276231), c, epsilon);
351298
352 sincosf(1.5, &s, &c);
299 s, c = sincos_f32(1.5);
353300 try expectApproxEqAbs(@as(f32, 0.997495), s, epsilon);
354301 try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon);
355302
356 sincosf(-1.5, &s, &c);
303 s, c = sincos_f32(-1.5);
357304 try expectApproxEqAbs(@as(f32, -0.997495), s, epsilon);
358305 try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon);
359306
360 sincosf(37.45, &s, &c);
307 s, c = sincos_f32(37.45);
361308 try expectApproxEqAbs(@as(f32, -0.24654257), s, epsilon);
362309 try expectApproxEqAbs(@as(f32, 0.96913195), c, epsilon);
363310
364 sincosf(89.123, &s, &c);
311 s, c = sincos_f32(89.123);
365312 try expectApproxEqAbs(@as(f32, 0.9161657), s, epsilon);
366313 try expectApproxEqAbs(@as(f32, 0.40079966), c, epsilon);
367314}
......@@ -375,31 +322,31 @@ test "sincos64.normal" {
375322 var s: f64 = undefined;
376323 var c: f64 = undefined;
377324
378 sincos(0.0, &s, &c);
325 s, c = sincos_f64(0.0);
379326 try expectApproxEqAbs(@as(f64, 0.0), s, epsilon);
380327 try expectApproxEqAbs(@as(f64, 1.0), c, epsilon);
381328
382 sincos(0.2, &s, &c);
329 s, c = sincos_f64(0.2);
383330 try expectApproxEqAbs(@as(f64, 0.19866933079506122), s, epsilon);
384331 try expectApproxEqAbs(@as(f64, 0.9800665778412416), c, epsilon);
385332
386 sincos(0.8923, &s, &c);
333 s, c = sincos_f64(0.8923);
387334 try expectApproxEqAbs(@as(f64, 0.7785173385577349), s, epsilon);
388335 try expectApproxEqAbs(@as(f64, 0.6276230983360804), c, epsilon);
389336
390 sincos(1.5, &s, &c);
337 s, c = sincos_f64(1.5);
391338 try expectApproxEqAbs(@as(f64, 0.9974949866040544), s, epsilon);
392339 try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon);
393340
394 sincos(-1.5, &s, &c);
341 s, c = sincos_f64(-1.5);
395342 try expectApproxEqAbs(@as(f64, -0.9974949866040544), s, epsilon);
396343 try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon);
397344
398 sincos(37.45, &s, &c);
345 s, c = sincos_f64(37.45);
399346 try expectApproxEqAbs(@as(f64, -0.24654331551411082), s, epsilon);
400347 try expectApproxEqAbs(@as(f64, 0.9691317730707778), c, epsilon);
401348
402 sincos(89.123, &s, &c);
349 s, c = sincos_f64(89.123);
403350 try expectApproxEqAbs(@as(f64, 0.9161652766622714), s, epsilon);
404351 try expectApproxEqAbs(@as(f64, 0.4008006809354791), c, epsilon);
405352}
......@@ -413,31 +360,31 @@ test "sincos80.normal" {
413360 var s: f80 = undefined;
414361 var c: f80 = undefined;
415362
416 sincosx(0.0, &s, &c);
363 s, c = sincos_f80(0.0);
417364 try expectApproxEqAbs(@as(f80, 0.0), s, epsilon);
418365 try expectApproxEqAbs(@as(f80, 1.0), c, epsilon);
419366
420 sincosx(0.2, &s, &c);
367 s, c = sincos_f80(0.2);
421368 try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), s, epsilon);
422369 try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), c, epsilon);
423370
424 sincosx(0.8923, &s, &c);
371 s, c = sincos_f80(0.8923);
425372 try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), s, epsilon);
426373 try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), c, epsilon);
427374
428 sincosx(1.5, &s, &c);
375 s, c = sincos_f80(1.5);
429376 try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), s, epsilon);
430377 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon);
431378
432 sincosx(-1.5, &s, &c);
379 s, c = sincos_f80(-1.5);
433380 try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), s, epsilon);
434381 try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon);
435382
436 sincosx(37.45, &s, &c);
383 s, c = sincos_f80(37.45);
437384 try expectApproxEqAbs(@as(f80, -0.24654331551411356504), s, epsilon);
438385 try expectApproxEqAbs(@as(f80, 0.9691317730707771246), c, epsilon);
439386
440 sincosx(89.123, &s, &c);
387 s, c = sincos_f80(89.123);
441388 try expectApproxEqAbs(@as(f80, 0.91616527666226951006), s, epsilon);
442389 try expectApproxEqAbs(@as(f80, 0.4008006809354834001), c, epsilon);
443390}
......@@ -451,31 +398,31 @@ test "sincos128.normal" {
451398 var s: f128 = undefined;
452399 var c: f128 = undefined;
453400
454 sincosq(0.0, &s, &c);
401 s, c = sincos_f128(0.0);
455402 try expectApproxEqAbs(@as(f128, 0.0), s, epsilon);
456403 try expectApproxEqAbs(@as(f128, 1.0), c, epsilon);
457404
458 sincosq(0.2, &s, &c);
405 s, c = sincos_f128(0.2);
459406 try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), s, epsilon);
460407 try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), c, epsilon);
461408
462 sincosq(0.8923, &s, &c);
409 s, c = sincos_f128(0.8923);
463410 try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), s, epsilon);
464411 try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), c, epsilon);
465412
466 sincosq(1.5, &s, &c);
413 s, c = sincos_f128(1.5);
467414 try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), s, epsilon);
468415 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon);
469416
470 sincosq(-1.5, &s, &c);
417 s, c = sincos_f128(-1.5);
471418 try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), s, epsilon);
472419 try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon);
473420
474 sincosq(37.45, &s, &c);
421 s, c = sincos_f128(37.45);
475422 try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), s, epsilon);
476423 try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), c, epsilon);
477424
478 sincosq(89.123, &s, &c);
425 s, c = sincos_f128(89.123);
479426 try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), s, epsilon);
480427 try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), c, epsilon);
481428}
lib/compiler_rt/sqrt.zig+148-133
......@@ -28,7 +28,10 @@ comptime {
2828 symbol(&sqrtl, "sqrtl");
2929}
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 {
3235 var ix: u16 = @bitCast(x);
3336 var top = ix >> 10;
3437
......@@ -93,7 +96,10 @@ pub fn __sqrth(x: f16) callconv(.c) f16 {
9396 return y;
9497}
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 {
97103 var ix: u32 = @bitCast(x);
98104
99105 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 {
147153 return y + t;
148154}
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 {
151160 var ix: u64 = @bitCast(x);
152161 var top = ix >> 52;
153162
......@@ -284,7 +293,10 @@ pub fn sqrt(x: f64) callconv(.c) f64 {
284293 return y;
285294}
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 {
288300 var ix: u80 = @bitCast(x);
289301 var top = ix >> 64;
290302
......@@ -381,7 +393,10 @@ pub fn __sqrtx(x: f80) callconv(.c) f80 {
381393 return y;
382394}
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 {
385400 var ix: u128 = @bitCast(x);
386401 var top = ix >> 112;
387402
......@@ -483,10 +498,10 @@ fn _Qp_sqrt(c: *f128, a: *f128) callconv(.c) void {
483498
484499pub fn sqrtl(x: c_longdouble) callconv(.c) c_longdouble {
485500 switch (@typeInfo(c_longdouble).float.bits) {
486 64 => return sqrt(x),
487 80 => return __sqrtx(x),
488 128 => return sqrtq(x),
489 else => @compileError("unreachable"),
501 64 => return sqrt_f64(x),
502 80 => return sqrt_f80(x),
503 128 => return sqrt_f128(x),
504 else => comptime unreachable,
490505 }
491506}
492507
......@@ -545,187 +560,187 @@ inline fn mul80_tail(a: u80, b: u80) u80 {
545560 return alo * blo +% ((ahi * blo) << 40) +% ((alo * bhi) << 40);
546561}
547562
548test "__sqrth" {
563test "sqrt_f16" {
549564 // sqrt(±0) is ±0
550 try std.testing.expectEqual(__sqrth(0x0.0p0), 0x0.0p0);
551 try std.testing.expectEqual(__sqrth(-0x0.0p0), -0x0.0p0);
565 try std.testing.expectEqual(sqrt_f16(0x0.0p0), 0x0.0p0);
566 try std.testing.expectEqual(sqrt_f16(-0x0.0p0), -0x0.0p0);
552567 // 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);
554569 // sqrt(4)=2
555 try std.testing.expectEqual(__sqrth(0x1p2), 0x1p1);
570 try std.testing.expectEqual(sqrt_f16(0x1p2), 0x1p1);
556571 // sqrt(x) for x=1, 1±ulp
557 try std.testing.expectEqual(__sqrth(0x1p0), 0x1p0);
558 try std.testing.expectEqual(__sqrth(0x1.004p0), 0x1p0);
559 try std.testing.expectEqual(__sqrth(0x1.FF8p-1), 0x1.FFCp-1);
572 try std.testing.expectEqual(sqrt_f16(0x1p0), 0x1p0);
573 try std.testing.expectEqual(sqrt_f16(0x1.004p0), 0x1p0);
574 try std.testing.expectEqual(sqrt_f16(0x1.FF8p-1), 0x1.FFCp-1);
560575 // 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);
562577 // 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);
564579 // 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))));
566581 // 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))));
568583 // sqrt(-ve) is nan
569 try std.testing.expect(math.isNan(__sqrth(-0x1p-14)));
570 try std.testing.expect(math.isNan(__sqrth(-0x1p+0)));
571 try std.testing.expect(math.isNan(__sqrth(-math.inf(f16))));
584 try std.testing.expect(math.isNan(sqrt_f16(-0x1p-14)));
585 try std.testing.expect(math.isNan(sqrt_f16(-0x1p+0)));
586 try std.testing.expect(math.isNan(sqrt_f16(-math.inf(f16))));
572587 // random arguments
573 try std.testing.expectEqual(__sqrth(0x1.1p14), 0x1.08p7);
574 try std.testing.expectEqual(__sqrth(0x1.C9p-12), 0x1.56p-6);
575 try std.testing.expectEqual(__sqrth(0x1.CE8p-7), 0x1.E68p-4);
576 try std.testing.expectEqual(__sqrth(0x1.134p-7), 0x1.778p-4);
577 try std.testing.expectEqual(__sqrth(0x1.E9Cp-10), 0x1.62p-5);
578 try std.testing.expectEqual(__sqrth(0x1.3Dp9), 0x1.92Cp4);
579 try std.testing.expectEqual(__sqrth(0x1.AA4p8), 0x1.4A4p4);
580 try std.testing.expectEqual(__sqrth(0x1.8A8p4), 0x1.3DCp2);
581 try std.testing.expectEqual(__sqrth(0x1.8Fp-7), 0x1.C4p-4);
582 try std.testing.expectEqual(__sqrth(0x1.584p-11), 0x1.A3Cp-6);
588 try std.testing.expectEqual(sqrt_f16(0x1.1p14), 0x1.08p7);
589 try std.testing.expectEqual(sqrt_f16(0x1.C9p-12), 0x1.56p-6);
590 try std.testing.expectEqual(sqrt_f16(0x1.CE8p-7), 0x1.E68p-4);
591 try std.testing.expectEqual(sqrt_f16(0x1.134p-7), 0x1.778p-4);
592 try std.testing.expectEqual(sqrt_f16(0x1.E9Cp-10), 0x1.62p-5);
593 try std.testing.expectEqual(sqrt_f16(0x1.3Dp9), 0x1.92Cp4);
594 try std.testing.expectEqual(sqrt_f16(0x1.AA4p8), 0x1.4A4p4);
595 try std.testing.expectEqual(sqrt_f16(0x1.8A8p4), 0x1.3DCp2);
596 try std.testing.expectEqual(sqrt_f16(0x1.8Fp-7), 0x1.C4p-4);
597 try std.testing.expectEqual(sqrt_f16(0x1.584p-11), 0x1.A3Cp-6);
583598}
584599
585test "sqrtf" {
600test "sqrt_f32" {
586601 // sqrt(±0) is ±0
587 try std.testing.expectEqual(sqrtf(0x0.0p0), 0x0.0p0);
588 try std.testing.expectEqual(sqrtf(-0x0.0p0), -0x0.0p0);
602 try std.testing.expectEqual(sqrt_f32(0x0.0p0), 0x0.0p0);
603 try std.testing.expectEqual(sqrt_f32(-0x0.0p0), -0x0.0p0);
589604 // 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);
591606 // sqrt(4)=2
592 try std.testing.expectEqual(sqrtf(0x1p2), 0x1p1);
607 try std.testing.expectEqual(sqrt_f32(0x1p2), 0x1p1);
593608 // sqrt(x) for x=1, 1±ulp
594 try std.testing.expectEqual(sqrtf(0x1p0), 0x1p0);
595 try std.testing.expectEqual(sqrtf(0x1.000002p0), 0x1p0);
596 try std.testing.expectEqual(sqrtf(0x1.FFFFFEp-1), 0x1.FFFFFEp-1);
609 try std.testing.expectEqual(sqrt_f32(0x1p0), 0x1p0);
610 try std.testing.expectEqual(sqrt_f32(0x1.000002p0), 0x1p0);
611 try std.testing.expectEqual(sqrt_f32(0x1.FFFFFEp-1), 0x1.FFFFFEp-1);
597612 // 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);
599614 // 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);
601616 // 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))));
603618 // 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))));
605620 // sqrt(-ve) is nan
606 try std.testing.expect(math.isNan(sqrtf(-0x1p-149)));
607 try std.testing.expect(math.isNan(sqrtf(-0x1p0)));
608 try std.testing.expect(math.isNan(sqrtf(-math.inf(f32))));
621 try std.testing.expect(math.isNan(sqrt_f32(-0x1p-149)));
622 try std.testing.expect(math.isNan(sqrt_f32(-0x1p0)));
623 try std.testing.expect(math.isNan(sqrt_f32(-math.inf(f32))));
609624 // random arguments
610 try std.testing.expectEqual(sqrtf(0x1.4DD57Ep77), 0x1.9D6DA8p38);
611 try std.testing.expectEqual(sqrtf(0x1.871848p102), 0x1.3C6AFAp51);
612 try std.testing.expectEqual(sqrtf(0x1.A1D748p-112), 0x1.470EFCp-56);
613 try std.testing.expectEqual(sqrtf(0x1.E626C2p18), 0x1.60C80Ep9);
614 try std.testing.expectEqual(sqrtf(0x1.E80E66p-29), 0x1.F3E282p-15);
615 try std.testing.expectEqual(sqrtf(0x1.B47204p89), 0x1.D8B732p44);
616 try std.testing.expectEqual(sqrtf(0x1.77F45p15), 0x1.B6BC3Ap7);
617 try std.testing.expectEqual(sqrtf(0x1.AD5F5p-48), 0x1.4B8A72p-24);
618 try std.testing.expectEqual(sqrtf(0x1.91A39p-76), 0x1.40A7A8p-38);
619 try std.testing.expectEqual(sqrtf(0x1.DAE088p79), 0x1.ED16DCp39);
625 try std.testing.expectEqual(sqrt_f32(0x1.4DD57Ep77), 0x1.9D6DA8p38);
626 try std.testing.expectEqual(sqrt_f32(0x1.871848p102), 0x1.3C6AFAp51);
627 try std.testing.expectEqual(sqrt_f32(0x1.A1D748p-112), 0x1.470EFCp-56);
628 try std.testing.expectEqual(sqrt_f32(0x1.E626C2p18), 0x1.60C80Ep9);
629 try std.testing.expectEqual(sqrt_f32(0x1.E80E66p-29), 0x1.F3E282p-15);
630 try std.testing.expectEqual(sqrt_f32(0x1.B47204p89), 0x1.D8B732p44);
631 try std.testing.expectEqual(sqrt_f32(0x1.77F45p15), 0x1.B6BC3Ap7);
632 try std.testing.expectEqual(sqrt_f32(0x1.AD5F5p-48), 0x1.4B8A72p-24);
633 try std.testing.expectEqual(sqrt_f32(0x1.91A39p-76), 0x1.40A7A8p-38);
634 try std.testing.expectEqual(sqrt_f32(0x1.DAE088p79), 0x1.ED16DCp39);
620635}
621636
622test "sqrt" {
637test "sqrt_f64" {
623638 // sqrt(±0) is ±0
624 try std.testing.expectEqual(sqrt(0x0.0p0), 0x0.0p0);
625 try std.testing.expectEqual(sqrt(-0x0.0p0), -0x0.0p0);
639 try std.testing.expectEqual(sqrt_f64(0x0.0p0), 0x0.0p0);
640 try std.testing.expectEqual(sqrt_f64(-0x0.0p0), -0x0.0p0);
626641 // 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);
628643 // sqrt(4)=2
629 try std.testing.expectEqual(sqrt(0x1p2), 0x1p1);
644 try std.testing.expectEqual(sqrt_f64(0x1p2), 0x1p1);
630645 // sqrt(x) for x=1, 1±ulp
631 try std.testing.expectEqual(sqrt(0x1p0), 0x1p0);
632 try std.testing.expectEqual(sqrt(0x1p0 + math.floatEps(f64)), 0x1p0);
633 try std.testing.expectEqual(sqrt(0x1p0 - math.floatEps(f64)), 0x1.FFFFFFFFFFFFFp-1);
646 try std.testing.expectEqual(sqrt_f64(0x1p0), 0x1p0);
647 try std.testing.expectEqual(sqrt_f64(0x1p0 + math.floatEps(f64)), 0x1p0);
648 try std.testing.expectEqual(sqrt_f64(0x1p0 - math.floatEps(f64)), 0x1.FFFFFFFFFFFFFp-1);
634649 // 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);
636651 // 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);
638653 // 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))));
640655 // 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))));
642657 // sqrt(-ve) is nan
643 try std.testing.expect(math.isNan(sqrt(-0x1p-1074)));
644 try std.testing.expect(math.isNan(sqrt(-0x1p0)));
645 try std.testing.expect(math.isNan(sqrt(-math.inf(f64))));
658 try std.testing.expect(math.isNan(sqrt_f64(-0x1p-1074)));
659 try std.testing.expect(math.isNan(sqrt_f64(-0x1p0)));
660 try std.testing.expect(math.isNan(sqrt_f64(-math.inf(f64))));
646661 // random arguments
647 try std.testing.expectEqual(sqrt(0x1.27D3510D4789Bp471), 0x1.852E97E58CFB7p235);
648 try std.testing.expectEqual(sqrt(0x1.8C4FCD5A07846p791), 0x1.C27504E56D938p395);
649 try std.testing.expectEqual(sqrt(0x1.B1B69324F96E7p-137), 0x1.D73BD0414D8BFp-69);
650 try std.testing.expectEqual(sqrt(0x1.1CBD179A811FEp278), 0x1.0DFCB9A114A61p139);
651 try std.testing.expectEqual(sqrt(0x1.1D0C7EFB04A56p917), 0x1.7E0708A25DDCDp458);
652 try std.testing.expectEqual(sqrt(0x1.21B355DA8C94Bp-249), 0x1.8121CBE2608E3p-125);
653 try std.testing.expectEqual(sqrt(0x1.63024D4C5E987p487), 0x1.AA56AEA589DCDp243);
654 try std.testing.expectEqual(sqrt(0x1.45AC3BE941F6Ep339), 0x1.9857F3F453E2Dp169);
655 try std.testing.expectEqual(sqrt(0x1.3B719C733AA24p267), 0x1.91E12E3AC8F71p133);
656 try std.testing.expectEqual(sqrt(0x1.0B150433A2275p357), 0x1.71CAB87F8277Cp178);
662 try std.testing.expectEqual(sqrt_f64(0x1.27D3510D4789Bp471), 0x1.852E97E58CFB7p235);
663 try std.testing.expectEqual(sqrt_f64(0x1.8C4FCD5A07846p791), 0x1.C27504E56D938p395);
664 try std.testing.expectEqual(sqrt_f64(0x1.B1B69324F96E7p-137), 0x1.D73BD0414D8BFp-69);
665 try std.testing.expectEqual(sqrt_f64(0x1.1CBD179A811FEp278), 0x1.0DFCB9A114A61p139);
666 try std.testing.expectEqual(sqrt_f64(0x1.1D0C7EFB04A56p917), 0x1.7E0708A25DDCDp458);
667 try std.testing.expectEqual(sqrt_f64(0x1.21B355DA8C94Bp-249), 0x1.8121CBE2608E3p-125);
668 try std.testing.expectEqual(sqrt_f64(0x1.63024D4C5E987p487), 0x1.AA56AEA589DCDp243);
669 try std.testing.expectEqual(sqrt_f64(0x1.45AC3BE941F6Ep339), 0x1.9857F3F453E2Dp169);
670 try std.testing.expectEqual(sqrt_f64(0x1.3B719C733AA24p267), 0x1.91E12E3AC8F71p133);
671 try std.testing.expectEqual(sqrt_f64(0x1.0B150433A2275p357), 0x1.71CAB87F8277Cp178);
657672}
658673
659674test "__sqrtx" {
660675 // sqrt(±0) is ±0
661 try std.testing.expectEqual(__sqrtx(0x0.0p0), 0x0.0p0);
662 try std.testing.expectEqual(__sqrtx(-0x0.0p0), -0x0.0p0);
676 try std.testing.expectEqual(sqrt_f80(0x0.0p0), 0x0.0p0);
677 try std.testing.expectEqual(sqrt_f80(-0x0.0p0), -0x0.0p0);
663678 // 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);
665680 // sqrt(4)=2
666 try std.testing.expectEqual(__sqrtx(0x1p2), 0x1p1);
681 try std.testing.expectEqual(sqrt_f80(0x1p2), 0x1p1);
667682 // sqrt(x) for x=1, 1±ulp
668 try std.testing.expectEqual(__sqrtx(0x1p0), 0x1p0);
669 try std.testing.expectEqual(__sqrtx(0x1p0 + math.floatEps(f80)), 0x1p0);
670 try std.testing.expectEqual(__sqrtx(0x1p0 - math.floatEps(f80)), 0x1.FFFFFFFFFFFFFFFEp-1);
683 try std.testing.expectEqual(sqrt_f80(0x1p0), 0x1p0);
684 try std.testing.expectEqual(sqrt_f80(0x1p0 + math.floatEps(f80)), 0x1p0);
685 try std.testing.expectEqual(sqrt_f80(0x1p0 - math.floatEps(f80)), 0x1.FFFFFFFFFFFFFFFEp-1);
671686 // 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);
673688 // 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);
675690 // 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))));
677692 // 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))));
679694 // sqrt(-ve) is nan
680 try std.testing.expect(math.isNan(__sqrtx(-0x1p-16442)));
681 try std.testing.expect(math.isNan(__sqrtx(-0x1p0)));
682 try std.testing.expect(math.isNan(__sqrtx(-math.inf(f80))));
695 try std.testing.expect(math.isNan(sqrt_f80(-0x1p-16442)));
696 try std.testing.expect(math.isNan(sqrt_f80(-0x1p0)));
697 try std.testing.expect(math.isNan(sqrt_f80(-math.inf(f80))));
683698 // random arguments
684 try std.testing.expectEqual(__sqrtx(0x1.087F3953486918A4p15482), 0x1.0436BBE03D02F32p7741);
685 try std.testing.expectEqual(__sqrtx(0x1.530CF9E2AE84D8Fp-6330), 0x1.269CFEF51933BE58p-3165);
686 try std.testing.expectEqual(__sqrtx(0x1.3F971515EADD574Ap5713), 0x1.9483232AB780B006p2856);
687 try std.testing.expectEqual(__sqrtx(0x1.4CC0DC7379222954p864), 0x1.23DD4D0A4758C2Cp432);
688 try std.testing.expectEqual(__sqrtx(0x1.920E5649559A839Ep-3181), 0x1.C5B5BC0F98DD83D2p-1591);
689 try std.testing.expectEqual(__sqrtx(0x1.2E59726F87CD1746p-629), 0x1.8973327E95CB350Cp-315);
690 try std.testing.expectEqual(__sqrtx(0x1.D3A16391F57B4D64p-9034), 0x1.59FF08B7DEEF5DB2p-4517);
691 try std.testing.expectEqual(__sqrtx(0x1.E7053D8DAA49BCEEp-11411), 0x1.F35AA3EA5E18E344p-5706);
692 try std.testing.expectEqual(__sqrtx(0x1.797ED0B05DD4A984p7521), 0x1.B7A22E40C6A7867Ap3760);
693 try std.testing.expectEqual(__sqrtx(0x1.FC50806445C7226Ap15371), 0x1.FE2766142653F5BEp7685);
699 try std.testing.expectEqual(sqrt_f80(0x1.087F3953486918A4p15482), 0x1.0436BBE03D02F32p7741);
700 try std.testing.expectEqual(sqrt_f80(0x1.530CF9E2AE84D8Fp-6330), 0x1.269CFEF51933BE58p-3165);
701 try std.testing.expectEqual(sqrt_f80(0x1.3F971515EADD574Ap5713), 0x1.9483232AB780B006p2856);
702 try std.testing.expectEqual(sqrt_f80(0x1.4CC0DC7379222954p864), 0x1.23DD4D0A4758C2Cp432);
703 try std.testing.expectEqual(sqrt_f80(0x1.920E5649559A839Ep-3181), 0x1.C5B5BC0F98DD83D2p-1591);
704 try std.testing.expectEqual(sqrt_f80(0x1.2E59726F87CD1746p-629), 0x1.8973327E95CB350Cp-315);
705 try std.testing.expectEqual(sqrt_f80(0x1.D3A16391F57B4D64p-9034), 0x1.59FF08B7DEEF5DB2p-4517);
706 try std.testing.expectEqual(sqrt_f80(0x1.E7053D8DAA49BCEEp-11411), 0x1.F35AA3EA5E18E344p-5706);
707 try std.testing.expectEqual(sqrt_f80(0x1.797ED0B05DD4A984p7521), 0x1.B7A22E40C6A7867Ap3760);
708 try std.testing.expectEqual(sqrt_f80(0x1.FC50806445C7226Ap15371), 0x1.FE2766142653F5BEp7685);
694709}
695710
696test "sqrtq" {
711test "sqrt_f128" {
697712 // sqrt(±0) is ±0
698 try std.testing.expectEqual(sqrtq(0x0.0p0), 0x0.0p0);
699 try std.testing.expectEqual(sqrtq(-0x0.0p0), -0x0.0p0);
713 try std.testing.expectEqual(sqrt_f128(0x0.0p0), 0x0.0p0);
714 try std.testing.expectEqual(sqrt_f128(-0x0.0p0), -0x0.0p0);
700715 // 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);
702717 // sqrt(4)=2
703 try std.testing.expectEqual(sqrtq(0x1p2), 0x1p1);
718 try std.testing.expectEqual(sqrt_f128(0x1p2), 0x1p1);
704719 // sqrt(x) for x=1, 1±ulp
705 try std.testing.expectEqual(sqrtq(0x1p0), 0x1p0);
706 try std.testing.expectEqual(sqrtq(0x1p0 + math.floatEps(f128)), 0x1p0);
707 try std.testing.expectEqual(sqrtq(0x1p0 - math.floatEps(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp-1);
720 try std.testing.expectEqual(sqrt_f128(0x1p0), 0x1p0);
721 try std.testing.expectEqual(sqrt_f128(0x1p0 + math.floatEps(f128)), 0x1p0);
722 try std.testing.expectEqual(sqrt_f128(0x1p0 - math.floatEps(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp-1);
708723 // 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);
710725 // 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);
712727 // 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))));
714729 // 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))));
716731 // sqrt(-ve) is nan
717 try std.testing.expect(math.isNan(sqrtq(-0x1p-16442)));
718 try std.testing.expect(math.isNan(sqrtq(-0x1p0)));
719 try std.testing.expect(math.isNan(sqrtq(-math.inf(f128))));
732 try std.testing.expect(math.isNan(sqrt_f128(-0x1p-16442)));
733 try std.testing.expect(math.isNan(sqrt_f128(-0x1p0)));
734 try std.testing.expect(math.isNan(sqrt_f128(-math.inf(f128))));
720735 // random arguments
721 try std.testing.expectEqual(sqrtq(0x1.B6942D29A331751600C9F3AF7E5Fp3363), 0x1.D9DE9AFEF0F2D25586A50CA39D4Dp1681);
722 try std.testing.expectEqual(sqrtq(0x1.5E65C405F84D471A8070ADD7A42Dp11765), 0x1.A78F7F9452B4D9EC2403C81D9D42p5882);
723 try std.testing.expectEqual(sqrtq(0x1.B42334D68F8016D8AE6F5E22B044p-5624), 0x1.4E247A7F2FF2A325E9377BB09C8p-2812);
724 try std.testing.expectEqual(sqrtq(0x1.E61715047F80F2E0B9382B38E06Bp10062), 0x1.60C25D9DFDC0116B78EF5AFDE0E9p5031);
725 try std.testing.expectEqual(sqrtq(0x1.2ED0B53B494CB55A7B04E653D40Ep-1026), 0x1.166CE78D658D2453D700B04C5748p-513);
726 try std.testing.expectEqual(sqrtq(0x1.1BA756B9790E78A4E6F0B083AA89p1835), 0x1.7D1767EA3303DB7A46940033988p917);
727 try std.testing.expectEqual(sqrtq(0x1.5B6C574319C1120335C8E1609704p4512), 0x1.2A3A8A415BB1648C548FBA2A4182p2256);
728 try std.testing.expectEqual(sqrtq(0x1.FF91E8CDEE1552A2B74E77B602Ep14953), 0x1.FFC8F171267D4FE75CBE7AB4D851p7476);
729 try std.testing.expectEqual(sqrtq(0x1.9B1837CFC629A1B6B1BB97099E7Dp2892), 0x1.4468511B909EAF8641BD59105A6Bp1446);
730 try std.testing.expectEqual(sqrtq(0x1.0E2115475E64A92340914E7F7B37p-13951), 0x1.73E536F82F414134012F55BA5368p-6976);
736 try std.testing.expectEqual(sqrt_f128(0x1.B6942D29A331751600C9F3AF7E5Fp3363), 0x1.D9DE9AFEF0F2D25586A50CA39D4Dp1681);
737 try std.testing.expectEqual(sqrt_f128(0x1.5E65C405F84D471A8070ADD7A42Dp11765), 0x1.A78F7F9452B4D9EC2403C81D9D42p5882);
738 try std.testing.expectEqual(sqrt_f128(0x1.B42334D68F8016D8AE6F5E22B044p-5624), 0x1.4E247A7F2FF2A325E9377BB09C8p-2812);
739 try std.testing.expectEqual(sqrt_f128(0x1.E61715047F80F2E0B9382B38E06Bp10062), 0x1.60C25D9DFDC0116B78EF5AFDE0E9p5031);
740 try std.testing.expectEqual(sqrt_f128(0x1.2ED0B53B494CB55A7B04E653D40Ep-1026), 0x1.166CE78D658D2453D700B04C5748p-513);
741 try std.testing.expectEqual(sqrt_f128(0x1.1BA756B9790E78A4E6F0B083AA89p1835), 0x1.7D1767EA3303DB7A46940033988p917);
742 try std.testing.expectEqual(sqrt_f128(0x1.5B6C574319C1120335C8E1609704p4512), 0x1.2A3A8A415BB1648C548FBA2A4182p2256);
743 try std.testing.expectEqual(sqrt_f128(0x1.FF91E8CDEE1552A2B74E77B602Ep14953), 0x1.FFC8F171267D4FE75CBE7AB4D851p7476);
744 try std.testing.expectEqual(sqrt_f128(0x1.9B1837CFC629A1B6B1BB97099E7Dp2892), 0x1.4468511B909EAF8641BD59105A6Bp1446);
745 try std.testing.expectEqual(sqrt_f128(0x1.0E2115475E64A92340914E7F7B37p-13951), 0x1.73E536F82F414134012F55BA5368p-6976);
731746}
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 @@
1const symbol = @import("../compiler_rt.zig").symbol;
21const testing = @import("std").testing;
2const compiler_rt = @import("../compiler_rt.zig");
3const symbol = compiler_rt.symbol;
34
45comptime {
56 symbol(&__subvdi3, "__subvdi3");
......@@ -9,7 +10,7 @@ pub fn __subvdi3(a: i64, b: i64) callconv(.c) i64 {
910 const sum = a -% b;
1011 // Overflow occurred iff the operands have opposite signs, and the sign of the
1112 // 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");
1314 return sum;
1415}
1516
lib/compiler_rt/subvsi3.zig+1-1
......@@ -10,7 +10,7 @@ pub fn __subvsi3(a: i32, b: i32) callconv(.c) i32 {
1010 const sum = a -% b;
1111 // Overflow occurred iff the operands have opposite signs, and the sign of the
1212 // 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");
1414 return sum;
1515}
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;
2121
2222const arch = builtin.cpu.arch;
2323const compiler_rt = @import("../compiler_rt.zig");
24const symbol = @import("../compiler_rt.zig").symbol;
24const symbol = compiler_rt.symbol;
2525
2626comptime {
27 symbol(&tanh, "__tanh");
27 symbol(&__tanh, "__tanh");
2828 symbol(&tanf, "tanf");
2929 symbol(&tan, "tan");
30 symbol(&tanx, "__tanx");
30 symbol(&__tanx, "__tanx");
3131 if (compiler_rt.want_ppc_abi) {
3232 symbol(&tanq, "tanf128");
3333 }
......@@ -35,12 +35,18 @@ comptime {
3535 symbol(&tanl, "tanl");
3636}
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 {
3942 // TODO: more efficient implementation
40 return @floatCast(tanf(x));
43 return @floatCast(tan_f32(x));
4144}
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 {
4450 // Small multiples of pi/2 rounded to double precision.
4551 const t1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18
4652 const t2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18
......@@ -90,7 +96,10 @@ pub fn tanf(x: f32) callconv(.c) f32 {
9096 return kernel.tandf(y, n & 1 != 0);
9197}
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 {
94103 var ix = @as(u64, @bitCast(x)) >> 32;
95104 ix &= 0x7fffffff;
96105
......@@ -120,7 +129,10 @@ pub fn tan(x: f64) callconv(.c) f64 {
120129 return kernel.tan(y[0], y[1], n & 1 != 0);
121130}
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 {
124136 const se = ld.signExponent(x) & 0x7fff;
125137 if (se == 0x7fff) {
126138 return x - x;
......@@ -141,7 +153,10 @@ pub fn tanx(x: f80) callconv(.c) f80 {
141153 return kernel.tanx(y[0], y[1], n & 1);
142154}
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 {
145160 const se = ld.signExponent(x) & 0x7fff;
146161 if (se == 0x7fff) {
147162 return x - x;
......@@ -164,18 +179,21 @@ pub fn tanq(x: f128) callconv(.c) f128 {
164179
165180pub fn tanl(x: c_longdouble) callconv(.c) c_longdouble {
166181 switch (@typeInfo(c_longdouble).float.bits) {
167 64 => return tan(x),
168 80 => return tanx(x),
169 128 => return tanq(x),
170 else => @compileError("unreachable"),
182 64 => return tan_f64(x),
183 80 => return tan_f80(x),
184 128 => return tan_f128(x),
185 else => comptime unreachable,
171186 }
172187}
173188
174189fn testTanNormal(comptime T: type) !void {
175190 const f = switch (T) {
176 f32 => tanf,
177 f64 => tan,
178 else => @compileError("unimplemented"),
191 f16 => tan_f16,
192 f32 => tan_f32,
193 f64 => tan_f64,
194 f80 => tan_f80,
195 f128 => tan_f128,
196 else => comptime unreachable,
179197 };
180198 const epsilon = 0.00001;
181199
......@@ -189,11 +207,12 @@ fn testTanNormal(comptime T: type) !void {
189207
190208fn testTanSpecial(comptime T: type) !void {
191209 const f = switch (T) {
192 f32 => tanf,
193 f64 => tan,
194 f80 => tanx,
195 f128 => tanq,
196 else => @compileError("unimplemented"),
210 f16 => tan_f16,
211 f32 => tan_f32,
212 f64 => tan_f64,
213 f80 => tan_f80,
214 f128 => tan_f128,
215 else => comptime unreachable,
197216 };
198217
199218 try expect(math.isPositiveZero(f(0.0)));
......@@ -214,23 +233,23 @@ test "tan64.normal" {
214233test "tan80.normal" {
215234 const epsilon = math.floatEps(f80);
216235
217 try expectApproxEqAbs(@as(f80, 0.0), tanx(0.0), epsilon);
218 try expectApproxEqAbs(@as(f80, 0.2027100355086724833213582716475345), tanx(0.2), epsilon);
219 try expectApproxEqAbs(@as(f80, 1.2404217445497097995561220131857544), tanx(0.8923), epsilon);
220 try expectApproxEqAbs(@as(f80, 14.10141994717171938764), tanx(1.5), epsilon);
221 try expectApproxEqAbs(@as(f80, -0.25439607116885656232), tanx(37.45), epsilon);
222 try expectApproxEqAbs(@as(f80, 2.2858376251355320963), tanx(89.123), epsilon);
236 try expectApproxEqAbs(@as(f80, 0.0), tan_f80(0.0), epsilon);
237 try expectApproxEqAbs(@as(f80, 0.2027100355086724833213582716475345), tan_f80(0.2), epsilon);
238 try expectApproxEqAbs(@as(f80, 1.2404217445497097995561220131857544), tan_f80(0.8923), epsilon);
239 try expectApproxEqAbs(@as(f80, 14.10141994717171938764), tan_f80(1.5), epsilon);
240 try expectApproxEqAbs(@as(f80, -0.25439607116885656232), tan_f80(37.45), epsilon);
241 try expectApproxEqAbs(@as(f80, 2.2858376251355320963), tan_f80(89.123), epsilon);
223242}
224243
225244test "tan128.normal" {
226245 const epsilon = math.floatEps(f128);
227246
228 try expectApproxEqAbs(@as(f128, 0.0), tanq(0.0), epsilon);
229 try expectApproxEqAbs(@as(f128, 0.2027100355086724833213582716475345), tanq(0.2), epsilon);
230 try expectApproxEqAbs(@as(f128, 1.2404217445497097995561220131857544), tanq(0.8923), epsilon);
231 try expectApproxEqAbs(@as(f128, 14.101419947171719387646083651987755), tanq(1.5), epsilon);
232 try expectApproxEqAbs(@as(f128, -0.2543960711688565630469573224504774), tanq(37.45), epsilon);
233 try expectApproxEqAbs(@as(f128, 2.2858376251355321074066028114094292), tanq(89.123), epsilon);
247 try expectApproxEqAbs(@as(f128, 0.0), tan_f128(0.0), epsilon);
248 try expectApproxEqAbs(@as(f128, 0.2027100355086724833213582716475345), tan_f128(0.2), epsilon);
249 try expectApproxEqAbs(@as(f128, 1.2404217445497097995561220131857544), tan_f128(0.8923), epsilon);
250 try expectApproxEqAbs(@as(f128, 14.101419947171719387646083651987755), tan_f128(1.5), epsilon);
251 try expectApproxEqAbs(@as(f128, -0.2543960711688565630469573224504774), tan_f128(37.45), epsilon);
252 try expectApproxEqAbs(@as(f128, 2.2858376251355321074066028114094292), tan_f128(89.123), epsilon);
234253}
235254
236255test "tan32.special" {
lib/compiler_rt/trunc.zig+76-43
......@@ -24,12 +24,18 @@ comptime {
2424 symbol(&truncl, "truncl");
2525}
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 {
2831 // TODO: more efficient implementation
29 return @floatCast(truncf(x));
32 return @floatCast(trunc_f32(x));
3033}
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 {
3339 const u: u32 = @bitCast(x);
3440 var e = @as(i32, @intCast(((u >> 23) & 0xFF))) - 0x7F + 9;
3541 var m: u32 = undefined;
......@@ -50,7 +56,10 @@ pub fn truncf(x: f32) callconv(.c) f32 {
5056 }
5157}
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 {
5463 const u: u64 = @bitCast(x);
5564 var e = @as(i32, @intCast(((u >> 52) & 0x7FF))) - 0x3FF + 12;
5665 var m: u64 = undefined;
......@@ -71,12 +80,18 @@ pub fn trunc(x: f64) callconv(.c) f64 {
7180 }
7281}
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 {
7587 // TODO: more efficient implementation
76 return @floatCast(truncq(x));
88 return @floatCast(trunc_f128(x));
7789}
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 {
8095 const u: u128 = @bitCast(x);
8196 var e = @as(i32, @intCast(((u >> 112) & 0x7FFF))) - 0x3FFF + 16;
8297 var m: u128 = undefined;
......@@ -99,51 +114,69 @@ pub fn truncq(x: f128) callconv(.c) f128 {
99114
100115pub fn truncl(x: c_longdouble) callconv(.c) c_longdouble {
101116 switch (@typeInfo(c_longdouble).float.bits) {
102 64 => return trunc(x),
103 80 => return __truncx(x),
104 128 => return truncq(x),
105 else => @compileError("unreachable"),
117 64 => return trunc_f64(x),
118 80 => return trunc_f80(x),
119 128 => return trunc_f128(x),
120 else => comptime unreachable,
106121 }
107122}
108123
109test "trunc32" {
110 try expect(truncf(1.3) == 1.0);
111 try expect(truncf(-1.3) == -1.0);
112 try expect(truncf(0.2) == 0.0);
113}
114
115test "trunc64" {
116 try expect(trunc(1.3) == 1.0);
117 try expect(trunc(-1.3) == -1.0);
118 try expect(trunc(0.2) == 0.0);
124test trunc_f16 {
125 try expect(trunc_f16(1.3) == 1.0);
126 try expect(trunc_f16(-1.3) == -1.0);
127 try expect(math.isPositiveZero(trunc_f16(0.2)));
128 try expect(math.isNegativeZero(trunc_f16(-0.2)));
129 try expect(math.isPositiveZero(trunc_f16(0.0)));
130 try expect(math.isNegativeZero(trunc_f16(-0.0)));
131 try expect(math.isPositiveInf(trunc_f16(math.inf(f32))));
132 try expect(math.isNegativeInf(trunc_f16(-math.inf(f32))));
133 try expect(math.isNan(trunc_f16(math.nan(f32))));
119134}
120135
121test "trunc128" {
122 try expect(truncq(1.3) == 1.0);
123 try expect(truncq(-1.3) == -1.0);
124 try expect(truncq(0.2) == 0.0);
136test trunc_f32 {
137 try expect(trunc_f32(1.3) == 1.0);
138 try expect(trunc_f32(-1.3) == -1.0);
139 try expect(math.isPositiveZero(trunc_f32(0.2)));
140 try expect(math.isNegativeZero(trunc_f32(-0.2)));
141 try expect(math.isPositiveZero(trunc_f32(0.0)));
142 try expect(math.isNegativeZero(trunc_f32(-0.0)));
143 try expect(math.isPositiveInf(trunc_f32(math.inf(f32))));
144 try expect(math.isNegativeInf(trunc_f32(-math.inf(f32))));
145 try expect(math.isNan(trunc_f32(math.nan(f32))));
125146}
126147
127test "trunc32.special" {
128 try expect(truncf(0.0) == 0.0); // 0x3F800000
129 try expect(truncf(-0.0) == -0.0);
130 try expect(math.isPositiveInf(truncf(math.inf(f32))));
131 try expect(math.isNegativeInf(truncf(-math.inf(f32))));
132 try expect(math.isNan(truncf(math.nan(f32))));
148test trunc_f64 {
149 try expect(trunc_f64(1.3) == 1.0);
150 try expect(trunc_f64(-1.3) == -1.0);
151 try expect(math.isPositiveZero(trunc_f64(0.2)));
152 try expect(math.isNegativeZero(trunc_f64(-0.2)));
153 try expect(math.isPositiveZero(trunc_f64(0.0)));
154 try expect(math.isNegativeZero(trunc_f64(-0.0)));
155 try expect(math.isPositiveInf(trunc_f64(math.inf(f64))));
156 try expect(math.isNegativeInf(trunc_f64(-math.inf(f64))));
157 try expect(math.isNan(trunc_f64(math.nan(f64))));
133158}
134159
135test "trunc64.special" {
136 try expect(trunc(0.0) == 0.0);
137 try expect(trunc(-0.0) == -0.0);
138 try expect(math.isPositiveInf(trunc(math.inf(f64))));
139 try expect(math.isNegativeInf(trunc(-math.inf(f64))));
140 try expect(math.isNan(trunc(math.nan(f64))));
160test trunc_f80 {
161 try expect(trunc_f80(1.3) == 1.0);
162 try expect(trunc_f80(-1.3) == -1.0);
163 try expect(math.isPositiveZero(trunc_f80(0.2)));
164 try expect(math.isNegativeZero(trunc_f80(-0.2)));
165 try expect(math.isPositiveZero(trunc_f80(0.0)));
166 try expect(math.isNegativeZero(trunc_f80(-0.0)));
167 try expect(math.isPositiveInf(trunc_f80(math.inf(f64))));
168 try expect(math.isNegativeInf(trunc_f80(-math.inf(f64))));
169 try expect(math.isNan(trunc_f80(math.nan(f64))));
141170}
142171
143test "trunc128.special" {
144 try expect(truncq(0.0) == 0.0);
145 try expect(truncq(-0.0) == -0.0);
146 try expect(math.isPositiveInf(truncq(math.inf(f128))));
147 try expect(math.isNegativeInf(truncq(-math.inf(f128))));
148 try expect(math.isNan(truncq(math.nan(f128))));
172test trunc_f128 {
173 try expect(trunc_f128(1.3) == 1.0);
174 try expect(trunc_f128(-1.3) == -1.0);
175 try expect(math.isPositiveZero(trunc_f128(0.2)));
176 try expect(math.isNegativeZero(trunc_f128(-0.2)));
177 try expect(math.isPositiveZero(trunc_f128(0.0)));
178 try expect(math.isNegativeZero(trunc_f128(-0.0)));
179 try expect(math.isPositiveInf(trunc_f128(math.inf(f128))));
180 try expect(math.isNegativeInf(trunc_f128(-math.inf(f128))));
181 try expect(math.isNan(trunc_f128(math.nan(f128))));
149182}
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 @@
11const 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 {
4202 const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits);
5203 const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits);
6204 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
99297 return @bitCast(result);
100298}
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 {
103301 const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits);
104302 const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit
105303 const dst_sig_bits = std.math.floatMantissaBits(dst_t);
lib/compiler_rt/truncf_test.zig+160-174
......@@ -1,79 +1,82 @@
11const std = @import("std");
22const testing = std.testing;
33
4const __truncsfhf2 = @import("truncsfhf2.zig").__truncsfhf2;
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 }
4const impl = @import("truncf.zig");
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);
2023}
2124
22test "truncsfhf2" {
23 try test__truncsfhf2(0x7fc00000, 0x7e00); // qNaN
24 try test__truncsfhf2(0x7fe00000, 0x7f00); // sNaN
25test f16_floatCast_f32 {
26 try test_f16_floatCast_f32(0x7fc00000, 0x7e00); // qNaN
27 try test_f16_floatCast_f32(0x7fe00000, 0x7f00); // sNaN
2528
26 try test__truncsfhf2(0, 0); // 0
27 try test__truncsfhf2(0x80000000, 0x8000); // -0
29 try test_f16_floatCast_f32(0, 0); // 0
30 try test_f16_floatCast_f32(0x80000000, 0x8000); // -0
2831
29 try test__truncsfhf2(0x7f800000, 0x7c00); // inf
30 try test__truncsfhf2(0xff800000, 0xfc00); // -inf
32 try test_f16_floatCast_f32(0x7f800000, 0x7c00); // inf
33 try test_f16_floatCast_f32(0xff800000, 0xfc00); // -inf
3134
32 try test__truncsfhf2(0x477ff000, 0x7c00); // 65520 -> inf
33 try test__truncsfhf2(0xc77ff000, 0xfc00); // -65520 -> -inf
35 try test_f16_floatCast_f32(0x477ff000, 0x7c00); // 65520 -> inf
36 try test_f16_floatCast_f32(0xc77ff000, 0xfc00); // -65520 -> -inf
3437
35 try test__truncsfhf2(0x71cc3892, 0x7c00); // 0x1.987124876876324p+100 -> inf
36 try test__truncsfhf2(0xf1cc3892, 0xfc00); // -0x1.987124876876324p+100 -> -inf
38 try test_f16_floatCast_f32(0x71cc3892, 0x7c00); // 0x1.987124876876324p+100 -> inf
39 try test_f16_floatCast_f32(0xf1cc3892, 0xfc00); // -0x1.987124876876324p+100 -> -inf
3740
38 try test__truncsfhf2(0x38800000, 0x0400); // normal (min), 2**-14
39 try test__truncsfhf2(0xb8800000, 0x8400); // normal (min), -2**-14
41 try test_f16_floatCast_f32(0x38800000, 0x0400); // normal (min), 2**-14
42 try test_f16_floatCast_f32(0xb8800000, 0x8400); // normal (min), -2**-14
4043
41 try test__truncsfhf2(0x477fe000, 0x7bff); // normal (max), 65504
42 try test__truncsfhf2(0xc77fe000, 0xfbff); // normal (max), -65504
44 try test_f16_floatCast_f32(0x477fe000, 0x7bff); // normal (max), 65504
45 try test_f16_floatCast_f32(0xc77fe000, 0xfbff); // normal (max), -65504
4346
44 try test__truncsfhf2(0x477fe100, 0x7bff); // normal, 65505 -> 65504
45 try test__truncsfhf2(0xc77fe100, 0xfbff); // normal, -65505 -> -65504
47 try test_f16_floatCast_f32(0x477fe100, 0x7bff); // normal, 65505 -> 65504
48 try test_f16_floatCast_f32(0xc77fe100, 0xfbff); // normal, -65505 -> -65504
4649
47 try test__truncsfhf2(0x477fef00, 0x7bff); // normal, 65519 -> 65504
48 try test__truncsfhf2(0xc77fef00, 0xfbff); // normal, -65519 -> -65504
50 try test_f16_floatCast_f32(0x477fef00, 0x7bff); // normal, 65519 -> 65504
51 try test_f16_floatCast_f32(0xc77fef00, 0xfbff); // normal, -65519 -> -65504
4952
50 try test__truncsfhf2(0x3f802000, 0x3c01); // normal, 1 + 2**-10
51 try test__truncsfhf2(0xbf802000, 0xbc01); // normal, -1 - 2**-10
53 try test_f16_floatCast_f32(0x3f802000, 0x3c01); // normal, 1 + 2**-10
54 try test_f16_floatCast_f32(0xbf802000, 0xbc01); // normal, -1 - 2**-10
5255
53 try test__truncsfhf2(0x3eaaa000, 0x3555); // normal, approx. 1/3
54 try test__truncsfhf2(0xbeaaa000, 0xb555); // normal, approx. -1/3
56 try test_f16_floatCast_f32(0x3eaaa000, 0x3555); // normal, approx. 1/3
57 try test_f16_floatCast_f32(0xbeaaa000, 0xb555); // normal, approx. -1/3
5558
56 try test__truncsfhf2(0x40490fdb, 0x4248); // normal, 3.1415926535
57 try test__truncsfhf2(0xc0490fdb, 0xc248); // normal, -3.1415926535
59 try test_f16_floatCast_f32(0x40490fdb, 0x4248); // normal, 3.1415926535
60 try test_f16_floatCast_f32(0xc0490fdb, 0xc248); // normal, -3.1415926535
5861
59 try test__truncsfhf2(0x45cc3892, 0x6e62); // normal, 0x1.987124876876324p+12
62 try test_f16_floatCast_f32(0x45cc3892, 0x6e62); // normal, 0x1.987124876876324p+12
6063
61 try test__truncsfhf2(0x3f800000, 0x3c00); // normal, 1
62 try test__truncsfhf2(0x38800000, 0x0400); // normal, 0x1.0p-14
64 try test_f16_floatCast_f32(0x3f800000, 0x3c00); // normal, 1
65 try test_f16_floatCast_f32(0x38800000, 0x0400); // normal, 0x1.0p-14
6366
64 try test__truncsfhf2(0x33800000, 0x0001); // denormal (min), 2**-24
65 try test__truncsfhf2(0xb3800000, 0x8001); // denormal (min), -2**-24
67 try test_f16_floatCast_f32(0x33800000, 0x0001); // denormal (min), 2**-24
68 try test_f16_floatCast_f32(0xb3800000, 0x8001); // denormal (min), -2**-24
6669
67 try test__truncsfhf2(0x387fc000, 0x03ff); // denormal (max), 2**-14 - 2**-24
68 try test__truncsfhf2(0xb87fc000, 0x83ff); // denormal (max), -2**-14 + 2**-24
70 try test_f16_floatCast_f32(0x387fc000, 0x03ff); // denormal (max), 2**-14 - 2**-24
71 try test_f16_floatCast_f32(0xb87fc000, 0x83ff); // denormal (max), -2**-14 + 2**-24
6972
70 try test__truncsfhf2(0x35800000, 0x0010); // denormal, 0x1.0p-20
71 try test__truncsfhf2(0x33280000, 0x0001); // denormal, 0x1.5p-25 -> 0x1.0p-24
72 try test__truncsfhf2(0x33000000, 0x0000); // 0x1.0p-25 -> zero
73 try test_f16_floatCast_f32(0x35800000, 0x0010); // denormal, 0x1.0p-20
74 try test_f16_floatCast_f32(0x33280000, 0x0001); // denormal, 0x1.5p-25 -> 0x1.0p-24
75 try test_f16_floatCast_f32(0x33000000, 0x0000); // 0x1.0p-25 -> zero
7376}
7477
75fn test__truncdfhf2(a: f64, expected: u16) void {
76 const rep: u16 = @bitCast(__truncdfhf2(a));
78fn test_f16_floatCast_f64(a: f64, expected: u16) !void {
79 const rep: u16 = @bitCast(f16_floatCast_f64(a));
7780
7881 if (rep == expected) {
7982 return;
......@@ -84,62 +87,56 @@ fn test__truncdfhf2(a: f64, expected: u16) void {
8487 return;
8588 }
8689 }
87
88 @panic("__truncdfhf2 test failure");
90 return error.TestFailure;
8991}
9092
91fn test__truncdfhf2_raw(a: u64, expected: u16) void {
92 const actual: u16 = @bitCast(__truncdfhf2(@bitCast(a)));
93
94 if (actual == expected) {
95 return;
96 }
97
98 @panic("__truncdfhf2 test failure");
93fn test_f16_floatCast_f64_raw(a: u64, expected: u16) !void {
94 const actual: u16 = @bitCast(f16_floatCast_f64(@bitCast(a)));
95 try testing.expect(actual == expected);
9996}
10097
101test "truncdfhf2" {
102 test__truncdfhf2_raw(0x7ff8000000000000, 0x7e00); // qNaN
103 test__truncdfhf2_raw(0x7ff0000000008000, 0x7e00); // NaN
98test f16_floatCast_f64 {
99 try test_f16_floatCast_f64_raw(0x7ff8000000000000, 0x7e00); // qNaN
100 try test_f16_floatCast_f64_raw(0x7ff0000000008000, 0x7e00); // NaN
104101
105 test__truncdfhf2_raw(0x7ff0000000000000, 0x7c00); //inf
106 test__truncdfhf2_raw(0xfff0000000000000, 0xfc00); // -inf
102 try test_f16_floatCast_f64_raw(0x7ff0000000000000, 0x7c00); //inf
103 try test_f16_floatCast_f64_raw(0xfff0000000000000, 0xfc00); // -inf
107104
108 test__truncdfhf2(0.0, 0x0); // zero
109 test__truncdfhf2_raw(0x80000000 << 32, 0x8000); // -zero
105 try test_f16_floatCast_f64(0.0, 0x0); // zero
106 try test_f16_floatCast_f64_raw(0x80000000 << 32, 0x8000); // -zero
110107
111 test__truncdfhf2(3.1415926535, 0x4248);
112 test__truncdfhf2(-3.1415926535, 0xc248);
108 try test_f16_floatCast_f64(3.1415926535, 0x4248);
109 try test_f16_floatCast_f64(-3.1415926535, 0xc248);
113110
114 test__truncdfhf2(0x1.987124876876324p+1000, 0x7c00);
115 test__truncdfhf2(0x1.987124876876324p+12, 0x6e62);
116 test__truncdfhf2(0x1.0p+0, 0x3c00);
117 test__truncdfhf2(0x1.0p-14, 0x0400);
111 try test_f16_floatCast_f64(0x1.987124876876324p+1000, 0x7c00);
112 try test_f16_floatCast_f64(0x1.987124876876324p+12, 0x6e62);
113 try test_f16_floatCast_f64(0x1.0p+0, 0x3c00);
114 try test_f16_floatCast_f64(0x1.0p-14, 0x0400);
118115
119116 // denormal
120 test__truncdfhf2(0x1.0p-20, 0x0010);
121 test__truncdfhf2(0x1.0p-24, 0x0001);
122 test__truncdfhf2(-0x1.0p-24, 0x8001);
123 test__truncdfhf2(0x1.5p-25, 0x0001);
117 try test_f16_floatCast_f64(0x1.0p-20, 0x0010);
118 try test_f16_floatCast_f64(0x1.0p-24, 0x0001);
119 try test_f16_floatCast_f64(-0x1.0p-24, 0x8001);
120 try test_f16_floatCast_f64(0x1.5p-25, 0x0001);
124121
125122 // and back to zero
126 test__truncdfhf2(0x1.0p-25, 0x0000);
127 test__truncdfhf2(-0x1.0p-25, 0x8000);
123 try test_f16_floatCast_f64(0x1.0p-25, 0x0000);
124 try test_f16_floatCast_f64(-0x1.0p-25, 0x8000);
128125
129126 // max (precise)
130 test__truncdfhf2(65504.0, 0x7bff);
127 try test_f16_floatCast_f64(65504.0, 0x7bff);
131128
132129 // max (rounded)
133 test__truncdfhf2(65519.0, 0x7bff);
130 try test_f16_floatCast_f64(65519.0, 0x7bff);
134131
135132 // max (to +inf)
136 test__truncdfhf2(65520.0, 0x7c00);
137 test__truncdfhf2(-65520.0, 0xfc00);
138 test__truncdfhf2(65536.0, 0x7c00);
133 try test_f16_floatCast_f64(65520.0, 0x7c00);
134 try test_f16_floatCast_f64(-65520.0, 0xfc00);
135 try test_f16_floatCast_f64(65536.0, 0x7c00);
139136}
140137
141fn test__trunctfsf2(a: f128, expected: u32) void {
142 const x = __trunctfsf2(a);
138fn test_f32_floatCast_f128(a: f128, expected: u32) !void {
139 const x = f32_floatCast_f128(a);
143140
144141 const rep: u32 = @bitCast(x);
145142 if (rep == expected) {
......@@ -151,28 +148,27 @@ fn test__trunctfsf2(a: f128, expected: u32) void {
151148 return;
152149 }
153150 }
154
155 @panic("__trunctfsf2 test failure");
151 return error.TestFailure;
156152}
157153
158test "trunctfsf2" {
154test f32_floatCast_f128 {
159155 // qnan
160 test__trunctfsf2(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7fc00000);
156 try test_f32_floatCast_f128(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7fc00000);
161157 // 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);
163159 // inf
164 test__trunctfsf2(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7f800000);
160 try test_f32_floatCast_f128(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7f800000);
165161 // zero
166 test__trunctfsf2(0.0, 0x0);
162 try test_f32_floatCast_f128(0.0, 0x0);
167163
168 test__trunctfsf2(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x4211d156);
169 test__trunctfsf2(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x3b71e9e2);
170 test__trunctfsf2(0x1.234eebb5faa678f4488693abcdefp+4534, 0x7f800000);
171 test__trunctfsf2(0x1.edcba9bb8c76a5a43dd21f334634p-435, 0x0);
164 try test_f32_floatCast_f128(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x4211d156);
165 try test_f32_floatCast_f128(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x3b71e9e2);
166 try test_f32_floatCast_f128(0x1.234eebb5faa678f4488693abcdefp+4534, 0x7f800000);
167 try test_f32_floatCast_f128(0x1.edcba9bb8c76a5a43dd21f334634p-435, 0x0);
172168}
173169
174fn test__trunctfdf2(a: f128, expected: u64) void {
175 const x = __trunctfdf2(a);
170fn test_f64_floatCast_f128(a: f128, expected: u64) !void {
171 const x = f64_floatCast_f128(a);
176172
177173 const rep: u64 = @bitCast(x);
178174 if (rep == expected) {
......@@ -184,28 +180,27 @@ fn test__trunctfdf2(a: f128, expected: u64) void {
184180 return;
185181 }
186182 }
187
188 @panic("__trunctfsf2 test failure");
183 return error.TestFailure;
189184}
190185
191test "trunctfdf2" {
186test f64_floatCast_f128 {
192187 // qnan
193 test__trunctfdf2(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000);
188 try test_f64_floatCast_f128(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000);
194189 // 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);
196191 // inf
197 test__trunctfdf2(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7ff0000000000000);
192 try test_f64_floatCast_f128(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7ff0000000000000);
198193 // zero
199 test__trunctfdf2(0.0, 0x0);
194 try test_f64_floatCast_f128(0.0, 0x0);
200195
201 test__trunctfdf2(0x1.af23456789bbaaab347645365cdep+5, 0x404af23456789bbb);
202 test__trunctfdf2(0x1.dedafcff354b6ae9758763545432p-9, 0x3f6dedafcff354b7);
203 test__trunctfdf2(0x1.2f34dd5f437e849b4baab754cdefp+4534, 0x7ff0000000000000);
204 test__trunctfdf2(0x1.edcbff8ad76ab5bf46463233214fp-435, 0x24cedcbff8ad76ab);
196 try test_f64_floatCast_f128(0x1.af23456789bbaaab347645365cdep+5, 0x404af23456789bbb);
197 try test_f64_floatCast_f128(0x1.dedafcff354b6ae9758763545432p-9, 0x3f6dedafcff354b7);
198 try test_f64_floatCast_f128(0x1.2f34dd5f437e849b4baab754cdefp+4534, 0x7ff0000000000000);
199 try test_f64_floatCast_f128(0x1.edcbff8ad76ab5bf46463233214fp-435, 0x24cedcbff8ad76ab);
205200}
206201
207fn test__truncdfsf2(a: f64, expected: u32) void {
208 const x = __truncdfsf2(a);
202fn test_f32_floatCast_f64(a: f64, expected: u32) !void {
203 const x = f32_floatCast_f64(a);
209204
210205 const rep: u32 = @bitCast(x);
211206 if (rep == expected) {
......@@ -217,90 +212,81 @@ fn test__truncdfsf2(a: f64, expected: u32) void {
217212 return;
218213 }
219214 }
220
221 std.debug.print("got 0x{x} wanted 0x{x}\n", .{ rep, expected });
222
223 @panic("__trunctfsf2 test failure");
215 return error.TestFailure;
224216}
225217
226test "truncdfsf2" {
218test f32_floatCast_f64 {
227219 // nan & qnan
228 test__truncdfsf2(@bitCast(@as(u64, 0x7ff8000000000000)), 0x7fc00000);
229 test__truncdfsf2(@bitCast(@as(u64, 0x7ff0000000000001)), 0x7fc00000);
220 try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff8000000000000)), 0x7fc00000);
221 try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff0000000000001)), 0x7fc00000);
230222 // inf
231 test__truncdfsf2(@bitCast(@as(u64, 0x7ff0000000000000)), 0x7f800000);
232 test__truncdfsf2(@bitCast(@as(u64, 0xfff0000000000000)), 0xff800000);
223 try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff0000000000000)), 0x7f800000);
224 try test_f32_floatCast_f64(@bitCast(@as(u64, 0xfff0000000000000)), 0xff800000);
233225
234 test__truncdfsf2(0.0, 0x0);
235 test__truncdfsf2(1.0, 0x3f800000);
236 test__truncdfsf2(-1.0, 0xbf800000);
226 try test_f32_floatCast_f64(0.0, 0x0);
227 try test_f32_floatCast_f64(1.0, 0x3f800000);
228 try test_f32_floatCast_f64(-1.0, 0xbf800000);
237229
238230 // huge number becomes inf
239 test__truncdfsf2(340282366920938463463374607431768211456.0, 0x7f800000);
231 try test_f32_floatCast_f64(340282366920938463463374607431768211456.0, 0x7f800000);
240232}
241233
242fn test__trunctfhf2(a: f128, expected: u16) void {
243 const x = __trunctfhf2(a);
234fn test_f16_floatCast_f128(a: f128, expected: u16) !void {
235 const x = f16_floatCast_f128(a);
244236
245237 const rep: u16 = @bitCast(x);
246 if (rep == expected) {
247 return;
248 }
249
250 std.debug.print("got 0x{x} wanted 0x{x}\n", .{ rep, expected });
251
252 @panic("__trunctfhf2 test failure");
238 try testing.expect(rep == expected);
253239}
254240
255test "trunctfhf2" {
241test f16_floatCast_f128 {
256242 // qNaN
257 test__trunctfhf2(@bitCast(@as(u128, 0x7fff8000000000000000000000000000)), 0x7e00);
243 try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff8000000000000000000000000000)), 0x7e00);
258244 // NaN
259 test__trunctfhf2(@bitCast(@as(u128, 0x7fff0000000000000000000000000001)), 0x7e00);
245 try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff0000000000000000000000000001)), 0x7e00);
260246 // inf
261 test__trunctfhf2(@bitCast(@as(u128, 0x7fff0000000000000000000000000000)), 0x7c00);
262 test__trunctfhf2(-@as(f128, @bitCast(@as(u128, 0x7fff0000000000000000000000000000))), 0xfc00);
247 try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff0000000000000000000000000000)), 0x7c00);
248 try test_f16_floatCast_f128(-@as(f128, @bitCast(@as(u128, 0x7fff0000000000000000000000000000))), 0xfc00);
263249 // zero
264 test__trunctfhf2(0.0, 0x0);
265 test__trunctfhf2(-0.0, 0x8000);
266
267 test__trunctfhf2(3.1415926535, 0x4248);
268 test__trunctfhf2(-3.1415926535, 0xc248);
269 test__trunctfhf2(0x1.987124876876324p+100, 0x7c00);
270 test__trunctfhf2(0x1.987124876876324p+12, 0x6e62);
271 test__trunctfhf2(0x1.0p+0, 0x3c00);
272 test__trunctfhf2(0x1.0p-14, 0x0400);
250 try test_f16_floatCast_f128(0.0, 0x0);
251 try test_f16_floatCast_f128(-0.0, 0x8000);
252
253 try test_f16_floatCast_f128(3.1415926535, 0x4248);
254 try test_f16_floatCast_f128(-3.1415926535, 0xc248);
255 try test_f16_floatCast_f128(0x1.987124876876324p+100, 0x7c00);
256 try test_f16_floatCast_f128(0x1.987124876876324p+12, 0x6e62);
257 try test_f16_floatCast_f128(0x1.0p+0, 0x3c00);
258 try test_f16_floatCast_f128(0x1.0p-14, 0x0400);
273259 // denormal
274 test__trunctfhf2(0x1.0p-20, 0x0010);
275 test__trunctfhf2(0x1.0p-24, 0x0001);
276 test__trunctfhf2(-0x1.0p-24, 0x8001);
277 test__trunctfhf2(0x1.5p-25, 0x0001);
260 try test_f16_floatCast_f128(0x1.0p-20, 0x0010);
261 try test_f16_floatCast_f128(0x1.0p-24, 0x0001);
262 try test_f16_floatCast_f128(-0x1.0p-24, 0x8001);
263 try test_f16_floatCast_f128(0x1.5p-25, 0x0001);
278264 // and back to zero
279 test__trunctfhf2(0x1.0p-25, 0x0000);
280 test__trunctfhf2(-0x1.0p-25, 0x8000);
265 try test_f16_floatCast_f128(0x1.0p-25, 0x0000);
266 try test_f16_floatCast_f128(-0x1.0p-25, 0x8000);
281267 // max (precise)
282 test__trunctfhf2(65504.0, 0x7bff);
268 try test_f16_floatCast_f128(65504.0, 0x7bff);
283269 // max (rounded)
284 test__trunctfhf2(65519.0, 0x7bff);
270 try test_f16_floatCast_f128(65519.0, 0x7bff);
285271 // max (to +inf)
286 test__trunctfhf2(65520.0, 0x7c00);
287 test__trunctfhf2(65536.0, 0x7c00);
288 test__trunctfhf2(-65520.0, 0xfc00);
289
290 test__trunctfhf2(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x508f);
291 test__trunctfhf2(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x1b8f);
292 test__trunctfhf2(0x1.234eebb5faa678f4488693abcdefp+453, 0x7c00);
293 test__trunctfhf2(0x1.edcba9bb8c76a5a43dd21f334634p-43, 0x0);
272 try test_f16_floatCast_f128(65520.0, 0x7c00);
273 try test_f16_floatCast_f128(65536.0, 0x7c00);
274 try test_f16_floatCast_f128(-65520.0, 0xfc00);
275
276 try test_f16_floatCast_f128(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x508f);
277 try test_f16_floatCast_f128(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x1b8f);
278 try test_f16_floatCast_f128(0x1.234eebb5faa678f4488693abcdefp+453, 0x7c00);
279 try test_f16_floatCast_f128(0x1.edcba9bb8c76a5a43dd21f334634p-43, 0x0);
294280}
295281
296test "trunctfxf2" {
297 try test__trunctfxf2(1.5, 1.5);
298 try test__trunctfxf2(2.5, 2.5);
299 try test__trunctfxf2(-2.5, -2.5);
300 try test__trunctfxf2(0.0, 0.0);
282fn test_f80_floatCast_f128(a: f128, expected: f80) !void {
283 const x = f80_floatCast_f128(a);
284 try testing.expect(x == expected);
301285}
302286
303fn test__trunctfxf2(a: f128, expected: f80) !void {
304 const x = __trunctfxf2(a);
305 try testing.expect(x == expected);
287test f80_floatCast_f128 {
288 try test_f80_floatCast_f128(1.5, 1.5);
289 try test_f80_floatCast_f128(2.5, 2.5);
290 try test_f80_floatCast_f128(-2.5, -2.5);
291 try test_f80_floatCast_f128(0.0, 0.0);
306292}
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;
66const shl = std.math.shl;
77
88const compiler_rt = @import("../compiler_rt.zig");
9const symbol = @import("../compiler_rt.zig").symbol;
9const symbol = compiler_rt.symbol;
1010
1111const 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 {
12111211 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
12121212 0x00, 0x04, 0x40,
12131213 },
1214 else => @compileError("unreachable"),
1214 else => comptime unreachable,
12151215 };
12161216 em_index -= hash_der.len;
12171217 @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;
7575///
7676/// NaN values are never considered equal to any value.
7777pub 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);
7979 assert(tolerance >= 0);
8080
8181 // 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 {
103103///
104104/// NaN values are never considered equal to any value.
105105pub 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);
107107 assert(tolerance > 0);
108108
109109 // 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" {
252252
253253 try expect(math.isNan(atan2_32(1.0, math.nan(f32))));
254254 try expect(math.isNan(atan2_32(math.nan(f32), 1.0)));
255 try expect(atan2_32(0.0, 5.0) == 0.0);
256 try expect(atan2_32(-0.0, 5.0) == -0.0);
255 try expect(math.isPositiveZero(atan2_32(0.0, 5.0)));
256 try expect(math.isNegativeZero(atan2_32(-0.0, 5.0)));
257257 try expect(math.approxEqAbs(f32, atan2_32(0.0, -5.0), math.pi, epsilon));
258258 //expect(math.approxEqAbs(f32, atan2_32(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero?
259259 try expect(math.approxEqAbs(f32, atan2_32(1.0, 0.0), math.pi / 2.0, epsilon));
......@@ -276,8 +276,8 @@ test "atan2_64.special" {
276276
277277 try expect(math.isNan(atan2_64(1.0, math.nan(f64))));
278278 try expect(math.isNan(atan2_64(math.nan(f64), 1.0)));
279 try expect(atan2_64(0.0, 5.0) == 0.0);
280 try expect(atan2_64(-0.0, 5.0) == -0.0);
279 try expect(math.isPositiveZero(atan2_64(0.0, 5.0)));
280 try expect(math.isNegativeZero(atan2_64(-0.0, 5.0)));
281281 try expect(math.approxEqAbs(f64, atan2_64(0.0, -5.0), math.pi, epsilon));
282282 //expect(math.approxEqAbs(f64, atan2_64(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero?
283283 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 {
527527 };
528528}
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
530544const std = @import("std");
531545const assert = std.debug.assert;
532546const Allocator = std.mem.Allocator;
src/link.zig+1-1
......@@ -2127,7 +2127,7 @@ pub fn resolveInputs(
21272127 continue;
21282128 },
21292129 }
2130 @compileError("unreachable");
2130 comptime unreachable;
21312131 }
21322132
21332133 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" {
18451845 64 => f64,
18461846 80 => f80,
18471847 128 => f128,
1848 else => @compileError("unreachable"),
1848 else => comptime unreachable,
18491849 };
18501850 var f1: F = 12.34;
18511851 const f2: *c_longdouble = &f1;
test/behavior/floatop.zig+4-4
......@@ -431,9 +431,9 @@ fn testSqrt(comptime T: type) !void {
431431 var inf: T = math.inf(T);
432432 try expect(math.isPositiveInf(@sqrt(inf)));
433433 var zero: T = 0.0;
434 try expect(@sqrt(zero) == 0.0);
434 try expect(math.isPositiveZero(@sqrt(zero)));
435435 var neg_zero: T = -0.0;
436 try expect(@sqrt(neg_zero) == 0.0);
436 try expect(math.isNegativeZero(@sqrt(neg_zero)));
437437 var neg_one: T = -1.0;
438438 try expect(math.isNan(@sqrt(neg_one)));
439439 var nan: T = math.nan(T);
......@@ -1501,9 +1501,9 @@ fn testNeg(comptime T: type) !void {
15011501
15021502 // subnormals
15031503 var zero: T = 0.0;
1504 try expect(-zero == -0.0);
1504 try expect(math.isNegativeZero(-zero));
15051505 var neg_zero: T = -0.0;
1506 try expect(-neg_zero == 0.0);
1506 try expect(math.isPositiveZero(-neg_zero));
15071507 var true_min: T = math.floatTrueMin(T);
15081508 try expect(-true_min == -math.floatTrueMin(T));
15091509 var neg_true_min: T = -math.floatTrueMin(T);
test/behavior/switch.zig+1-1
......@@ -1267,7 +1267,7 @@ test "switch with complex item expressions" {
12671267test "switch evaluation order" {
12681268 const eu: anyerror!u32 = 0;
12691269 _ = eu catch |err| switch (err) {
1270 if (true) @compileError("unreachable") => unreachable,
1270 if (true) comptime unreachable => unreachable,
12711271 else => unreachable,
12721272 };
12731273}
test/behavior/switch_on_captured_error.zig+3-3
......@@ -243,7 +243,7 @@ test "switch on error union catch capture" {
243243 var a: error{}!u64 = 0;
244244 _ = &a;
245245 const b = a catch |err| switch (err) {
246 undefined => @compileError("unreachable"),
246 undefined => comptime unreachable,
247247 };
248248 try expectEqual(@as(u64, 0), b);
249249 }
......@@ -829,7 +829,7 @@ test "switch on error union if else capture" {
829829 var a: error{}!u64 = 0;
830830 _ = &a;
831831 const b = if (a) |x| x else |err| switch (err) {
832 undefined => @compileError("unreachable"),
832 undefined => comptime unreachable,
833833 };
834834 try expectEqual(@as(u64, 0), b);
835835 }
......@@ -840,7 +840,7 @@ test "switch on error union if else capture" {
840840 var a: error{}!u64 = 0;
841841 _ = &a;
842842 const b = if (a) |*x| x.* else |err| switch (err) {
843 undefined => @compileError("unreachable"),
843 undefined => comptime unreachable,
844844 };
845845 try expectEqual(@as(u64, 0), b);
846846 }