History

win: math.h: fix fpclassify/signbit/etc - use C instead of broken asm

The asm code cannot currently be used with tcc since tcc doesn't support 't' constraint. Use inline C implementation instead, place it win32/include/tcc/tcc_libm.h, and include it from win32/include/math.h. Since fpclassify now works, it also fixes few other macros which depend on it. Implicitly fixed: isfinite, isinf, isnan, isnormal. The implementations were taken from musl-libc rs-1.0 (MIT license).

Avi Halachmi (:avih) committed 11 years ago

Commit 9c52ba41 parent 6e261a12 files · +97 −22Browse files

Unified · Split

2 files
  1. win32/include/math.h +9 −22
  2. win32/include/tcc/tcc_libm.h +88 −0
win32/include/math.h+9−22
@@ -313,13 +313,9 @@ extern "C" { · 312 unmodified lines
313 313
314 extern int __cdecl __fpclassifyf (float);314 extern int __cdecl __fpclassifyf (float);
315 extern int __cdecl __fpclassify (double);315 extern int __cdecl __fpclassify (double);
316 extern int __cdecl __fpclassifyl (long double);
316 317
317 __CRT_INLINE int __cdecl __fpclassifyl (long double x){318/* Implemented at tcc/tcc_libm.h */
318 unsigned short sw;
319 __asm__ ("fxam; fstsw %%ax;" : "=a" (sw): "t" (x));
320 return sw & (FP_NAN | FP_NORMAL | FP_ZERO );
321 }
322
323#define fpclassify(x) (sizeof (x) == sizeof (float) ? __fpclassifyf (x) \319#define fpclassify(x) (sizeof (x) == sizeof (float) ? __fpclassifyf (x) \
324 : sizeof (x) == sizeof (double) ? __fpclassify (x) \320 : sizeof (x) == sizeof (double) ? __fpclassify (x) \
325 : __fpclassifyl (x))321 : __fpclassifyl (x))
@@ -339,24 +335,12 @@ extern "C" { · 13 unmodified lines
339#define isnormal(x) (fpclassify(x) == FP_NORMAL)335#define isnormal(x) (fpclassify(x) == FP_NORMAL)
340 336
341 /* 7.12.3.6 The signbit macro */337 /* 7.12.3.6 The signbit macro */
342 __CRT_INLINE int __cdecl __signbit (double x) {
343 unsigned short stw;
344 __asm__ ( "fxam; fstsw %%ax;": "=a" (stw) : "t" (x));
345 return stw & 0x0200;
346 }
347 338
348 __CRT_INLINE int __cdecl __signbitf (float x) {339 extern int __cdecl __signbitf (float);
349 unsigned short stw;340 extern int __cdecl __signbit (double);
350 __asm__ ("fxam; fstsw %%ax;": "=a" (stw) : "t" (x));341 extern int __cdecl __signbitl (long double);
351 return stw & 0x0200;
352 }
353
354 __CRT_INLINE int __cdecl __signbitl (long double x) {
355 unsigned short stw;
356 __asm__ ("fxam; fstsw %%ax;": "=a" (stw) : "t" (x));
357 return stw & 0x0200;
358 }
359 342
343/* Implemented at tcc/tcc_libm.h */
360#define signbit(x) (sizeof (x) == sizeof (float) ? __signbitf (x) \344#define signbit(x) (sizeof (x) == sizeof (float) ? __signbitf (x) \
361 : sizeof (x) == sizeof (double) ? __signbit (x) \345 : sizeof (x) == sizeof (double) ? __signbit (x) \
362 : __signbitl (x))346 : __signbitl (x))
@@ -746,5 +730,8 @@ extern "C++" { · 383 unmodified lines
746 * which always returns true: yes, (NaN != NaN) is true).730 * which always returns true: yes, (NaN != NaN) is true).
747 */731 */
748 732
733/* Mini libm (inline __fpclassify*, __signbit* and variants) */
734#include "tcc/tcc_libm.h"
735
749#endif /* End _MATH_H_ */736#endif /* End _MATH_H_ */
750 737
win32/include/tcc/tcc_libm.h+88−0
@@ -0,0 +1,88 @@
1#ifndef _TCC_LIBM_H_
2#define _TCC_LIBM_H_
3
4#include "../include/math.h"
5
6/* TCC uses 8 bytes for double and long double, so effectively the l variants
7 * are never used. For now, they just run the normal (double) variant.
8 */
9
10/*
11 * most of the code in this file is taken from MUSL rs-1.0 (MIT license)
12 * - musl-libc: http://git.musl-libc.org/cgit/musl/tree/src/math?h=rs-1.0
13 * - License: http://git.musl-libc.org/cgit/musl/tree/COPYRIGHT?h=rs-1.0
14 */
15
16/*******************************************************************************
17 Start of code based on MUSL
18*******************************************************************************/
19/*
20musl as a whole is licensed under the following standard MIT license:
21
22----------------------------------------------------------------------
23Copyright � 2005-2014 Rich Felker, et al.
24
25Permission is hereby granted, free of charge, to any person obtaining
26a copy of this software and associated documentation files (the
27"Software"), to deal in the Software without restriction, including
28without limitation the rights to use, copy, modify, merge, publish,
29distribute, sublicense, and/or sell copies of the Software, and to
30permit persons to whom the Software is furnished to do so, subject to
31the following conditions:
32
33The above copyright notice and this permission notice shall be
34included in all copies or substantial portions of the Software.
35
36THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
37EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
38MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
39IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
40CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
41TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
42SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43----------------------------------------------------------------------
44*/
45
46/* fpclassify */
47
48__CRT_INLINE int __cdecl __fpclassify (double x) {
49 union {double f; uint64_t i;} u = {x};
50 int e = u.i>>52 & 0x7ff;
51 if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
52 if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE;
53 return FP_NORMAL;
54}
55
56__CRT_INLINE int __cdecl __fpclassifyf (float x) {
57 union {float f; uint32_t i;} u = {x};
58 int e = u.i>>23 & 0xff;
59 if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
60 if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE;
61 return FP_NORMAL;
62}
63
64__CRT_INLINE int __cdecl __fpclassifyl (long double x) {
65 return __fpclassify(x);
66}
67
68/* signbit */
69
70__CRT_INLINE int __cdecl __signbit (double x) {
71 union {double d; uint64_t i;} y = { x };
72 return y.i>>63;
73}
74
75__CRT_INLINE int __cdecl __signbitf (float x) {
76 union {float f; uint32_t i; } y = { x };
77 return y.i>>31;
78}
79
80__CRT_INLINE int __cdecl __signbitl (long double x) {
81 return __signbit(x);
82}
83
84/*******************************************************************************
85 End of code based on MUSL
86*******************************************************************************/
87
88#endif /* _TCC_LIBM_H_ */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t