Skip to content

Commit c9b82ff

Browse files
committed
Added issignaling and optimized some softfloat routines
1 parent 15fc6b8 commit c9b82ff

File tree

15 files changed

+452
-173
lines changed

15 files changed

+452
-173
lines changed

src/libc/include/__math_def.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,21 @@ extern "C" {
4444
int _fpclassifyf(float) __NOEXCEPT_CONST;
4545
int _fpclassifyl(long double) __NOEXCEPT_CONST;
4646

47-
bool _isinff(float) __NOEXCEPT_CONST;
47+
bool _issignalingf(float) __NOEXCEPT_CONST;
4848
bool _isnanf(float) __NOEXCEPT_CONST;
49-
bool _isnormalf(float) __NOEXCEPT_CONST;
49+
bool _isinff(float) __NOEXCEPT_CONST;
5050
bool _isfinitef(float) __NOEXCEPT_CONST;
51-
bool _iszerof(float) __NOEXCEPT_CONST;
51+
bool _isnormalf(float) __NOEXCEPT_CONST;
5252
bool _issubnormalf(float) __NOEXCEPT_CONST;
53+
bool _iszerof(float) __NOEXCEPT_CONST;
5354

54-
bool _isinfl(long double) __NOEXCEPT_CONST;
55+
bool _issignalingl(long double) __NOEXCEPT_CONST;
5556
bool _isnanl(long double) __NOEXCEPT_CONST;
56-
bool _isnormall(long double) __NOEXCEPT_CONST;
57+
bool _isinfl(long double) __NOEXCEPT_CONST;
5758
bool _isfinitel(long double) __NOEXCEPT_CONST;
58-
bool _iszerol(long double) __NOEXCEPT_CONST;
59+
bool _isnormall(long double) __NOEXCEPT_CONST;
5960
bool _issubnormall(long double) __NOEXCEPT_CONST;
61+
bool _iszerol(long double) __NOEXCEPT_CONST;
6062

6163
#if 0
6264
/* disabled until builtin is optimized */

src/libc/include/math.h

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121
float: _signbitf \
2222
)(x))
2323

24-
#define isinf(x) ((int)_Generic(__math_promote(x), \
25-
long double: _isinfl, \
26-
default: _isinff, \
27-
float: _isinff \
24+
#define issignaling(x) ((int)_Generic(__math_promote(x), \
25+
long double: _issignalingl, \
26+
default: _issignalingf, \
27+
float: _issignalingf \
2828
)(x))
2929

3030
#define isnan(x) ((int)_Generic(__math_promote(x), \
@@ -33,10 +33,11 @@
3333
float: _isnanf \
3434
)(x))
3535

36-
#define isnormal(x) ((int)_Generic(__math_promote(x), \
37-
long double: _isnormall, \
38-
default: _isnormalf, \
39-
float: _isnormalf \
36+
37+
#define isinf(x) ((int)_Generic(__math_promote(x), \
38+
long double: _isinfl, \
39+
default: _isinff, \
40+
float: _isinff \
4041
)(x))
4142

4243
#define isfinite(x) ((int)_Generic(__math_promote(x), \
@@ -45,10 +46,10 @@
4546
float: _isfinitef \
4647
)(x))
4748

48-
#define iszero(x) ((int)_Generic(__math_promote(x), \
49-
long double: _iszerol, \
50-
default: _iszerof, \
51-
float: _iszerof \
49+
#define isnormal(x) ((int)_Generic(__math_promote(x), \
50+
long double: _isnormall, \
51+
default: _isnormalf, \
52+
float: _isnormalf \
5253
)(x))
5354

5455
#define issubnormal(x) ((int)_Generic(__math_promote(x), \
@@ -57,6 +58,12 @@
5758
float: _issubnormalf \
5859
)(x))
5960

61+
#define iszero(x) ((int)_Generic(__math_promote(x), \
62+
long double: _iszerol, \
63+
default: _iszerof, \
64+
float: _iszerof \
65+
)(x))
66+
6067
#define fpclassify(x) ((int)_Generic(__math_promote(x), \
6168
long double: _fpclassifyl, \
6269
default: _fpclassifyf, \

src/libc/issignalingf.src

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
assume adl=1
2+
3+
section .text
4+
5+
public __issignalingf
6+
7+
; assumes quiet NaN is 0x7FC00000 or 0xFFC00000
8+
; bool _issignalingf(float)
9+
__issignalingf:
10+
; based off __isnanf, unoptimized
11+
xor a, a
12+
ld iy, 0
13+
add iy, sp
14+
ld hl, (iy + 3)
15+
adc hl, hl
16+
ret z ; infinity
17+
ld a, (iy + 6)
18+
rla
19+
20+
or a, a
21+
adc hl, hl
22+
jr z, .quiet_nan
23+
24+
add a, 1 ; attempt to overflow the exponent
25+
sbc a, a
26+
ret
27+
28+
.quiet_nan:
29+
xor a, a
30+
ret

src/libc/issignalingl.src

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
assume adl=1
2+
3+
section .text
4+
5+
public __issignalingl
6+
7+
; assumes quiet NaN is 0x7FF8000000000000 or 0xFFF8000000000000
8+
; bool _issignalingl(long double)
9+
__issignalingl:
10+
; based off __isnanl, unoptimized
11+
pop bc, hl, de
12+
xor a, a
13+
adc hl, de
14+
pop de
15+
push bc, bc, bc, bc
16+
ld a, e
17+
jr nz, .mant_nonzero ; normal, subnormal, or NaN
18+
jr c, .mant_nonzero ; normal, subnormal, or NaN
19+
; common NaN, inf, normal, or subnormal
20+
; quiet NaN will be along this path
21+
xor a, $F8
22+
ret z ; quiet NaN
23+
xor a, $F8
24+
ret z
25+
dec a
26+
.mant_nonzero:
27+
add a, 16 ; overflows 0xF0
28+
sbc a, a
29+
ret z
30+
ld a, d
31+
add a, a
32+
add a, 2
33+
sbc a, a
34+
ret

src/libcxx/include/cmath

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -34,27 +34,18 @@ template<typename _Tp> inline constexpr
3434
__cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool>
3535
signbit(_Tp __x) { return (__x < 0); }
3636

37-
inline constexpr bool isinf(float __x) {
38-
if (__builtin_constant_p(__x)) {
39-
return __builtin_isinf(__x);
40-
}
41-
return _isinff(__x);
37+
inline constexpr bool issignaling(float __x) {
38+
return _issignalingf(__x);
4239
}
43-
inline constexpr bool isinf(double __x) {
44-
if (__builtin_constant_p(__x)) {
45-
return __builtin_isinf(__x);
46-
}
47-
return _isinff(__x);
40+
inline constexpr bool issignaling(double __x) {
41+
return _issignalingf(__x);
4842
}
49-
inline constexpr bool isinf(long double __x) {
50-
if (__builtin_constant_p(__x)) {
51-
return __builtin_isinf(__x);
52-
}
53-
return _isinfl(__x);
43+
inline constexpr bool issignaling(long double __x) {
44+
return _issignalingl(__x);
5445
}
5546
template<typename _Tp> inline constexpr
5647
__cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool>
57-
isinf(_Tp __x) { return false; }
48+
issignaling(_Tp __x) { return false; }
5849

5950
inline constexpr bool isnan(float __x) {
6051
if (__builtin_constant_p(__x)) {
@@ -78,27 +69,27 @@ template<typename _Tp> inline constexpr
7869
__cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool>
7970
isnan(_Tp __x) { return false; }
8071

81-
inline constexpr bool isnormal(float __x) {
72+
inline constexpr bool isinf(float __x) {
8273
if (__builtin_constant_p(__x)) {
83-
return __builtin_isnormal(__x);
74+
return __builtin_isinf(__x);
8475
}
85-
return _isnormalf(__x);
76+
return _isinff(__x);
8677
}
87-
inline constexpr bool isnormal(double __x) {
78+
inline constexpr bool isinf(double __x) {
8879
if (__builtin_constant_p(__x)) {
89-
return __builtin_isnormal(__x);
80+
return __builtin_isinf(__x);
9081
}
91-
return _isnormalf(__x);
82+
return _isinff(__x);
9283
}
93-
inline constexpr bool isnormal(long double __x) {
84+
inline constexpr bool isinf(long double __x) {
9485
if (__builtin_constant_p(__x)) {
95-
return __builtin_isnormal(__x);
86+
return __builtin_isinf(__x);
9687
}
97-
return _isnormall(__x);
88+
return _isinfl(__x);
9889
}
9990
template<typename _Tp> inline constexpr
10091
__cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool>
101-
isnormal(_Tp __x) { return (__x != 0); }
92+
isinf(_Tp __x) { return false; }
10293

10394
inline constexpr bool isfinite(float __x) {
10495
if (__builtin_constant_p(__x)) {
@@ -122,27 +113,27 @@ template<typename _Tp> inline constexpr
122113
__cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool>
123114
isfinite(_Tp __x) { return true; }
124115

125-
inline constexpr bool iszero(float __x) {
116+
inline constexpr bool isnormal(float __x) {
126117
if (__builtin_constant_p(__x)) {
127-
return (__x == 0.0f);
118+
return __builtin_isnormal(__x);
128119
}
129-
return _iszerof(__x);
120+
return _isnormalf(__x);
130121
}
131-
inline constexpr bool iszero(double __x) {
122+
inline constexpr bool isnormal(double __x) {
132123
if (__builtin_constant_p(__x)) {
133-
return (__x == 0.0);
124+
return __builtin_isnormal(__x);
134125
}
135-
return _iszerof(__x);
126+
return _isnormalf(__x);
136127
}
137-
inline constexpr bool iszero(long double __x) {
128+
inline constexpr bool isnormal(long double __x) {
138129
if (__builtin_constant_p(__x)) {
139-
return (__x == 0.0L);
130+
return __builtin_isnormal(__x);
140131
}
141-
return _iszerol(__x);
132+
return _isnormall(__x);
142133
}
143134
template<typename _Tp> inline constexpr
144135
__cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool>
145-
iszero(_Tp __x) { return (__x == 0); }
136+
isnormal(_Tp __x) { return (__x != 0); }
146137

147138
inline constexpr bool issubnormal(float __x) {
148139
if (__builtin_constant_p(__x)) {
@@ -166,6 +157,28 @@ template<typename _Tp> inline constexpr
166157
__cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool>
167158
issubnormal(_Tp __x) { return false; }
168159

160+
inline constexpr bool iszero(float __x) {
161+
if (__builtin_constant_p(__x)) {
162+
return (__x == 0.0f);
163+
}
164+
return _iszerof(__x);
165+
}
166+
inline constexpr bool iszero(double __x) {
167+
if (__builtin_constant_p(__x)) {
168+
return (__x == 0.0);
169+
}
170+
return _iszerof(__x);
171+
}
172+
inline constexpr bool iszero(long double __x) {
173+
if (__builtin_constant_p(__x)) {
174+
return (__x == 0.0L);
175+
}
176+
return _iszerol(__x);
177+
}
178+
template<typename _Tp> inline constexpr
179+
__cmath_enable_if_t<__cmath_is_integral_v<_Tp>, bool>
180+
iszero(_Tp __x) { return (__x == 0); }
181+
169182
inline constexpr int fpclassify(float __x) {
170183
if (__builtin_constant_p(__x)) {
171184
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, __x);
@@ -801,12 +814,13 @@ trunc(_Tp __x) { return trunc(__x); }
801814
} // namespace std
802815

803816
using std::signbit;
804-
using std::isinf;
817+
using std::issignaling;
805818
using std::isnan;
806-
using std::isnormal;
819+
using std::isinf;
807820
using std::isfinite;
808-
using std::iszero;
821+
using std::isnormal;
809822
using std::issubnormal;
823+
using std::iszero;
810824
using std::fpclassify;
811825

812826
using std::isgreater;

0 commit comments

Comments
 (0)