From: Message-Id: <200306211408.h5LE8iD2022450@speedy.ludd.luth.se> Subject: fpclassify To: DJGPP-WORKERS Date: Sat, 21 Jun 2003 16:08:44 +0200 (CEST) X-Mailer: ELM [version 2.4ME+ PL78 (25)] MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII X-MailScanner: Found to be clean Reply-To: djgpp-workers AT delorie DOT com 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 #else +#include + #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 . + * + * This software may be used freely so long as this copyright notice is + * left intact. There is no warranty on this software. + * + */ + +#include + +/* + * 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 . + * + * 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 + +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 . + * + * This software may be used freely so long as this copyright notice is + * left intact. There is no warranty on this software. + * + */ + +#include +/*#include */ + +/* + * 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 . + * + * 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 + +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 . + * + * This software may be used freely so long as this copyright notice is + * left intact. There is no warranty on this software. + * + */ + +#include + +/* + * 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 . + * + * 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 + +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