Simon666
February 17th, 2005, 02:53 AM
Hello,
I make use of a function SquareRoot that is defined in assembler. I'm not sure whether it works correctly so I asked some people for the code. Below is what I received:
================================================
*
* +--------------------------------------------+
* | Unsigned32 SquareRoot(Unsigned32 Argument) |
* +--------------------------------------------+
*
* Functional description : Computes the square root of an Unsigned32.
*
* Algorithm : Newton_iteration -> x(n+1) = 1/2 [N/x(n) + x(n)]
* (See EDN 26/11/87 : DESIGN IDEAS, p250).
*
XDEF _SquareRoot
_SquareRoot
START_INPUT_PARAMETERS D2
DECLARE_INPUT_PARAMETER 4,SQRT_ARGUMENT
*
CLR.L D2 reset msw of d2 !
*
* Compute the "first guess"
*
* 1. Find the most significant non_zero bit pair in N.
* (A bit pair is bits b,b-1 with b even)
* 2. Define i=b/2
* 2^
* 3. Create two numbers :
* N divided by 2^i & 2^i
* 4. Average them to get guess1, the first guess.
*
MOVE.L SQRT_ARGUMENT(SP),D0
MOVE.L D0,D1 save argument
BEQ.B SQRT_900 eq => sqrt(000) = 000
BPL.B SQRT_100 pl => bit pair "32",31 = zero !
*
* Compute sqrt for N >>
*
CLR.W D0
SWAP D0 do = N/2^16
*
* See if N is 0FFFE0001 or greater; if so return 0FFFFH
* (We know that 0FFFFH squared = 0FFFFE0001H)
*
MOVE.W D0,D2
NEG.W D2
ROXR.W #1,D0
SUBQ.W #2,D2
BHI.B SQRT_200 hi => N < 0FFFE0000H
*
* N = FFFExxxx or FFFFxxxx
*
OR.W D1,D2
BNE.B SQRT_900
SUBQ.W #1,D0
BRA.B SQRT_900
*
* The first guess for bit pair 32/31 = zero
*
SQRT_100
ADD.L D0,D0 move bits b-1 -> b
OR.L D1,D0 all non_zero bit-pairs in b now
MOVE.W #15,D2 b/2 (30 .. 0)
*
* Find the most_significant bit_pair
*
SQRT_110
LSL.L #2,D0 test bit_pair
DBCS D2,SQRT_110 until non-zero bit_pair is found ...
*
* Calculate the first_guess
*
MOVE.L D1,D0 N
LSR.L D2,D0 N/2^i
ADD.W #16,D2 i+16
BSET.L D2,D2 d2hi = 2^i
SWAP D2 d2lo = 2^i
ADD.W D2,D0 extend d0 = N/2^i + 2^i (17 bits)
ROXR.W #1,D0 the first guess ...
*
* Aplly Newton's Method.
*
SQRT_200
MOVE.L D1,D2 N
DIVU D0,D2
ADD.W D2,D0
ROXR.W #1,D0 d0 = 1/2[N/guess1 + guess1] => guess2
*
MOVE.L D1,D2 n
DIVU D0,D2
CMP.W D0,D2 is N/guess2 < guess2 ?
BHS.B SQRT_900 hs => no, guess2 = sqrt
ADD.W D2,D0
ROXR.W #1,D0 guess3
*
MOVE.W D0,D2
MULU.W D2,D2 N**2
CMP.L D1,D2 is this > N ?
BLS.B SQRT_900 ls => sqrt
SUBQ.W #1,D0 guess3-1 = sqrt
*
* Exit _SquareRoot
*
SQRT_900
AND.L #0FFFFH,D0 long();
RESTORE_REGISTERS D2
RTS
================================================
Anybody knows how to define a function unsigned int SquareRoot(unsigned int) out of this and compile the thing as to test it?
I make use of a function SquareRoot that is defined in assembler. I'm not sure whether it works correctly so I asked some people for the code. Below is what I received:
================================================
*
* +--------------------------------------------+
* | Unsigned32 SquareRoot(Unsigned32 Argument) |
* +--------------------------------------------+
*
* Functional description : Computes the square root of an Unsigned32.
*
* Algorithm : Newton_iteration -> x(n+1) = 1/2 [N/x(n) + x(n)]
* (See EDN 26/11/87 : DESIGN IDEAS, p250).
*
XDEF _SquareRoot
_SquareRoot
START_INPUT_PARAMETERS D2
DECLARE_INPUT_PARAMETER 4,SQRT_ARGUMENT
*
CLR.L D2 reset msw of d2 !
*
* Compute the "first guess"
*
* 1. Find the most significant non_zero bit pair in N.
* (A bit pair is bits b,b-1 with b even)
* 2. Define i=b/2
* 2^
* 3. Create two numbers :
* N divided by 2^i & 2^i
* 4. Average them to get guess1, the first guess.
*
MOVE.L SQRT_ARGUMENT(SP),D0
MOVE.L D0,D1 save argument
BEQ.B SQRT_900 eq => sqrt(000) = 000
BPL.B SQRT_100 pl => bit pair "32",31 = zero !
*
* Compute sqrt for N >>
*
CLR.W D0
SWAP D0 do = N/2^16
*
* See if N is 0FFFE0001 or greater; if so return 0FFFFH
* (We know that 0FFFFH squared = 0FFFFE0001H)
*
MOVE.W D0,D2
NEG.W D2
ROXR.W #1,D0
SUBQ.W #2,D2
BHI.B SQRT_200 hi => N < 0FFFE0000H
*
* N = FFFExxxx or FFFFxxxx
*
OR.W D1,D2
BNE.B SQRT_900
SUBQ.W #1,D0
BRA.B SQRT_900
*
* The first guess for bit pair 32/31 = zero
*
SQRT_100
ADD.L D0,D0 move bits b-1 -> b
OR.L D1,D0 all non_zero bit-pairs in b now
MOVE.W #15,D2 b/2 (30 .. 0)
*
* Find the most_significant bit_pair
*
SQRT_110
LSL.L #2,D0 test bit_pair
DBCS D2,SQRT_110 until non-zero bit_pair is found ...
*
* Calculate the first_guess
*
MOVE.L D1,D0 N
LSR.L D2,D0 N/2^i
ADD.W #16,D2 i+16
BSET.L D2,D2 d2hi = 2^i
SWAP D2 d2lo = 2^i
ADD.W D2,D0 extend d0 = N/2^i + 2^i (17 bits)
ROXR.W #1,D0 the first guess ...
*
* Aplly Newton's Method.
*
SQRT_200
MOVE.L D1,D2 N
DIVU D0,D2
ADD.W D2,D0
ROXR.W #1,D0 d0 = 1/2[N/guess1 + guess1] => guess2
*
MOVE.L D1,D2 n
DIVU D0,D2
CMP.W D0,D2 is N/guess2 < guess2 ?
BHS.B SQRT_900 hs => no, guess2 = sqrt
ADD.W D2,D0
ROXR.W #1,D0 guess3
*
MOVE.W D0,D2
MULU.W D2,D2 N**2
CMP.L D1,D2 is this > N ?
BLS.B SQRT_900 ls => sqrt
SUBQ.W #1,D0 guess3-1 = sqrt
*
* Exit _SquareRoot
*
SQRT_900
AND.L #0FFFFH,D0 long();
RESTORE_REGISTERS D2
RTS
================================================
Anybody knows how to define a function unsigned int SquareRoot(unsigned int) out of this and compile the thing as to test it?