diff options
Diffstat (limited to 'sysdeps/i386/fpu/i386-math-asm.h')
-rw-r--r-- | sysdeps/i386/fpu/i386-math-asm.h | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/sysdeps/i386/fpu/i386-math-asm.h b/sysdeps/i386/fpu/i386-math-asm.h index c15029d..5d8d847 100644 --- a/sysdeps/i386/fpu/i386-math-asm.h +++ b/sysdeps/i386/fpu/i386-math-asm.h @@ -52,6 +52,14 @@ flt_min: \ dbl_min: \ .byte 0, 0, 0, 0, 0, 0, 0x10, 0; \ .size dbl_min, .-dbl_min; +#define DEFINE_LDBL_MIN \ + .section .rodata.cst16,"aM",@progbits,16; \ + .p2align 4; \ + .type ldbl_min,@object; \ +ldbl_min: \ + .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x1, 0; \ + .byte 0, 0, 0, 0, 0, 0; \ + .size ldbl_min, .-ldbl_min; /* Remove excess range and precision by storing a value on the stack and loading it back. The value is given to be nonnegative or NaN; @@ -123,4 +131,164 @@ dbl_min: \ addl $8, %esp; \ cfi_adjust_cfa_offset (-8); +/* Force an underflow exception if the given value is subnormal. The + relevant constant for the minimum of the type must have been + defined, the MO macro must have been defined for access to memory + operands, and, if PIC, the PIC register must have been loaded. */ +#define FLT_CHECK_FORCE_UFLOW \ + flds MO(flt_min); \ + fld %st(1); \ + fabs; \ + fucompp; \ + fnstsw; \ + sahf; \ + jnc 6424f; \ + subl $4, %esp; \ + cfi_adjust_cfa_offset (4); \ + fld %st(0); \ + fmul %st(0); \ + fstps (%esp); \ + addl $4, %esp; \ + cfi_adjust_cfa_offset (-4); \ +6424: +#define DBL_CHECK_FORCE_UFLOW \ + fldl MO(dbl_min); \ + fld %st(1); \ + fabs; \ + fucompp; \ + fnstsw; \ + sahf; \ + jnc 6453f; \ + subl $8, %esp; \ + cfi_adjust_cfa_offset (8); \ + fld %st(0); \ + fmul %st(0); \ + fstpl (%esp); \ + addl $8, %esp; \ + cfi_adjust_cfa_offset (-8); \ +6453: + +/* Likewise, but also remove excess range and precision if the value + is subnormal. */ +#define FLT_CHECK_FORCE_UFLOW_NARROW \ + flds MO(flt_min); \ + fld %st(1); \ + fabs; \ + fucompp; \ + fnstsw; \ + sahf; \ + jnc 6424f; \ + subl $4, %esp; \ + cfi_adjust_cfa_offset (4); \ + fld %st(0); \ + fmul %st(0); \ + fstps (%esp); \ + fstps (%esp); \ + flds (%esp); \ + addl $4, %esp; \ + cfi_adjust_cfa_offset (-4); \ +6424: +#define DBL_CHECK_FORCE_UFLOW_NARROW \ + fldl MO(dbl_min); \ + fld %st(1); \ + fabs; \ + fucompp; \ + fnstsw; \ + sahf; \ + jnc 6453f; \ + subl $8, %esp; \ + cfi_adjust_cfa_offset (8); \ + fld %st(0); \ + fmul %st(0); \ + fstpl (%esp); \ + fstpl (%esp); \ + fldl (%esp); \ + addl $8, %esp; \ + cfi_adjust_cfa_offset (-8); \ +6453: + +/* Likewise, but the argument is nonnegative or NaN. */ +#define LDBL_CHECK_FORCE_UFLOW_NONNEG_NAN \ + fldt MO(ldbl_min); \ + fld %st(1); \ + fucompp; \ + fnstsw; \ + sahf; \ + jnc 6464f; \ + fld %st(0); \ + fmul %st(0); \ + fstp %st(0); \ +6464: + +/* Likewise, but the argument is not a NaN. */ +#define FLT_CHECK_FORCE_UFLOW_NONNAN \ + fld %st(0); \ + fabs; \ + fcomps MO(flt_min); \ + fnstsw; \ + sahf; \ + jnc 6424f; \ + subl $4, %esp; \ + cfi_adjust_cfa_offset (4); \ + fld %st(0); \ + fmul %st(0); \ + fstps (%esp); \ + addl $4, %esp; \ + cfi_adjust_cfa_offset (-4); \ +6424: +#define DBL_CHECK_FORCE_UFLOW_NONNAN \ + fld %st(0); \ + fabs; \ + fcompl MO(dbl_min); \ + fnstsw; \ + sahf; \ + jnc 6453f; \ + subl $8, %esp; \ + cfi_adjust_cfa_offset (8); \ + fld %st(0); \ + fmul %st(0); \ + fstpl (%esp); \ + addl $8, %esp; \ + cfi_adjust_cfa_offset (-8); \ +6453: + +/* Likewise, but the argument is nonnegative and not a NaN. */ +#define FLT_CHECK_FORCE_UFLOW_NONNEG \ + fcoms MO(flt_min); \ + fnstsw; \ + sahf; \ + jnc 6424f; \ + subl $4, %esp; \ + cfi_adjust_cfa_offset (4); \ + fld %st(0); \ + fmul %st(0); \ + fstps (%esp); \ + addl $4, %esp; \ + cfi_adjust_cfa_offset (-4); \ +6424: +#define DBL_CHECK_FORCE_UFLOW_NONNEG \ + fcoml MO(dbl_min); \ + fnstsw; \ + sahf; \ + jnc 6453f; \ + subl $8, %esp; \ + cfi_adjust_cfa_offset (8); \ + fld %st(0); \ + fmul %st(0); \ + fstpl (%esp); \ + addl $8, %esp; \ + cfi_adjust_cfa_offset (-8); \ +6453: +#define LDBL_CHECK_FORCE_UFLOW_NONNEG \ + fldt MO(ldbl_min); \ + fld %st(1); \ + fcompp; \ + fnstsw; \ + sahf; \ + jnc 6464f; \ + fld %st(0); \ + fmul %st(0); \ + fstp %st(0); \ +6464: + #endif /* i386-math-asm.h. */ |