patch-2.1.73 linux/arch/i386/math-emu/reg_u_div.S
Next file: linux/arch/i386/math-emu/reg_u_mul.S
Previous file: linux/arch/i386/math-emu/reg_u_add.S
Back to the patch index
Back to the overall index
- Lines: 135
- Date:
Tue Dec 9 17:57:09 1997
- Orig file:
v2.1.72/linux/arch/i386/math-emu/reg_u_div.S
- Orig date:
Thu Oct 5 06:30:43 1995
diff -u --recursive --new-file v2.1.72/linux/arch/i386/math-emu/reg_u_div.S linux/arch/i386/math-emu/reg_u_div.S
@@ -2,22 +2,24 @@
/*---------------------------------------------------------------------------+
| reg_u_div.S |
| |
- | Core division routines |
+ | Divide one FPU_REG by another and put the result in a destination FPU_REG.|
| |
- | Copyright (C) 1992,1993,1995 |
- | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@jacobi.maths.monash.edu.au |
+ | Copyright (C) 1992,1993,1995,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@suburbia.net |
| |
| |
+---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------+
- | Kernel for the division routines. |
- | |
- | void reg_u_div(FPU_REG *a, FPU_REG *a, |
- | FPU_REG *dest, unsigned int control_word) |
+ | Call from C as: |
+ | int FPU_u_div(FPU_REG *a, FPU_REG *b, FPU_REG *dest, |
+ | unsigned int control_word, char *sign) |
| |
| Does not compute the destination exponent, but does adjust it. |
+ | |
+ | Return value is the tag of the answer, or-ed with FPU_Exception if |
+ | one was raised, or -1 on internal error. |
+---------------------------------------------------------------------------*/
#include "exception.h"
@@ -67,9 +69,12 @@
.byte 0
#endif NON_REENTRANT_FPU
+#define REGA PARAM1
+#define REGB PARAM2
+#define DEST PARAM3
.text
-ENTRY(reg_u_div)
+ENTRY(FPU_u_div)
pushl %ebp
movl %esp,%ebp
#ifndef NON_REENTRANT_FPU
@@ -80,32 +85,28 @@
pushl %edi
pushl %ebx
- movl PARAM1,%esi /* pointer to num */
- movl PARAM2,%ebx /* pointer to denom */
- movl PARAM3,%edi /* pointer to answer */
-
-#ifdef DENORM_OPERAND
- movl EXP(%esi),%eax
- cmpl EXP_UNDER,%eax
- jg xOp1_not_denorm
-
- call SYMBOL_NAME(denormal_operand)
- orl %eax,%eax
- jnz fpu_Arith_exit
-
-xOp1_not_denorm:
- movl EXP(%ebx),%eax
- cmpl EXP_UNDER,%eax
- jg xOp2_not_denorm
-
- call SYMBOL_NAME(denormal_operand)
- orl %eax,%eax
- jnz fpu_Arith_exit
+ movl REGA,%esi
+ movl REGB,%ebx
+ movl DEST,%edi
+
+ movw EXP(%esi),%dx
+ movw EXP(%ebx),%ax
+ .byte 0x0f,0xbf,0xc0 /* movsx %ax,%eax */
+ .byte 0x0f,0xbf,0xd2 /* movsx %dx,%edx */
+ subl %eax,%edx
+ addl EXP_BIAS,%edx
+
+ /* A denormal and a large number can cause an exponent underflow */
+ cmpl EXP_WAY_UNDER,%edx
+ jg xExp_not_underflow
+
+ /* Set to a really low value allow correct handling */
+ movl EXP_WAY_UNDER,%edx
+
+xExp_not_underflow:
-xOp2_not_denorm:
-#endif DENORM_OPERAND
+ movw %dx,EXP(%edi)
-ENTRY(divide_kernel)
#ifdef PARANOID
/* testl $0x80000000, SIGH(%esi) // Dividend */
/* je L_bugged */
@@ -147,7 +148,7 @@
/* Do the shifting here */
/* increase the exponent */
- incl EXP(%edi)
+ incw EXP(%edi)
/* shift the mantissa right one bit */
stc /* To set the ms bit */
@@ -423,7 +424,7 @@
testb $255,FPU_ovfl_flag /* was the num > denom ? */
je LRound_precision
- incl EXP(%edi)
+ incw EXP(%edi)
/* shift the mantissa right one bit */
stc /* Will set the ms bit */
@@ -433,7 +434,7 @@
/* Round the result as required */
LRound_precision:
- decl EXP(%edi) /* binary point between 1st & 2nd bits */
+ decw EXP(%edi) /* binary point between 1st & 2nd bits */
movl %eax,%edx
movl FPU_result_1,%ebx
@@ -462,6 +463,7 @@
jmp L_exit
L_exit:
+ movl $-1,%eax
popl %ebx
popl %edi
popl %esi
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov