^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 "wm_sqrt.S"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) /*---------------------------------------------------------------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) | wm_sqrt.S |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) | Fixed point arithmetic square root evaluation. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) | Copyright (C) 1992,1993,1995,1997 |
^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@suburbia.net |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) | Call from C as: |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) | int wm_sqrt(FPU_REG *n, unsigned int control_word) |
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /*---------------------------------------------------------------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) | wm_sqrt(FPU_REG *n, unsigned int control_word) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) | returns the square root of n in n. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) | Use Newton's method to compute the square root of a number, which must |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) | be in the range [1.0 .. 4.0), to 64 bits accuracy. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) | Does not check the sign or tag of the argument. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) | Sets the exponent, but not the sign or tag of the result. |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) | The guess is kept in %esi:%edi |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) +---------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "exception.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "fpu_emu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #ifndef NON_REENTRANT_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* Local storage on the stack: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define FPU_accum_3 -4(%ebp) /* ms word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define FPU_accum_2 -8(%ebp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define FPU_accum_1 -12(%ebp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define FPU_accum_0 -16(%ebp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * The de-normalised argument:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * sq_2 sq_1 sq_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * b b b b b b b ... b b b b b b .... b b b b 0 0 0 ... 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * ^ binary point here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define FPU_fsqrt_arg_2 -20(%ebp) /* ms word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define FPU_fsqrt_arg_1 -24(%ebp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define FPU_fsqrt_arg_0 -28(%ebp) /* ls word, at most the ms bit is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* Local storage in a static area: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .align 4,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) FPU_accum_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .long 0 /* ms word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) FPU_accum_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .long 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) FPU_accum_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .long 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) FPU_accum_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .long 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* The de-normalised argument:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) sq_2 sq_1 sq_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) b b b b b b b ... b b b b b b .... b b b b 0 0 0 ... 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) ^ binary point here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) FPU_fsqrt_arg_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .long 0 /* ms word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) FPU_fsqrt_arg_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .long 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) FPU_fsqrt_arg_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .long 0 /* ls word, at most the ms bit is set */
^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(wm_sqrt)
^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) pushl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) pushl %edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) pushl %ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) movl PARAM1,%esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) movl SIGH(%esi),%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) movl SIGL(%esi),%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) xorl %edx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* We use a rough linear estimate for the first guess.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) cmpw EXP_BIAS,EXP(%esi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) jnz sqrt_arg_ge_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) shrl $1,%eax /* arg is in the range [1.0 .. 2.0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) rcrl $1,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) rcrl $1,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) sqrt_arg_ge_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* From here on, n is never accessed directly again until it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) replaced by the answer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) movl %eax,FPU_fsqrt_arg_2 /* ms word of n */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) movl %ecx,FPU_fsqrt_arg_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) movl %edx,FPU_fsqrt_arg_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* Make a linear first estimate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) shrl $1,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) addl $0x40000000,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) movl $0xaaaaaaaa,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) mull %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) shll %edx /* max result was 7fff... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) testl $0x80000000,%edx /* but min was 3fff... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) jnz sqrt_prelim_no_adjust
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) movl $0x80000000,%edx /* round up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) sqrt_prelim_no_adjust:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) movl %edx,%esi /* Our first guess */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* We have now computed (approx) (2 + x) / 3, which forms the basis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) for a few iterations of Newton's method */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) movl FPU_fsqrt_arg_2,%ecx /* ms word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * From our initial estimate, three iterations are enough to get us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * to 30 bits or so. This will then allow two iterations at better
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * precision to complete the process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* Compute (g + n/g)/2 at each iteration (g is the guess). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) shrl %ecx /* Doing this first will prevent a divide */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* overflow later. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) movl %ecx,%edx /* msw of the arg / 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) divl %esi /* current estimate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) shrl %esi /* divide by 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) addl %eax,%esi /* the new estimate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) movl %ecx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) divl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) shrl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) addl %eax,%esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) movl %ecx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) divl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) shrl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) addl %eax,%esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * Now that an estimate accurate to about 30 bits has been obtained (in %esi),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * we improve it to 60 bits or so.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * The strategy from now on is to compute new estimates from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * guess := guess + (n - guess^2) / (2 * guess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* First, find the square of the guess */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) movl %esi,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) mull %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* guess^2 now in %edx:%eax */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) movl FPU_fsqrt_arg_1,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) subl %ecx,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) movl FPU_fsqrt_arg_2,%ecx /* ms word of normalized n */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) sbbl %ecx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) jnc sqrt_stage_2_positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* Subtraction gives a negative result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) negate the result before division. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) notl %edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) notl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) addl $1,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) adcl $0,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) divl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) movl %eax,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) movl %edx,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) divl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) jmp sqrt_stage_2_finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) sqrt_stage_2_positive:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) divl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) movl %eax,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) movl %edx,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) divl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) notl %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) notl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) addl $1,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) adcl $0,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) sqrt_stage_2_finish:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) sarl $1,%ecx /* divide by 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) rcrl $1,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* Form the new estimate in %esi:%edi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) movl %eax,%edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) addl %ecx,%esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) jnz sqrt_stage_2_done /* result should be [1..2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* It should be possible to get here only if the arg is ffff....ffff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) cmpl $0xffffffff,FPU_fsqrt_arg_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) jnz sqrt_stage_2_error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* The best rounded result. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) xorl %eax,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) decl %eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) movl %eax,%edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) movl %eax,%esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) movl $0x7fffffff,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) jmp sqrt_round_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) sqrt_stage_2_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) pushl EX_INTERNAL|0x213
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) sqrt_stage_2_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /* Now the square root has been computed to better than 60 bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /* Find the square of the guess. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) movl %edi,%eax /* ls word of guess */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) mull %edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) movl %edx,FPU_accum_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) movl %esi,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) mull %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) movl %edx,FPU_accum_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) movl %eax,FPU_accum_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) movl %edi,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) mull %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) addl %eax,FPU_accum_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) adcl %edx,FPU_accum_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) adcl $0,FPU_accum_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* movl %esi,%eax */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /* mull %edi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) addl %eax,FPU_accum_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) adcl %edx,FPU_accum_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) adcl $0,FPU_accum_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* guess^2 now in FPU_accum_3:FPU_accum_2:FPU_accum_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) movl FPU_fsqrt_arg_0,%eax /* get normalized n */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) subl %eax,FPU_accum_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) movl FPU_fsqrt_arg_1,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) sbbl %eax,FPU_accum_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) movl FPU_fsqrt_arg_2,%eax /* ms word of normalized n */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) sbbl %eax,FPU_accum_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) jnc sqrt_stage_3_positive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* Subtraction gives a negative result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) negate the result before division */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) notl FPU_accum_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) notl FPU_accum_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) notl FPU_accum_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) addl $1,FPU_accum_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) adcl $0,FPU_accum_2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) adcl $0,FPU_accum_3 /* This must be zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) jz sqrt_stage_3_no_error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) sqrt_stage_3_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) pushl EX_INTERNAL|0x207
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) sqrt_stage_3_no_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) movl FPU_accum_2,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) movl FPU_accum_1,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) divl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) movl %eax,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) movl %edx,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) divl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) sarl $1,%ecx /* divide by 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) rcrl $1,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* prepare to round the result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) addl %ecx,%edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) adcl $0,%esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) jmp sqrt_stage_3_finished
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) sqrt_stage_3_positive:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) movl FPU_accum_2,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) movl FPU_accum_1,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) divl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) movl %eax,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) movl %edx,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) divl %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) sarl $1,%ecx /* divide by 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) rcrl $1,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* prepare to round the result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) notl %eax /* Negate the correction term */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) notl %ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) addl $1,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) adcl $0,%ecx /* carry here ==> correction == 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) adcl $0xffffffff,%esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) addl %ecx,%edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) adcl $0,%esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) sqrt_stage_3_finished:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * The result in %esi:%edi:%esi should be good to about 90 bits here,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * and the rounding information here does not have sufficient accuracy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * in a few rare cases.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) cmpl $0xffffffe0,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) ja sqrt_near_exact_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) cmpl $0x00000020,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) jb sqrt_near_exact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) cmpl $0x7fffffe0,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) jb sqrt_round_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) cmpl $0x80000020,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) jb sqrt_get_more_precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) sqrt_round_result:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* Set up for rounding operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) movl %eax,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) movl %esi,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) movl %edi,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) movl PARAM1,%edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) movw EXP_BIAS,EXP(%edi) /* Result is in [1.0 .. 2.0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) jmp fpu_reg_round
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) sqrt_near_exact_x:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /* First, the estimate must be rounded up. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) addl $1,%edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) adcl $0,%esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) sqrt_near_exact:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * This is an easy case because x^1/2 is monotonic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * We need just find the square of our estimate, compare it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * with the argument, and deduce whether our estimate is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * above, below, or exact. We use the fact that the estimate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * is known to be accurate to about 90 bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) movl %edi,%eax /* ls word of guess */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) mull %edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) movl %edx,%ebx /* 2nd ls word of square */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) movl %eax,%ecx /* ls word of square */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) movl %edi,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) mull %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) addl %eax,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) addl %eax,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) cmp $0xffffffb0,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) jb sqrt_near_exact_ok
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) cmp $0x00000050,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) ja sqrt_near_exact_ok
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) pushl EX_INTERNAL|0x214
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) sqrt_near_exact_ok:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) or %ebx,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) js sqrt_near_exact_small
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) jnz sqrt_near_exact_large
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) or %ebx,%edx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) jnz sqrt_near_exact_large
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /* Our estimate is exactly the right answer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) xorl %eax,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) jmp sqrt_round_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) sqrt_near_exact_small:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /* Our estimate is too small */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) movl $0x000000ff,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) jmp sqrt_round_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) sqrt_near_exact_large:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /* Our estimate is too large, we need to decrement it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) subl $1,%edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) sbbl $0,%esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) movl $0xffffff00,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) jmp sqrt_round_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) sqrt_get_more_precision:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /* This case is almost the same as the above, except we start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) with an extra bit of precision in the estimate. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) stc /* The extra bit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) rcll $1,%edi /* Shift the estimate left one bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) rcll $1,%esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) movl %edi,%eax /* ls word of guess */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) mull %edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) movl %edx,%ebx /* 2nd ls word of square */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) movl %eax,%ecx /* ls word of square */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) movl %edi,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) mull %esi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) addl %eax,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) addl %eax,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* Put our estimate back to its original value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) stc /* The ms bit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) rcrl $1,%esi /* Shift the estimate left one bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) rcrl $1,%edi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) #ifdef PARANOID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) cmp $0xffffff60,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) jb sqrt_more_prec_ok
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) cmp $0x000000a0,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ja sqrt_more_prec_ok
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) pushl EX_INTERNAL|0x215
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) call EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) sqrt_more_prec_ok:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) #endif /* PARANOID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) or %ebx,%ebx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) js sqrt_more_prec_small
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) jnz sqrt_more_prec_large
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) or %ebx,%ecx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) jnz sqrt_more_prec_large
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* Our estimate is exactly the right answer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) movl $0x80000000,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) jmp sqrt_round_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) sqrt_more_prec_small:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /* Our estimate is too small */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) movl $0x800000ff,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) jmp sqrt_round_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) sqrt_more_prec_large:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) /* Our estimate is too large */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) movl $0x7fffff00,%eax
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) jmp sqrt_round_result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) SYM_FUNC_END(wm_sqrt)