www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2003/05/10/18:03:23

From: <ams AT ludd DOT luth DOT se>
Message-Id: <200305102203.h4AM38Fu029737@speedy.ludd.luth.se>
Subject: fpclassify
To: DJGPP-WORKERS <djgpp-workers AT delorie DOT com>
Date: Sun, 11 May 2003 00:03:08 +0200 (CEST)
X-Mailer: ELM [version 2.4ME+ PL78 (25)]
MIME-Version: 1.0
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 <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:        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 <sys/math_def.h> which I created,
because #including <math.h> made as very unhappy. Here's the start of
what I get if I try to include <math,h>:
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.

<math.h> includes <sys/math_def.h> too of course. <sys/math_def.h> 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

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019