From: Message-Id: <200305102203.h4AM38Fu029737@speedy.ludd.luth.se> Subject: fpclassify To: DJGPP-WORKERS Date: Sun, 11 May 2003 00:03:08 +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 Heloo. C99 means we should make a fpclassify macro. Easy: #define fpclassify(x) ((sizeof(x)==sizeof(float))? __fpclassifyf(x) : \ (sizeof(x)==sizeof(double))? __fpclassifyd(x) : \ __fpclassifyld(x)) This returns FP_INFINITE, FP_NAN, FP_NORMAL, FP_SUBNORMAL or FP_ZERO, or FP_UNNORMAL (extension allowed), depending on value of x. This will be used in these C99 macros: #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) As you can see it calls the helper functions __fpclassifyf(), __fpclassifyd() and __fpclassifyld(). I've coded them in assembly (for fun and to improve my assembly). Here's __fpclassifyf() for illustration purposes: /* * 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 /* * 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 Now, as you can see this includes which I created, because #including made as very unhappy. Here's the start of what I get if I try to include : E:/DJGPP/BIN/make.exe -C c99/math gcc ... -c fpclassf.S t:\tmp\cc2qguYe.s: Assembler messages: t:\tmp\cc2qguYe.s:32: Error: no such instruction: `extern double __dj_huge_val' t:\tmp\cc2qguYe.s:36: Error: no such instruction: `double acos(double _x)' t:\tmp\cc2qguYe.s:37: Error: no such instruction: `double asin(double _x)' t:\tmp\cc2qguYe.s:38: Error: no such instruction: `double atan(double _x)' t:\tmp\cc2qguYe.s:39: Error: no such instruction: `double atan2(double _y,double _x)' Clearly the prototypes mess it up. includes too of course. is: #ifndef __dj_include_sys_math_def_h_ #define __dj_include_sys_math_def_h_ #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \ || !defined(__STRICT_ANSI__) #define FP_INFINITE 0 #define FP_NAN 1 #define FP_NORMAL 2 #define FP_SUBNORMAL 3 #define FP_ZERO 4 /* Extended with Unnormals (for long doubles). */ #define FP_UNNORMAL 1024 #endif /* (__STDC_VERSION__ >= 199901L) || !__STRICT_ANSI__ */ #endif /* !__dj_include_sys_math_def_h_ */ The reason for all this is that I need the #defines of FP_* in my assembly. Is there a better way to do it? Right, MartinS