home *** CD-ROM | disk | FTP | other *** search
- /*
- ** This file is part of the alternative 80386 math library and is
- ** covered by the GNU General Public license with my modification
- ** as noted in the README file that accompanied this file.
- **
- ** Copyright 1990 G. Geers
- **
- ** A mix of C and assembler - well I've got the functions so I might
- ** as well use them!
- **
- */
-
- #include "fpumath.h"
-
- asm(".align 4");
- asm(".Lulp:");
- asm(".double 1.1102230246251565e-16");
-
- asm(".align 4");
- asm(".Lulpup:");
- asm(".double 2.2204460492503131e-16");
-
- double
- nextafter(x, y)
- double x, y;
- {
- asm("subl $8, %esp");
-
- if (isnan(x) || isnan(y))
- return(quiet_nan(1.0));
-
- if (isinf(x))
- if (y > x)
- return(-max_normal());
- else
- if (y < x)
- return(max_normal());
-
- if (x == 0.0)
- if (y > 0.0)
- return(min_subnormal());
- else
- return(-min_subnormal());
-
- if (isnormal(x)) {
- if ((x == min_normal()) && y < x)
- return(max_subnormal());
-
- if ((x == max_normal()) && y > x)
- return(infinity());
-
- if ((x == -max_normal()) && y < x)
- return(-infinity());
-
- asm("movl 12(%ebp), %eax");
- asm("andl $0x7ff00000, %eax");
- asm("movl %eax, -12(%ebp)");
- asm("movl $0x0, -16(%ebp)");
- asm("fincstp");
-
- if (fabs(x) <= 2.0 && y < x)
- asm("fldl .Lulp");
- else
- asm("fldl .Lulpup");
-
- asm("fldl -16(%ebp)");
- asm("fmulp");
-
- if (y > x) {
- asm("fldl 8(%ebp)");
- asm("faddp");
- asm("leave");
- asm("ret");
- }
- if (y < x) {
- asm("fldl 8(%ebp)");
- asm("fsubp");
- asm("leave");
- asm("ret");
- }
- }
- else
- if (issubnormal(x)) {
- if ((x == max_subnormal()) && y > x)
- return(min_normal());
-
- if ((x == -max_subnormal()) && y < x)
- return(-min_normal());
-
- if (y > x)
- return(x + min_subnormal());
-
- if (y < x)
- return(x - min_subnormal());
- }
-
- return(x);
- }
-