^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) .file "div_Xsig.S"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) /*---------------------------------------------------------------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) | div_Xsig.S |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) | Division subroutine for 96 bit quantities |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) | Copyright (C) 1994,1995 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) | Australia. E-mail billm@jacobi.maths.monash.edu.au |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) +---------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /*---------------------------------------------------------------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) | Divide the 96 bit quantity pointed to by a, by that pointed to by b, and |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) | put the 96 bit result at the location d. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) | The result may not be accurate to 96 bits. It is intended for use where |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) | a result better than 64 bits is required. The result should usually be |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) | good to at least 94 bits. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) | The returned result is actually divided by one half. This is done to |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) | prevent overflow. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) | .aaaaaaaaaaaaaa / .bbbbbbbbbbbbb -> .dddddddddddd |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) | void div_Xsig(Xsig *a, Xsig *b, Xsig *dest) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) +---------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "exception.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "fpu_emu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define XsigLL(x) (x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define XsigL(x) 4(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define XsigH(x) 8(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #ifndef NON_REENTRANT_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) Local storage on the stack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) Accumulator: FPU_accum_3:FPU_accum_2:FPU_accum_1:FPU_accum_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define FPU_accum_3 -4(%ebp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define FPU_accum_2 -8(%ebp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define FPU_accum_1 -12(%ebp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define FPU_accum_0 -16(%ebp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define FPU_result_3 -20(%ebp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define FPU_result_2 -24(%ebp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define FPU_result_1 -28(%ebp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) Local storage in a static area:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) Accumulator: FPU_accum_3:FPU_accum_2:FPU_accum_1:FPU_accum_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .align 4,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) FPU_accum_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .long 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) FPU_accum_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .long 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) FPU_accum_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .long 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) FPU_accum_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .long 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) FPU_result_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .long 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) FPU_result_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .long 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) FPU_result_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .long 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #endif /* NON_REENTRANT_FPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) SYM_FUNC_START(div_Xsig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) pushl %ebp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) movl %esp,%ebp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #ifndef NON_REENTRANT_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) subl $28,%esp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #endif /* NON_REENTRANT_FPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) pushl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) pushl %edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) pushl %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) movl PARAM1,%esi /* pointer to num */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) movl PARAM2,%ebx /* pointer to denom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) testl $0x80000000, XsigH(%ebx) /* Divisor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) je L_bugged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /*---------------------------------------------------------------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) | Divide: Return arg1/arg2 to arg3. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) | The maximum returned value is (ignoring exponents) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) | .ffffffff ffffffff |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) | ------------------ = 1.ffffffff fffffffe |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) | .80000000 00000000 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) | and the minimum is |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) | .80000000 00000000 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) | ------------------ = .80000000 00000001 (rounded) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) | .ffffffff ffffffff |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) +---------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* Save extended dividend in local register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* Divide by 2 to prevent overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) clc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) movl XsigH(%esi),%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) rcrl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) movl %eax,FPU_accum_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) movl XsigL(%esi),%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) rcrl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) movl %eax,FPU_accum_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) movl XsigLL(%esi),%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) rcrl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) movl %eax,FPU_accum_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) movl $0,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) rcrl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) movl %eax,FPU_accum_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) movl FPU_accum_2,%eax /* Get the current num */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) movl FPU_accum_3,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /*----------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* Initialization done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) Do the first 32 bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* We will divide by a number which is too large */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) movl XsigH(%ebx),%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) addl $1,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) jnc LFirst_div_not_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* here we need to divide by 100000000h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) i.e., no division at all.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) mov %edx,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) jmp LFirst_div_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) LFirst_div_not_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) divl %ecx /* Divide the numerator by the augmented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) denom ms dw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) LFirst_div_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) movl %eax,FPU_result_3 /* Put the result in the answer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) mull XsigH(%ebx) /* mul by the ms dw of the denom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) subl %eax,FPU_accum_2 /* Subtract from the num local reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) sbbl %edx,FPU_accum_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) movl FPU_result_3,%eax /* Get the result back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) mull XsigL(%ebx) /* now mul the ls dw of the denom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) subl %eax,FPU_accum_1 /* Subtract from the num local reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) sbbl %edx,FPU_accum_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) sbbl $0,FPU_accum_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) je LDo_2nd_32_bits /* Must check for non-zero result here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) jb L_bugged_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* need to subtract another once of the denom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) incl FPU_result_3 /* Correct the answer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) movl XsigL(%ebx),%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) movl XsigH(%ebx),%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) subl %eax,FPU_accum_1 /* Subtract from the num local reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) sbbl %edx,FPU_accum_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) sbbl $0,FPU_accum_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) jne L_bugged_1 /* Must check for non-zero result here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /*----------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* Half of the main problem is done, there is just a reduced numerator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) to handle now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) Work with the second 32 bits, FPU_accum_0 not used from now on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) LDo_2nd_32_bits:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) movl FPU_accum_2,%edx /* get the reduced num */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) movl FPU_accum_1,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /* need to check for possible subsequent overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) cmpl XsigH(%ebx),%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) jb LDo_2nd_div
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ja LPrevent_2nd_overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) cmpl XsigL(%ebx),%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) jb LDo_2nd_div
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) LPrevent_2nd_overflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* The numerator is greater or equal, would cause overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* prevent overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) subl XsigL(%ebx),%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) sbbl XsigH(%ebx),%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) movl %edx,FPU_accum_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) movl %eax,FPU_accum_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) incl FPU_result_3 /* Reflect the subtraction in the answer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) je L_bugged_2 /* Can't bump the result to 1.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) LDo_2nd_div:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) cmpl $0,%ecx /* augmented denom msw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) jnz LSecond_div_not_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* %ecx == 0, we are dividing by 1.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) mov %edx,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) jmp LSecond_div_done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) LSecond_div_not_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) divl %ecx /* Divide the numerator by the denom ms dw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) LSecond_div_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) movl %eax,FPU_result_2 /* Put the result in the answer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) mull XsigH(%ebx) /* mul by the ms dw of the denom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) subl %eax,FPU_accum_1 /* Subtract from the num local reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) sbbl %edx,FPU_accum_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) jc L_bugged_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) movl FPU_result_2,%eax /* Get the result back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) mull XsigL(%ebx) /* now mul the ls dw of the denom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) subl %eax,FPU_accum_0 /* Subtract from the num local reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) sbbl %edx,FPU_accum_1 /* Subtract from the num local reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) sbbl $0,FPU_accum_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) jc L_bugged_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) jz LDo_3rd_32_bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) cmpl $1,FPU_accum_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) jne L_bugged_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /* need to subtract another once of the denom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) movl XsigL(%ebx),%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) movl XsigH(%ebx),%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) subl %eax,FPU_accum_0 /* Subtract from the num local reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) sbbl %edx,FPU_accum_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) sbbl $0,FPU_accum_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) jc L_bugged_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) jne L_bugged_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) addl $1,FPU_result_2 /* Correct the answer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) adcl $0,FPU_result_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) jc L_bugged_2 /* Must check for non-zero result here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /*----------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* The division is essentially finished here, we just need to perform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) tidying operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) Deal with the 3rd 32 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) LDo_3rd_32_bits:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* We use an approximation for the third 32 bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) To take account of the 3rd 32 bits of the divisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) (call them del), we subtract del * (a/b) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) movl FPU_result_3,%eax /* a/b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) mull XsigLL(%ebx) /* del */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) subl %edx,FPU_accum_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* A borrow indicates that the result is negative */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) jnb LTest_over
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) movl XsigH(%ebx),%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) addl %edx,FPU_accum_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) subl $1,FPU_result_2 /* Adjust the answer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) sbbl $0,FPU_result_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* The above addition might not have been enough, check again. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) movl FPU_accum_1,%edx /* get the reduced num */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) cmpl XsigH(%ebx),%edx /* denom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) jb LDo_3rd_div
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) movl XsigH(%ebx),%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) addl %edx,FPU_accum_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) subl $1,FPU_result_2 /* Adjust the answer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) sbbl $0,FPU_result_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) jmp LDo_3rd_div
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) LTest_over:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) movl FPU_accum_1,%edx /* get the reduced num */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* need to check for possible subsequent overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) cmpl XsigH(%ebx),%edx /* denom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) jb LDo_3rd_div
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* prevent overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) subl XsigH(%ebx),%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) movl %edx,FPU_accum_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) addl $1,FPU_result_2 /* Reflect the subtraction in the answer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) adcl $0,FPU_result_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) LDo_3rd_div:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) movl FPU_accum_0,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) movl FPU_accum_1,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) divl XsigH(%ebx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) movl %eax,FPU_result_1 /* Rough estimate of third word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) movl PARAM3,%esi /* pointer to answer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) movl FPU_result_1,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) movl %eax,XsigLL(%esi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) movl FPU_result_2,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) movl %eax,XsigL(%esi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) movl FPU_result_3,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) movl %eax,XsigH(%esi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) L_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) popl %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) popl %edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) popl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) leave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /* The logic is wrong if we got here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) L_bugged:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) pushl EX_INTERNAL|0x240
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) pop %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) jmp L_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) L_bugged_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) pushl EX_INTERNAL|0x241
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) pop %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) jmp L_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) L_bugged_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) pushl EX_INTERNAL|0x242
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) pop %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) jmp L_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) SYM_FUNC_END(div_Xsig)