
; ============================================================================
; File: isqr.asm
; Desc: Fast cycle integer 32 bit square root with 16 bit result 
; Auth: Coded by Kevin Weatherman April, 2003
;       Based on method by Wilco Dijkstra @ Advanced RISC Machines, Ltd.
;
; ============================================================================

; - GBA -
; Time: constant 51 cycles from IWRAM. Vs 594 cycles for BIOS,SWI 8, Sqrt()!
; In ROM (32 bit ARM) default wait states, w/ prefetch on is 386 cycles
; Size: 208 bytes
;

		AREA   |isqrt_asm$$code|, CODE
		EXPORT isqrt

		CODE32
		ALIGN

N		RN R0
Offset	RN R1
Root	RN R2

; Entry 
isqrt 	MOV     Offset,#(3 << 30)
		MOV     Root,#(1 << 30)

		CMP		N,Root
		SUBHS	N,N,Root
		ADC		Root,Offset,Root,LSL #1

		CMP		N,Root,ROR #(2 * 1)
		SUBHS	N,N,Root,ROR #(2 * 1)
		ADC		Root,Offset,Root,LSL #1

		CMP		N,Root,ROR #(2 * 2)
		SUBHS	N,N,Root,ROR #(2 * 2)
		ADC		Root,Offset,Root,LSL #1

		CMP		N,Root,ROR #(2 * 3)
		SUBHS	N,N,Root,ROR #(2 * 3)
		ADC		Root,Offset,Root,LSL #1

		CMP		N,Root,ROR #(2 * 4)
		SUBHS	N,N,Root,ROR #(2 * 4)
		ADC		Root,Offset,Root,LSL #1

		CMP		N,Root,ROR #(2 * 5)
		SUBHS	N,N,Root,ROR #(2 * 5)
		ADC		Root,Offset,Root,LSL #1

		CMP		N,Root,ROR #(2 * 6)
		SUBHS	N,N,Root,ROR #(2 * 6)
		ADC		Root,Offset,Root,LSL #1

		CMP		N,Root,ROR #(2 * 7)
		SUBHS	N,N,Root,ROR #(2 * 7)
		ADC		Root,Offset,Root,LSL #1

		CMP		N,Root,ROR #(2 * 8)
		SUBHS	N,N,Root,ROR #(2 * 8)
		ADC		Root,Offset,Root,LSL #1

		CMP		N,Root,ROR #(2 * 9)
		SUBHS	N,N,Root,ROR #(2 * 9)
		ADC		Root,Offset,Root,LSL #1

		CMP		N,Root,ROR #(2 * 10)
		SUBHS	N,N,Root,ROR #(2 * 10)
		ADC		Root,Offset,Root,LSL #1

		CMP		N,Root,ROR #(2 * 11)
		SUBHS	N,N,Root,ROR #(2 * 11)
		ADC		Root,Offset,Root,LSL #1

		CMP		N,Root,ROR #(2 * 12)
		SUBHS	N,N,Root,ROR #(2 * 12)
		ADC		Root,Offset,Root,LSL #1

		CMP		N,Root,ROR #(2 * 13)
		SUBHS	N,N,Root,ROR #(2 * 13)
		ADC		Root,Offset,Root,LSL #1

		CMP		N,Root,ROR #(2 * 14)
		SUBHS	N,N,Root,ROR #(2 * 14)
		ADC		Root,Offset,Root,LSL #1

		CMP		N,Root,ROR #(2 * 15)
		SUBHS	N,N,Root,ROR #(2 * 15)
		ADC		Root,Offset,Root,LSL #1

		; Rounding
		IF :DEF:USE_ROUNDING
	    CMP     N,Root
	    ADC     Root,Root,#1
		ENDIF

		BIC     N,Root,#(3 << 30)

		BX      LR
		END
