summaryrefslogtreecommitdiff
path: root/libc/i386fp/fperror.x
diff options
context:
space:
mode:
Diffstat (limited to 'libc/i386fp/fperror.x')
-rw-r--r--libc/i386fp/fperror.x126
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