/ fpclass.s (emx+gcc) -- Copyright (c) 1996 by Eberhard Mattes

#include <emx/asm386.h>

#define FUNC    MATHSUFFIX3(__fpclassify)

        .globl  LABEL(FUNC)

        .text

        ALIGN

#if defined (LONG_DOUBLE)

/ int __fpclassifyl (long double x)

#define x       4(%esp)

LABEL(FUNC):
        PROFILE_NOFRAME
        fldt    x
        fxam
        fstsww  %ax
        fstp    %st(0)
        movb    %ah, %al
        andl    $0x47, %eax
        movb    Ltable(%eax), %al
        EPILOGUE(FUNC)

Ltable: .byte   FP_NAN          /* +unnormal, not supported by 387 */
        .byte   FP_NAN          /* -unnormal, not supported by 387 */
        .byte   FP_NAN          /* +NaN */
        .byte   FP_NAN          /* -NaN */
        .byte   FP_NORMAL       /* +normal */
        .byte   FP_INFINITE     /* +infinity */
        .byte   FP_NORMAL       /* -normal */
        .byte   FP_INFINITE     /* -infinity */
        .byte   FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN
        .byte   FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN
        .byte   FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN
        .byte   FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN
        .byte   FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN
        .byte   FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN
        .byte   FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN, FP_NAN
        .byte   FP_ZERO         /* +zero */
        .byte   FP_NAN          /* empty */
        .byte   FP_ZERO         /* -zero */
        .byte   FP_NAN          /* empty */
        .byte   FP_SUBNORMAL    /* +denormal */
        .byte   FP_NAN          /* empty, not supported by 387 */
        .byte   FP_SUBNORMAL    /* -denormal */
        .byte   FP_NAN          /* empty, not supported by 387 */

#elif defined (FLOAT)

/ int __fpclassifyf (float x)

#define x       4(%esp)

LABEL(FUNC):
        PROFILE_NOFRAME
        movl    x, %edx
        movl    $FP_ZERO, %eax          /* Clear upper 24 bits */
        andl    $0x7fffffff, %edx
        jz      Lreturn
        movb    $FP_SUBNORMAL, %al
        cmpl    $0x00800000, %edx
        jb      Lreturn
        movb    $FP_NORMAL, %al
        cmpl    $0x7f800000, %edx
        jb      Lreturn
        movb    $FP_INFINITE, %al
        je      Lreturn
        movb    $FP_NAN, %al
        ALIGN
Lreturn:
        EPILOGUE(FUNC)

#else

/ int __fpclassify (double x)

#define x0      4(%esp)
#define x4      8(%esp)

LABEL(FUNC):
        PROFILE_NOFRAME
        movl    x4, %edx
        movl    $FP_NORMAL, %eax                /* Clear upper 24 bits */
        andl    $0x7ff00000, %edx
        jz      Lexp0
        cmpl    $0x7ff00000, %edx
        je      Lexpmax
        ALIGN
Lreturn:EPILOGUE(FUNC)

        ALIGN
Lexp0:  movb    $FP_SUBNORMAL, %al
        testl   $0x000fffff, x4
        jnz     Lreturn
        cmpl    $0, x0
        jne     Lreturn
        movb    $FP_ZERO, %al
        jmp     Lreturn

        ALIGN
Lexpmax:testl   $0x000fffff, x4
        jnz     Lnan
        movb    $FP_INFINITE, %al
        cmpl    $0, x0
        je      Lreturn
        ALIGN
Lnan:   movb    $FP_NAN, %al
        jmp     Lreturn

#endif
