authorgravatar for jan.hafer@rwth-aachen.deJan Philipp Hafer <jan.hafer@rwth-aachen.de> 2023-10-21 11:12:02+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-10-21 02:12:02-07:00
logf335d92b28e02f8c3efa2f814e72966e0c53565f
tree6cc3eb7472c217de7827c36c85854a194fdd2a87
parenta5c79c79983739630d7269f8583525d83ba9677b
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

compiler_rt: arm frsub, drsub with tests (#17629)

Tests with +-0, numbers with accuracy 0.001, 0.000001, +-max for inf.

1 files changed, 64 insertions(+), 2 deletions(-)

lib/compiler_rt/arm.zig+64-2
......@@ -40,7 +40,8 @@ comptime {
4040 @export(__aeabi_read_tp, .{ .name = "__aeabi_read_tp", .linkage = common.linkage, .visibility = common.visibility });
4141 }
4242
43 // floating-point helper functions (double-precision reverse subtraction, y – x), see subdf3.zig
43 // floating-point helper functions (single+double-precision reverse subtraction, y – x), see subdf3.zig
44 @export(__aeabi_frsub, .{ .name = "__aeabi_frsub", .linkage = common.linkage, .visibility = common.visibility });
4445 @export(__aeabi_drsub, .{ .name = "__aeabi_drsub", .linkage = common.linkage, .visibility = common.visibility });
4546 }
4647 }
......@@ -191,7 +192,68 @@ pub fn __aeabi_ldivmod() callconv(.Naked) void {
191192 unreachable;
192193}
193194
194pub fn __aeabi_drsub(a: f64, b: f64) callconv(.AAPCS) f64 {
195// Float Arithmetic
196
197fn __aeabi_frsub(a: f32, b: f32) callconv(.AAPCS) f32 {
198 const neg_a: f32 = @bitCast(@as(u32, @bitCast(a)) ^ (@as(u32, 1) << 31));
199 return b + neg_a;
200}
201
202fn __aeabi_drsub(a: f64, b: f64) callconv(.AAPCS) f64 {
195203 const neg_a: f64 = @bitCast(@as(u64, @bitCast(a)) ^ (@as(u64, 1) << 63));
196204 return b + neg_a;
197205}
206
207test "__aeabi_frsub" {
208 if (!builtin.cpu.arch.isARM()) return error.SkipZigTest;
209 const inf32 = std.math.inf(f32);
210 const maxf32 = std.math.floatMax(f32);
211 const frsub_data = [_][3]f32{
212 [_]f32{ 0.0, 0.0, -0.0 },
213 [_]f32{ 0.0, -0.0, -0.0 },
214 [_]f32{ -0.0, 0.0, 0.0 },
215 [_]f32{ -0.0, -0.0, -0.0 },
216 [_]f32{ 0.0, 1.0, 1.0 },
217 [_]f32{ 1.0, 0.0, -1.0 },
218 [_]f32{ 1.0, 1.0, 0.0 },
219 [_]f32{ 1234.56789, 9876.54321, 8641.97532 },
220 [_]f32{ 9876.54321, 1234.56789, -8641.97532 },
221 [_]f32{ -8641.97532, 1234.56789, 9876.54321 },
222 [_]f32{ 8641.97532, 9876.54321, 1234.56789 },
223 [_]f32{ -maxf32, -maxf32, 0.0 },
224 [_]f32{ maxf32, maxf32, 0.0 },
225 [_]f32{ maxf32, -maxf32, -inf32 },
226 [_]f32{ -maxf32, maxf32, inf32 },
227 };
228 if (!builtin.cpu.arch.isARM()) return error.SkipZigTest;
229 for (frsub_data) |data| {
230 try std.testing.expectApproxEqAbs(data[2], __aeabi_frsub(data[0], data[1]), 0.001);
231 }
232}
233
234test "__aeabi_drsub" {
235 if (!builtin.cpu.arch.isARM()) return error.SkipZigTest;
236 const inf64 = std.math.inf(f64);
237 const maxf64 = std.math.floatMax(f64);
238 const frsub_data = [_][3]f64{
239 [_]f64{ 0.0, 0.0, -0.0 },
240 [_]f64{ 0.0, -0.0, -0.0 },
241 [_]f64{ -0.0, 0.0, 0.0 },
242 [_]f64{ -0.0, -0.0, -0.0 },
243 [_]f64{ 0.0, 1.0, 1.0 },
244 [_]f64{ 1.0, 0.0, -1.0 },
245 [_]f64{ 1.0, 1.0, 0.0 },
246 [_]f64{ 1234.56789, 9876.54321, 8641.97532 },
247 [_]f64{ 9876.54321, 1234.56789, -8641.97532 },
248 [_]f64{ -8641.97532, 1234.56789, 9876.54321 },
249 [_]f64{ 8641.97532, 9876.54321, 1234.56789 },
250 [_]f64{ -maxf64, -maxf64, 0.0 },
251 [_]f64{ maxf64, maxf64, 0.0 },
252 [_]f64{ maxf64, -maxf64, -inf64 },
253 [_]f64{ -maxf64, maxf64, inf64 },
254 };
255 if (!builtin.cpu.arch.isARM()) return error.SkipZigTest;
256 for (frsub_data) |data| {
257 try std.testing.expectApproxEqAbs(data[2], __aeabi_drsub(data[0], data[1]), 0.000001);
258 }
259}