Mail Archives: djgpp-workers/2003/06/21/10:09:06
Hi.
Here's a patch to add fpclassify to libc.
Note that I kept __attribute((const)) in the texinfo file.
Comments?
Right,
MartinS
Index: djgpp/include/math.h
===================================================================
RCS file: /cvs/djgpp/djgpp/include/math.h,v
retrieving revision 1.8
diff -p -u -r1.8 math.h
--- djgpp/include/math.h 22 Mar 2003 11:59:57 -0000 1.8
+++ djgpp/include/math.h 21 Jun 2003 14:02:53 -0000
@@ -9,6 +9,8 @@
#include <libm/math.h>
#else
+#include <sys/math_def.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -56,6 +58,21 @@ extern long double __dj_huge_vall;
extern float __dj_nan;
#define NAN __dj_nan
+#define fpclassify(x) ((sizeof(x)==sizeof(float))? __fpclassifyf(x) : \
+ (sizeof(x)==sizeof(double))? __fpclassifyd(x) : \
+ __fpclassifyld(x))
+
+#define isfinite(x) (fpclassify(x)==FP_NORMAL || \
+ fpclassify(x)==FP_SUBNORMAL || \
+ fpclassify(x)==FP_ZERO)
+#define isinf(x) (fpclassify(x)==FP_INFINITE)
+#define isnan(x) (fpclassify(x)==FP_NAN)
+#define isnormal(x) (fpclassify(x)==FP_NORMAL)
+
+int __fpclassifyf(float) __attribute((const));
+int __fpclassifyd(double) __attribute((const));
+int __fpclassifyld(long double) __attribute((const));
+
#endif /* (__STDC_VERSION__ >= 199901L) || !__STRICT_ANSI__ */
#ifndef __STRICT_ANSI__
@@ -111,8 +128,6 @@ struct exception {
extern double erf(double);
extern double erfc(double);
extern double gamma(double);
-extern int isinf(double);
-extern int isnan(double);
extern int finite(double);
extern double j0(double);
extern double j1(double);
Index: djgpp/src/libc/c99/math/fpclassd.S
===================================================================
RCS file: djgpp/src/libc/c99/math/fpclassd.S
diff -N djgpp/src/libc/c99/math/fpclassd.S
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ djgpp/src/libc/c99/math/fpclassd.S 21 Jun 2003 14:03:16 -0000
@@ -0,0 +1,59 @@
+/*
+ * File fpclassd.S.
+ *
+ * Copyright (C) 2003 Martin Str@"omberg <ams AT ludd DOT luth DOT se>.
+ *
+ * This software may be used freely so long as this copyright notice is
+ * left intact. There is no warranty on this software.
+ *
+ */
+
+#include <sys/math_def.h>
+
+/*
+ * Bits: 63 (sign), 62-52 (exponent), 51-0 (fraction)
+ * Zero: +/- 0 0
+ * Subnormal +/- 0 !=0
+ * Normal +/- !=0, <0xff any
+ * Infinity: +/- 0xff 0
+ * NaN: any 0xff !=0
+ */
+
+/*
+ * Stack:
+ * 8(%esp): high 32 bits of the double
+ * 4(%esp): low 32 bits of the double
+ * 0(%esp): return address
+ */
+ .globl ___fpclassifyd
+___fpclassifyd:
+ movl 8(%esp), %eax
+ movl %eax, %edx
+ andl $0x7ff00000, %eax
+ jz zero_exponent
+
+ cmpl $0x7ff00000, %eax
+ je all_ones_exponent
+
+ movl $FP_NORMAL, %eax
+ ret
+
+zero_exponent:
+ andl $0xfffff, %edx
+ orl 4(%esp), %edx
+ movl $FP_ZERO, %eax
+ jz zero
+
+ movl $FP_SUBNORMAL, %eax
+zero:
+ ret
+
+all_ones_exponent:
+ andl $0xfffff, %edx
+ orl 4(%esp), %edx
+ movl $FP_INFINITE, %eax
+ jz infinity
+
+ movl $FP_NAN, %eax
+infinity:
+ ret
Index: djgpp/src/libc/c99/math/fpclassd.txh
===================================================================
RCS file: djgpp/src/libc/c99/math/fpclassd.txh
diff -N djgpp/src/libc/c99/math/fpclassd.txh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ djgpp/src/libc/c99/math/fpclassd.txh 21 Jun 2003 14:03:16 -0000
@@ -0,0 +1,43 @@
+@ignore
+ * File fpclassl.txh.
+ *
+ * Copyright (C) 2003 Martin Str@"omberg <ams AT ludd DOT luth DOT se>.
+ *
+ * This software may be used freely so long as this copyright notice is
+ * left intact. There is no warranty on this software.
+ *
+@end ignore
+
+@node __fpclassifyd, math
+@findex __fpclassifyd
+@subheading Syntax
+
+@example
+#include <math.h>
+
+int __fpclassifyd(double) __attribute((const));
+@end example
+
+@subheading Description
+
+Returns the kind of the floating point value supplied. You should use
+the type generic macro @code{fpclassify} instead of this function.
+
+@subheading Return Value
+
+FP_INFINITE, FP_NAN, FP_NORMAL, FP_SUBNORMAL or FP_ZERO.
+
+@subheading Portability
+
+@portability !ansi-c89, ansi-c99
+
+@subheading Example
+
+@example
+if( __fpclassifyf(0.0) != FP_ZERO )
+@{
+ printf("Something is wrong with the implementation!\n");
+@}
+
+@end example
+
Index: djgpp/src/libc/c99/math/fpclassf.S
===================================================================
RCS file: djgpp/src/libc/c99/math/fpclassf.S
diff -N djgpp/src/libc/c99/math/fpclassf.S
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ djgpp/src/libc/c99/math/fpclassf.S 21 Jun 2003 14:03:17 -0000
@@ -0,0 +1,52 @@
+/*
+ * File fpclassf.S.
+ *
+ * Copyright (C) 2003 Martin Str@"omberg <ams AT ludd DOT luth DOT se>.
+ *
+ * This software may be used freely so long as this copyright notice is
+ * left intact. There is no warranty on this software.
+ *
+ */
+
+#include <sys/math_def.h>
+/*#include <math.h>*/
+
+/*
+ * Bits: 31 (sign), 30-23 (exponent), 22-0 (fraction)
+ * Zero: +/- 0 0
+ * Subnormal +/- 0 !=0
+ * Normal +/- !=0, <0xff any
+ * Infinity: +/- 0xff 0
+ * NaN: any 0xff !=0
+ */
+
+ .globl ___fpclassifyf
+___fpclassifyf:
+ movl 4(%esp), %eax
+ movl %eax, %edx
+ andl $0x7f800000, %eax
+ jz zero_exponent
+
+ cmpl $0x7f800000, %eax
+ je all_ones_exponent
+
+ movl $FP_NORMAL, %eax
+ ret
+
+zero_exponent:
+ movl $FP_ZERO, %eax
+ testl $0x7fffff, %edx
+ jz zero
+
+ movl $FP_SUBNORMAL, %eax
+zero:
+ ret
+
+all_ones_exponent:
+ movl $FP_INFINITE, %eax
+ testl $0x7fffff, %edx
+ jz infinity
+
+ movl $FP_NAN, %eax
+infinity:
+ ret
Index: djgpp/src/libc/c99/math/fpclassf.txh
===================================================================
RCS file: djgpp/src/libc/c99/math/fpclassf.txh
diff -N djgpp/src/libc/c99/math/fpclassf.txh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ djgpp/src/libc/c99/math/fpclassf.txh 21 Jun 2003 14:03:17 -0000
@@ -0,0 +1,43 @@
+@ignore
+ * File fpclassl.txh.
+ *
+ * Copyright (C) 2003 Martin Str@"omberg <ams AT ludd DOT luth DOT se>.
+ *
+ * This software may be used freely so long as this copyright notice is
+ * left intact. There is no warranty on this software.
+ *
+@end ignore
+
+@node __fpclassifyf, math
+@findex __fpclassifyf
+@subheading Syntax
+
+@example
+#include <math.h>
+
+int __fpclassifyf(float) __attribute((const));
+@end example
+
+@subheading Description
+
+Returns the kind of the floating point value supplied. You should use
+the type generic macro @code{fpclassify} instead of this function.
+
+@subheading Return Value
+
+FP_INFINITE, FP_NAN, FP_NORMAL, FP_SUBNORMAL or FP_ZERO.
+
+@subheading Portability
+
+@portability !ansi-c89, ansi-c99
+
+@subheading Example
+
+@example
+if( __fpclassifyf(0.0F) != FP_ZERO )
+@{
+ printf("Something is wrong with the implementation!\n");
+@}
+
+@end example
+
Index: djgpp/src/libc/c99/math/fpclassl.S
===================================================================
RCS file: djgpp/src/libc/c99/math/fpclassl.S
diff -N djgpp/src/libc/c99/math/fpclassl.S
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ djgpp/src/libc/c99/math/fpclassl.S 21 Jun 2003 14:03:17 -0000
@@ -0,0 +1,67 @@
+/*
+ * File fpclassd.S.
+ *
+ * Copyright (C) 2003 Martin Str@"omberg <ams AT ludd DOT luth DOT se>.
+ *
+ * This software may be used freely so long as this copyright notice is
+ * left intact. There is no warranty on this software.
+ *
+ */
+
+#include <sys/math_def.h>
+
+/*
+ * Bits: 79 (sign), 78-64 (exponent), 63 (integer), 62-0 (fraction)
+ * Zero: +/- 0 1 0
+ * Subnormal +/- 0 1 !=0
+ * Normal +/- !=0, <0xff 1 any
+ * Infinity: +/- 0xff 1 0
+ * NaN: any 0xff 1 !=0
+ * Unnormal any any 0 any
+ */
+
+/*
+ * Stack:
+ * 12(%esp): high 16 bits of the long double
+ * 8(%esp): middle 32 bits of the long double
+ * 4(%esp): low 32 bits of the long double
+ * 0(%esp): return address
+ */
+ .globl ___fpclassifyld
+___fpclassifyld:
+ movl 8(%esp), %edx
+ testl $0x80000000, %edx
+ jz unnormal
+
+ movl 12(%esp), %eax
+ andl $0x7fffffff, %edx /* Remove integer bit. */
+ andl $0x7fff, %eax
+ jz zero_exponent
+
+ cmpl $0x7fff, %eax
+ je all_ones_exponent
+
+ movl $FP_NORMAL, %eax
+ ret
+
+zero_exponent:
+ orl 4(%esp), %edx
+ movl $FP_ZERO, %eax
+ jz zero
+
+ movl $FP_SUBNORMAL, %eax
+zero:
+ ret
+
+all_ones_exponent:
+ orl 4(%esp), %edx
+ movl $FP_INFINITE, %eax
+ jz infinity
+
+ movl $FP_NAN, %eax
+infinity:
+ ret
+
+unnormal:
+ movl $FP_UNNORMAL, %eax
+ ret
Index: djgpp/src/libc/c99/math/fpclassl.txh
===================================================================
RCS file: djgpp/src/libc/c99/math/fpclassl.txh
diff -N djgpp/src/libc/c99/math/fpclassl.txh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ djgpp/src/libc/c99/math/fpclassl.txh 21 Jun 2003 14:03:17 -0000
@@ -0,0 +1,43 @@
+@ignore
+ * File fpclassl.txh.
+ *
+ * Copyright (C) 2003 Martin Str@"omberg <ams AT ludd DOT luth DOT se>.
+ *
+ * This software may be used freely so long as this copyright notice is
+ * left intact. There is no warranty on this software.
+ *
+@end ignore
+
+@node __fpclassifyld, math
+@findex __fpclassifyld
+@subheading Syntax
+
+@example
+#include <math.h>
+
+int __fpclassifyld(long double) __attribute((const));
+@end example
+
+@subheading Description
+
+Returns the kind of the floating point value supplied. You should use
+the type generic macro @code{fpclassify} instead of this function.
+
+@subheading Return Value
+
+FP_INFINITE, FP_NAN, FP_NORMAL, FP_SUBNORMAL, FP_ZERO or FP_UNNORMAL.
+
+@subheading Portability
+
+@portability !ansi-c89, ansi-c99
+
+@subheading Example
+
+@example
+if( __fpclassifyf(0.0L) != FP_ZERO )
+@{
+ printf("Something is wrong with the implementation!\n");
+@}
+
+@end example
+
Index: djgpp/src/libc/c99/math/makefile
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/c99/math/makefile,v
retrieving revision 1.2
diff -p -u -r1.2 makefile
--- djgpp/src/libc/c99/math/makefile 22 Mar 2003 11:59:57 -0000 1.2
+++ djgpp/src/libc/c99/math/makefile 21 Jun 2003 14:03:17 -0000
@@ -4,5 +4,8 @@ TOP=../..
SRC += hugevalf.c
SRC += hugevall.c
SRC += nan.c
+SRC += fpclassf.S
+SRC += fpclassd.S
+SRC += fpclassl.S
include $(TOP)/../makefile.inc
- Raw text -