Merge pull request #8582 from LemonBoy/more-libc-impl

Improve the libc implementation
This commit is contained in:
Veikka Tuominen 2021-04-20 19:54:16 +03:00 committed by GitHub
commit 2ca26ffde7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -239,7 +239,7 @@ export fn memcmp(vl: ?[*]const u8, vr: ?[*]const u8, n: usize) callconv(.C) isiz
return 0;
}
test "test_memcmp" {
test "memcmp" {
const base_arr = &[_]u8{ 1, 1, 1 };
const arr1 = &[_]u8{ 1, 1, 1 };
const arr2 = &[_]u8{ 1, 0, 1 };
@ -263,7 +263,7 @@ export fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) c
return 0;
}
test "test_bcmp" {
test "bcmp" {
const base_arr = &[_]u8{ 1, 1, 1 };
const arr1 = &[_]u8{ 1, 1, 1 };
const arr2 = &[_]u8{ 1, 0, 1 };
@ -859,6 +859,85 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
return @bitCast(T, ux);
}
test "fmod, fmodf" {
inline for ([_]type{ f32, f64 }) |T| {
const nan_val = math.nan(T);
const inf_val = math.inf(T);
std.testing.expect(isNan(generic_fmod(T, nan_val, 1.0)));
std.testing.expect(isNan(generic_fmod(T, 1.0, nan_val)));
std.testing.expect(isNan(generic_fmod(T, inf_val, 1.0)));
std.testing.expect(isNan(generic_fmod(T, 0.0, 0.0)));
std.testing.expect(isNan(generic_fmod(T, 1.0, 0.0)));
std.testing.expectEqual(@as(T, 0.0), generic_fmod(T, 0.0, 2.0));
std.testing.expectEqual(@as(T, -0.0), generic_fmod(T, -0.0, 2.0));
std.testing.expectEqual(@as(T, -2.0), generic_fmod(T, -32.0, 10.0));
std.testing.expectEqual(@as(T, -2.0), generic_fmod(T, -32.0, -10.0));
std.testing.expectEqual(@as(T, 2.0), generic_fmod(T, 32.0, 10.0));
std.testing.expectEqual(@as(T, 2.0), generic_fmod(T, 32.0, -10.0));
}
}
fn generic_fmin(comptime T: type, x: T, y: T) T {
if (isNan(x))
return y;
if (isNan(y))
return x;
return if (x < y) x else y;
}
export fn fminf(x: f32, y: f32) callconv(.C) f32 {
return generic_fmin(f32, x, y);
}
export fn fmin(x: f64, y: f64) callconv(.C) f64 {
return generic_fmin(f64, x, y);
}
test "fmin, fminf" {
inline for ([_]type{ f32, f64 }) |T| {
const nan_val = math.nan(T);
std.testing.expect(isNan(generic_fmin(T, nan_val, nan_val)));
std.testing.expectEqual(@as(T, 1.0), generic_fmin(T, nan_val, 1.0));
std.testing.expectEqual(@as(T, 1.0), generic_fmin(T, 1.0, nan_val));
std.testing.expectEqual(@as(T, 1.0), generic_fmin(T, 1.0, 10.0));
std.testing.expectEqual(@as(T, -1.0), generic_fmin(T, 1.0, -1.0));
}
}
fn generic_fmax(comptime T: type, x: T, y: T) T {
if (isNan(x))
return y;
if (isNan(y))
return x;
return if (x < y) y else x;
}
export fn fmaxf(x: f32, y: f32) callconv(.C) f32 {
return generic_fmax(f32, x, y);
}
export fn fmax(x: f64, y: f64) callconv(.C) f64 {
return generic_fmax(f64, x, y);
}
test "fmax, fmaxf" {
inline for ([_]type{ f32, f64 }) |T| {
const nan_val = math.nan(T);
std.testing.expect(isNan(generic_fmax(T, nan_val, nan_val)));
std.testing.expectEqual(@as(T, 1.0), generic_fmax(T, nan_val, 1.0));
std.testing.expectEqual(@as(T, 1.0), generic_fmax(T, 1.0, nan_val));
std.testing.expectEqual(@as(T, 10.0), generic_fmax(T, 1.0, 10.0));
std.testing.expectEqual(@as(T, 1.0), generic_fmax(T, 1.0, -1.0));
}
}
// NOTE: The original code is full of implicit signed -> unsigned assumptions and u32 wraparound
// behaviour. Most intermediate i32 values are changed to u32 where appropriate but there are
// potentially some edge cases remaining that are not handled in the same way.
@ -1017,8 +1096,8 @@ test "sqrt special" {
std.testing.expect(std.math.isPositiveInf(sqrt(std.math.inf(f64))));
std.testing.expect(sqrt(0.0) == 0.0);
std.testing.expect(sqrt(-0.0) == -0.0);
std.testing.expect(std.math.isNan(sqrt(-1.0)));
std.testing.expect(std.math.isNan(sqrt(std.math.nan(f64))));
std.testing.expect(isNan(sqrt(-1.0)));
std.testing.expect(isNan(sqrt(std.math.nan(f64))));
}
export fn sqrtf(x: f32) f32 {
@ -1122,6 +1201,6 @@ test "sqrtf special" {
std.testing.expect(std.math.isPositiveInf(sqrtf(std.math.inf(f32))));
std.testing.expect(sqrtf(0.0) == 0.0);
std.testing.expect(sqrtf(-0.0) == -0.0);
std.testing.expect(std.math.isNan(sqrtf(-1.0)));
std.testing.expect(std.math.isNan(sqrtf(std.math.nan(f32))));
std.testing.expect(isNan(sqrtf(-1.0)));
std.testing.expect(isNan(sqrtf(std.math.nan(f32))));
}