This is used in various selftests and will be handy when integrating those with nolibc.
Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de Acked-by: Willy Tarreau w@1wt.eu --- tools/include/nolibc/Makefile | 1 + tools/include/nolibc/math.h | 31 ++++++++++++++++++++++++++++ tools/include/nolibc/nolibc.h | 1 + tools/include/nolibc/stdlib.h | 18 ++++++++++++++++ tools/testing/selftests/nolibc/nolibc-test.c | 2 ++ 5 files changed, 53 insertions(+)
diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile index 4bbe3b7fa2805f356d9a5cc1e4a8ee55b05af746..552e44f5a48211f81c68068b9b99c1dd6e44e9d8 100644 --- a/tools/include/nolibc/Makefile +++ b/tools/include/nolibc/Makefile @@ -35,6 +35,7 @@ all_files := \ fcntl.h \ getopt.h \ limits.h \ + math.h \ nolibc.h \ signal.h \ stackprotector.h \ diff --git a/tools/include/nolibc/math.h b/tools/include/nolibc/math.h new file mode 100644 index 0000000000000000000000000000000000000000..9df823ddd41297436015333d66561f810f101d06 --- /dev/null +++ b/tools/include/nolibc/math.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ +/* + * math definitions for NOLIBC + * Copyright (C) 2025 Thomas Weißschuh thomas.weissschuh@linutronix.de + */ + +/* make sure to include all global symbols */ +#include "nolibc.h" + +#ifndef _NOLIBC_SYS_MATH_H +#define _NOLIBC_SYS_MATH_H + +static __inline__ +double fabs(double x) +{ + return x >= 0 ? x : -x; +} + +static __inline__ +float fabsf(float x) +{ + return x >= 0 ? x : -x; +} + +static __inline__ +long double fabsl(long double x) +{ + return x >= 0 ? x : -x; +} + +#endif /* _NOLIBC_SYS_MATH_H */ diff --git a/tools/include/nolibc/nolibc.h b/tools/include/nolibc/nolibc.h index 3f329feb379c4c808d2e56fbb2b7a6c4b08a7c0d..2207f3d3c5cf92b96150149050f0bde0ed7e7147 100644 --- a/tools/include/nolibc/nolibc.h +++ b/tools/include/nolibc/nolibc.h @@ -115,6 +115,7 @@ #include "dirent.h" #include "fcntl.h" #include "getopt.h" +#include "math.h"
/* Used by programs to avoid std includes */ #define NOLIBC diff --git a/tools/include/nolibc/stdlib.h b/tools/include/nolibc/stdlib.h index 4790298f985c2b0db91ec777140201b7ec869346..5fd99a480f821210212f08d814a4c09c2c804db8 100644 --- a/tools/include/nolibc/stdlib.h +++ b/tools/include/nolibc/stdlib.h @@ -32,6 +32,24 @@ static __attribute__((unused)) char itoa_buffer[21]; * As much as possible, please keep functions alphabetically sorted. */
+static __inline__ +int abs(int j) +{ + return j >= 0 ? j : -j; +} + +static __inline__ +long labs(long j) +{ + return j >= 0 ? j : -j; +} + +static __inline__ +long long llabs(long long j) +{ + return j >= 0 ? j : -j; +} + /* must be exported, as it's used by libgcc for various divide functions */ void abort(void); __attribute__((weak,unused,noreturn,section(".text.nolibc_abort"))) diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c index df1cb3e62564f1fa78c55740f7c2403b8390168f..14a27bc6c83e4fda595b10dc29cf56b63904272a 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1318,6 +1318,8 @@ int run_stdlib(int min, int max) CASE_TEST(tolower_noop); EXPECT_EQ(1, tolower('a'), 'a'); break; CASE_TEST(toupper); EXPECT_EQ(1, toupper('a'), 'A'); break; CASE_TEST(toupper_noop); EXPECT_EQ(1, toupper('A'), 'A'); break; + CASE_TEST(abs); EXPECT_EQ(1, abs(-10), 10); break; + CASE_TEST(abs_noop); EXPECT_EQ(1, abs(10), 10); break;
case __LINE__: return ret; /* must be last */