Skip to content

Commit 343bbf3

Browse files
ZERICO2005mateoconlechuga
authored andcommitted
Added _fpclassifyf and _isnormalf
1 parent 7eea9f9 commit 343bbf3

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

src/libc/fpclassify.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include <math.h>
2+
#include <stdint.h>
3+
4+
#if 0
5+
6+
/* Portable version */
7+
8+
int _fpclassifyf(float x)
9+
{
10+
return
11+
isnan(x) ? FP_NAN :
12+
isinf(x) ? FP_INFINITE :
13+
(x == 0.0f) ? FP_ZERO :
14+
isnormal(x) ? FP_NORMAL :
15+
FP_SUBNORMAL;
16+
}
17+
18+
#else
19+
20+
/* Bitwise version */
21+
22+
typedef union Float32_Bitwise {
23+
float flt_part;
24+
uint32_t u32_part;
25+
uint24_t u24_part;
26+
} Float32_Bitwise;
27+
28+
#define Float32_Exponent_Mask INT32_C(0x7F800000)
29+
#define Float32_Mantissa_Mask INT32_C(0x007FFFFF)
30+
31+
int _fpclassifyf(float x)
32+
{
33+
Float32_Bitwise x_bin;
34+
x_bin.flt_part = x;
35+
36+
const uint32_t exp_mask = x_bin.u32_part & Float32_Exponent_Mask;
37+
38+
// Both of these compile to the same lto.src as of 2024-Oct-10
39+
#if 1
40+
uint24_t mantissa = x_bin.u24_part;
41+
// bit 23 is part of the exponent, so it must be cleared
42+
mantissa += mantissa;
43+
#else
44+
uint32_t mantissa = x_bin.u32_part & Float32_Mantissa_Mask;
45+
#endif
46+
47+
return (
48+
(exp_mask == 0) ? FP_ZERO :
49+
(exp_mask == Float32_Exponent_Mask) ? FP_INFINITE :
50+
FP_NORMAL
51+
) | (mantissa != 0);
52+
}
53+
54+
#endif
55+
56+
int _fpclassify(double) __attribute__((alias("_fpclassifyf")));

src/libc/include/math.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ extern "C" {
2929
#define FP_ILOGB0 (~__INT_MAX__)
3030
#define FP_ILOGBNAN __INT_MAX__
3131

32+
#define FP_NORMAL 0x1
33+
#define FP_ZERO 0x2
34+
#define FP_SUBNORMAL (FP_NORMAL | FP_ZERO) /* 0x3 */
35+
#define FP_INFINITE 0x4
36+
#define FP_NAN (FP_NORMAL | FP_INFINITE) /* 0x5 */
37+
3238
#define signbit(x) __builtin_signbit(x)
3339
#define isgreater(x, y) __builtin_isgreater(x, y)
3440
#define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
@@ -41,6 +47,7 @@ int _isinff(float n);
4147
int _isnanf(float n);
4248
int _isnormalf(float n);
4349
int _isfinitef(float n);
50+
int _fpclassifyf(float n);
4451

4552
#define isinf(x) ( \
4653
sizeof((x)) == sizeof(float) ? _isinff((x)) : \
@@ -54,6 +61,9 @@ int _isfinitef(float n);
5461
#define isfinite(x) ( \
5562
sizeof((x)) == sizeof(float) ? _isfinitef((x)) : \
5663
1)
64+
#define fpclassify(x) ( \
65+
sizeof((x)) == sizeof(float) ? _fpclassifyf((x)) : \
66+
0)
5767

5868
double acos(double);
5969
float acosf(float);

src/libc/isnormal.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <stdint.h>
2+
#include <math.h>
3+
4+
typedef union Float32_Bitwise {
5+
float flt_part;
6+
uint32_t u32_part;
7+
uint24_t u24_part;
8+
} Float32_Bitwise;
9+
10+
#define Float32_Exponent_Mask INT32_C(0x7F800000)
11+
12+
int _isnormalf(float x)
13+
{
14+
Float32_Bitwise x_bin;
15+
x_bin.flt_part = x;
16+
17+
const int32_t exp_mask = x_bin.u32_part & Float32_Exponent_Mask;
18+
19+
// Check that the exponent isn't all zeros (subnormal) or all ones (nan/inf)
20+
return (exp_mask != 0 && exp_mask != Float32_Exponent_Mask);
21+
}
22+
23+
int _isnormal(double) __attribute__((alias("_isnormalf")));

0 commit comments

Comments
 (0)