Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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)