diff options
Diffstat (limited to 'libc/i386fp/fperror.x')
-rw-r--r-- | libc/i386fp/fperror.x | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/libc/i386fp/fperror.x b/libc/i386fp/fperror.x new file mode 100644 index 0000000..04f3f74 --- /dev/null +++ b/libc/i386fp/fperror.x @@ -0,0 +1,126 @@ +! bcc 386 floating point routines (version 2) +! --- fpdenormal, fperror, fpinfinity, fpNaN, fpoverflow, fpunderflow,fpdivzero +! author: Bruce Evans + +#include "fperr.h" +#include "fplib.h" + + .extern _fperr + +! Cause a denormal-operand exception +! Preserves all general registers if signal handler returns + + .globl fpdenormal + .align ALIGNMENT +fpdenormal: +#if 0 + push eax + mov eax,#EFDENORMAL + call fperror + pop eax +#endif + ret + +! Cause an exception with error code eax, preserving all genregs except eax + + .globl fperror + .align ALIGNMENT +fperror: + push ebp ! set up usual frame ... + mov ebp,esp ! ... for debugging + push edx ! save default + push ecx + push eax ! error code is arg to C routine + call _fperr + add esp,#GENREG_SIZE + pop ecx ! restore default + pop edx + pop ebp + ret + + .align ALIGNMENT +fphuge: + mov ecx,#D_HUGE_LOW ! prepare number +-HUGEVAL + or edx,#D_HUGE_HIGH ! ... in case signal handler returns + jmp fperror + +! Cause an infinite-operand exception +! Return +-HUGEVAL in edx:ecx with sign from edx + + .globl fpinfinity + .align ALIGNMENT +fpinfinity: + mov eax,#EFINFINITY + jmp fphuge ! almost right + +! Cause an NaN-operand exception +! Return +-HUGEVAL in edx:ecx with sign from edx + + .globl fpNaN + .align ALIGNMENT +fpNaN: + mov eax,#EFNAN ! there are different types of NaNs but... + jmp fphuge ! WRONG + +! Cause an overflow exception +! Return +-HUGEVAL in edx:ecx with sign from edx + + .globl fpoverflow + .align ALIGNMENT +fpoverflow: + mov eax,#EFOVERFLOW + jmp fphuge ! almost right + +! Cause an underflow exception (actually assume it is masked for now) +! Return denormal or 0.0 in edx:ecx +! XXX - this should cause a denormal exception or none for the denormal case +! Args: sign in edx, fraction in esi:eax, right shift in edi +! Returns: denormalized number in edx:eax + + .globl fpunderflow + .align ALIGNMENT +fpunderflow: +#if 0 + mov eax,#EFUNDERFLOW + jmp fperror +#endif + cmp edi,#REG_BIT + jb denormalize1 + mov eax,esi + sub esi,esi + sub edi,#REG_BIT + cmp edi,#REG_BIT + jb denormalize1 +denormalize_underflow: +#if 0 + mov eax,#EFUNDERFLOW + jmp fperror +#endif + sub eax,eax + mov edx,eax + ret + + .align ALIGNMENT +denormalize1: + mov ecx,edi + shrd eax,esi,cl + shr esi,cl + mov ecx,esi + or ecx,eax + jz denormalize_underflow + and edx,#D_SIGN_MASK + or edx,esi + ret + +! Cause an fp division by zero exception +! Return +-HUGEVAL in edx:ecx with sign from edx + + .globl fpdivzero + .align ALIGNMENT +fpdivzero: + mov eax,#EFDIVZERO + test edx,#D_EXP_MASK + jnz fphuge ! almost right + sub ecx,ecx + mov edx,ecx + jmp fperror |