⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 recip16.asm

📁 包含几个高效的矢量运算的数学函数
💻 ASM
字号:
;; Vectorized and modified by: Jeff Axelrod
;; Original Version:	Alex Tessarolo

;;===========================================================================
;;
;; Contents:	InvQ15YmYe	; Y = 1/X, X = Q15, Y  = Ym * Ye, 
;;				;                   Ym = Q15, 
;;				;	            Ye = 2^n, n = 1 to 15
;;
;;===========================================================================

;; Usage ASM:	
;;		.bss	inv_X,1		;  8000h to 7FFFh (Q0.15 format)
;;		.bss	inv_Ym,1	;    0.5 to   1	  (Q0.15 format)
;;					; or -1  to -0.5  (Q0.15 format)
;;		.bss	inv_Ye,1	; Ye = 2^n, n = 1,2,...,13,14,15
;;
;;		call	InvQ15YmYe
;;
;;---------------------------------------------------------------------------
;;
;; Input:	inv_X
;;
;; Modifies:	DP
;;		SXM
;;		OVM	
;;		ACC
;;		P
;;		T
;;
;; Output:	inv_Ym
;;		inv_Ye		
;;
;;---------------------------------------------------------------------------
;;
;; Algorithm:	The most optimal method for calculating the inverse of a
;;		fractional number (Y=1/X) is to normalize the number first. 
;;		This limits the range of the number as follows:	
;;
;;			0.5 <= Xnorm <   1		
;;			-1  <= Xnorm <= -0.5			(1)
;;
;;		The resulting equation becomes:
;;
;;			Y = 1/(Xnorm*2^-n)
;;
;;		or	Y = 2^n/Xnorm				(2)
;;
;;			where n = 1,2,3,...,14,15 
;;
;;		Letting Ye = 2^n:
;;
;;			Ye = 2^n				(3)
;;
;;		Substituting (3) into equation (2):
;;
;;			Y = Ye * 1/Xnorm			(4)
;;
;;		Letting Ym = 1/Xnorm:
;;
;;			Ym = 1/Xnorm				(5)
;;
;;		Substituting (5) into equation (4):
;;
;;			Y = Ye * Ym				(6)
;; 	
;;		For the given range of Xnorm, the range of Ym is:
;;
;;			 1 <= Ym <   2
;;			-2 <= Ym <= -1				(7)
;;
;;		To calculate the value of Ym, various options are possible:
;;
;;		(a) Taylor Series Expansion
;;		(b) 2nd,3rd,4th,.. Order Polynomial (Line Of Best Fit)
;;		(c) Successive Approximation
;;
;;		The method chosen in this example is (c). Successive 
;;		approximation yields the most optimum code versus speed 
;;		versus accuracy option. The method outlined below yilds an 
;;		accuracy of 15 bits.
;;
;;		Assume Ym(new) = exact value of 1/Xnorm:
;;		
;;			Ym(new) = 1/Xnorm			(c1)
;;		
;;		or	Ym(new)*X = 1				(c2)
;;
;;		Assume Ym(old) = estimate of value 1/X:
;;
;;			Ym(old)*Xnorm = 1 + Dyx 		
;;
;;		or	Dxy = Ym(old)*Xnorm - 1			(c3)
;;
;;			where Dyx = error in calculation
;;
;;		Assume that Ym(new) and Ym(old) are related as follows:
;;
;;			Ym(new) = Ym(old) - Dy			(c4)
;;
;;			where Dy = difference in values 
;;
;;		Substituting (c2) and (c4) into (c3):
;;		
;;			Ym(old)*Xnorm = Ym(new)*Xnorm + Dxy
;;
;;			(Ym(new) + Dy)*Xnorm = Ym(new)*Xnorm + Dxy
;;
;;			Ym(new)*Xnorm + Dy*Xnorm = Ym(new)*Xnorm + Dxy
;;		
;;			Dy*Xnorm = Dxy			
;;
;;			Dy = Dxy * 1/Xnorm			(c5)
;;
;;		Assume that 1/Xnorm is approximately equal to Ym(old):
;;
;;			Dy = Dxy * Ym(old) (approx)		(c6)
;;
;;		Substituting (c6) into (c4):
;;
;;			Ym(new) = Ym(old) - Dxy*Ym(old)		(c7)
;;
;;		Substituting for Dxy from (c3) into (c7):
;;
;;			Ym(new) = Ym(old) - (Ym(old)*Xnorm - 1)*Ym(old)
;;
;;			Ym(new) = Ym(old) - Ym(old)^2*Xnorm + Ym(old)
;;
;;		     	Ym(new) = 2*Ym(old) - Ym(old)^2*Xnorm 	(c8) 
;;
;;		If after each calculation we equate Ym(old) to Ym(new):
;;
;;			Ym(old) = Ym(new) = Ym
;;		
;;		Then equation (c8) evaluates to:
;;
;;		     +--------------------------+
;;		     |	Ym = 2*Ym - Ym^2*Xnorm 	| 		(c9) 
;;		     +--------------------------+
;;
;;		If we start with an initial estimate of Ym, then equation
;;		(c9) will converge to a solution very rapidly (typically
;;		3 iterations for 16-bit resolution).
;;
;;		The initial estimate can either be obtained from a look up 
;;		table, or from choosing a mid-point, or simply from linear 
;;		interpolation. The method chosen for this problem is the
;;		latter. This is simply accomplished by taking the complement
;;		of the least significant bits of the Xnorm value.
;;
;;===========================================================================


 .text		
				    
InvYeTable:
	.word	0002h		; Ye = 2^1
	.word	0004h		; Ye = 2^2
	.word	0008h		; Ye = 2^3
	.word	0010h		; Ye = 2^4
	.word	0020h		; Ye = 2^5
	.word	0040h		; Ye = 2^6
	.word	0080h		; Ye = 2^7
	.word	0100h		; Ye = 2^8
	.word	0200h		; Ye = 2^9
	.word	0400h		; Ye = 2^10
	.word	0800h		; Ye = 2^11
	.word	1000h		; Ye = 2^12
	.word	2000h		; Ye = 2^13
	.word	4000h		; Ye = 2^14
	.word	8000h		; Ye = 2^15

	.include "ccall.asm"
	
	.def	_ti_recip16
_ti_recip16:
	pre_ccall 4,AR_X,AR_Ym,AR_Ye,AR_N

AR_Xnorm .set AR_Ye ; reuse Ye 
AR_Table .set ar7

	mar *,AR_N	
	mar *-,AR_X

	setc	SXM		; MUST turn sign extension mode on.
					; Note: Overflow mode is off in C.
	setc	OVM		; MUST turn overflow mode on.
	spm	1		; MUST set product shift mode to +1.				

LOOP:
;	lacc	inv_X,16	; Normalize the input value X.
	lacc *+,16,AR_Table
	lar	AR_Table,#InvYeTable
	rpt	#15
	norm *+		; ACCH = X normalized.
	nop
	nop ; pipeline
	mar *,AR_Xnorm
;	sach	inv_Xnorm  	; AR2 points to appropriate Ye value in table.
	sach *,AR_Ym

	sfr			; Estimate the first Ym value.
	xor	#01FFFh,16		
;	sach	inv_Ym
	sach *
				; First iteration:
;	lacc	inv_Ym,15	; Calculate Ym = 2*Ym - Ym^2*X
	lacc *,15
;	lt	inv_Ym
	lt *,AR_Xnorm
;	mpy	inv_Xnorm
	mpy *,AR_Ym
;	sph	inv_Ym
	sph *
;	mpy	inv_Ym
	mpy *
	spac
;	sach	inv_Ym,2
	sach *,2

				; Second iteration:
;	lacc	inv_Ym,15	; Calculate Ym = 2*Ym - Ym^2*X
	lacc *,15
;	lt	inv_Ym
	lt *,AR_Xnorm
;	mpy	inv_Xnorm
	mpy *,AR_Ym
;	sph	inv_Ym
	sph *
;	mpy	inv_Ym
	mpy *
	spac
;	sach	inv_Ym,2
	sach *,2

				; Final iteration:
;	lacc	inv_Ym,15	; Calculate Ym = 2*Ym - Ym^2*X
	lacc *,15
;	lt	inv_Ym
	lt *,AR_Xnorm
;	mpy	inv_Xnorm
	mpy *,AR_Ym
;	sph	inv_Ym
	sph *
;	mpy	inv_Ym
	mpy *
	spac

;	splk	#07000h,inv_Ym	; Make sure that 8000h <= Ym < 7FFFh
	splk	#07000h,*		; Make sure that 8000h <= Ym < 7FFFh
;	add	inv_Ym,16
;	sub	inv_Ym,16
;	sub	inv_Ym,16
;	add	inv_Ym,16
	add	*,16
	sub	*,16
	sub	*,16
	add	*,16
;	sach	inv_Ym,3
	sach *+,3,AR_Ye

	sar	AR_Table,*	; Read Ye value from table.
	lacl	*
	tblr	*+,AR_N	; Ye = *AR2
	
	banz LOOP,AR_X

DONE:
	clrc OVM ; Restore OVM	
	spm	0		; MUST restore product shift mode to 0.
	post_ccall 4

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -