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

📄 ldiv16.asm

📁 CCS3.3自带的TI 5400系列DSP的dsplib文件。文档说明可以在TI公司网站上下载。
💻 ASM
字号:
;***********************************************************
; Version 2.20.01                                           
;***********************************************************
;****************************************************************
;  Function:	ldiv16.asm
;  Description: divide Q31 by Q15 yielding Q15 result
;
;
;  Copyright Texas instruments Inc, 1998
;----------------------------------------------------------------
; Revision History:  
; 1.00Beta - K. Baldwin. Original Beta Release 8/31/98
;****************************************************************
	.mmregs
	.def	_ldiv16
_ldiv16:

;
; Far_mode adjustment
;---------------------------------------------------------------
;
	.if __far_mode
	.asg	1, OFFSET
	.else
	.asg	0, OFFSET
	.endif

;
; Set size of space on stack for preserving save on entry registers
;---------------------------------------------------------------
;

REG_SAVE_SZ	.set 4

;-------------------------------------------------------------------------
; Command-line stack arguments
;-------------------------------------------------------------------------

ARG_Y 		.set 1 + OFFSET + REG_SAVE_SZ
ARG_Z	 	.set 2 + OFFSET + REG_SAVE_SZ
ARG_ZEXP	.set 3 + OFFSET + REG_SAVE_SZ
ARG_N		.set 4 + OFFSET + REG_SAVE_SZ

;-------------------------------------------------------------------------
; ARXY_ means Xmem/Ymem register
;-------------------------------------------------------------------------

AR_Y 		.set ar0 ; Points to SP_INDEX
AR_N 		.set ar1
AR_Z 		.set ar2
AR_X		.set ar3
AR_PROD		.set ar4 
AR_ZEXP 	.set ar5
AR_TABLE 	.set ar7

;-------------------------------------------------------------------------
; Stack local variables
;-------------------------------------------------------------------------

SP_PROD_H 	.set 0
SP_PROD_L       .set 1
SP_XNORM	.set 2
SP_TEMP		.set 3
SP_EXP		.set 4
SP_SIGN         .set 5
SP_MAX_EXP	.set 6

FSZ 		.set 7 ; # of local variables

;-------------------------------------------------------------------------
; Preserve contents registers that will be used by this function
;-------------------------------------------------------------------------

	pshm	ar1				; 1 cycle
	pshm	ar7				; 1 cycle
        PSHM    ST0                                 ; 1 cycle
        PSHM    ST1                                 ; 1 cycle
        RSBX    OVA                                 ; 1 cycle
        RSBX    OVB                                 ; 1 cycle

;-------------------------------------------------------------------------
; Process command-line arguments
;-------------------------------------------------------------------------

	stl	a,*(AR_X)			; 1 cycle
	mvdk	*sp(ARG_Y), AR_Y		; 2 cycles
	mvdk	*sp(ARG_Z),AR_Z			; 2 cycles
	mvdk	*sp(ARG_ZEXP),AR_ZEXP		; 2 cycles

;-------------------------------------------------------------------------	
; N=N-1
;-------------------------------------------------------------------------

	ld	*sp(ARG_N),a			; 1 cycle
	sub	#1,a				; 2 cycles
	stlm	a,AR_N				; 1 cycle

;-------------------------------------------------------------------------
; Can't access local variables before this instruction
; Can't access command-line arguments after this instruction
;-------------------------------------------------------------------------

	frame	#-FSZ				; 1 cycle        
 
;-------------------------------------------------------------------------
; Initialize constants and set arithmetic modes
;-------------------------------------------------------------------------

	ssbx	SXM				; 1 cycle
	ssbx	OVM				; 1 cycle

	ldm	sp, a				; 1 cycle
	add	#SP_PROD_H, a			; 2 cycles
	stlm	a, AR_PROD			; 1 cycle

LOOP:

;-------------------------------------------------------------------------
; Treat all values as positive, preserve sign for inclusion in final result
; Normalize input value to determine initial exponent.
;-------------------------------------------------------------------------

	ld 	*AR_Y+,16,a			; 1 cycle
	exp	a				; 1 cycle
	nop					; 1 cycle
	nop					; 1 cycle
	norm	a				; 1 cycle
	
	ldm	t, b				; 1 cycle
        add	#1, b				; 2 cycles
        stl	b, *AR_ZEXP			; 1 cycle
	sth	a,*sp(SP_XNORM)			; 1 cycle

;---------------------------------------------------------------------------
; The algorithm used in calculating the quotient is to invert the denominator
; and multiply by numerator. The reciprocal of the Q15 number is found by an
; approximation method.
;
;           Ym = 2 * Ym - Ym^2 * X
; where, Ym is the best approximation and X is the normalize value of the
; denominator. The reciprocal converges to 15 bit accuaracy in 3 iterations.
; First approximation is obtained by shifting right by 1.
;---------------------------------------------------------------------------

	sfta	a,-1				; 1 cycle	
	sth	a,*AR_Z				; 1 cycle

;---------------------------------------------------------------------------
; First two iterations:
;---------------------------------------------------------------------------

	.loop 2
	ld *AR_Z,15,a 				; 1 cycle
	ld *AR_Z,t				; 1 cycle
	mpy *sp(SP_XNORM),b			; 1 cycle
	sth b,1,*AR_Z				; 1 cycle
	mpy *AR_Z,b				; 1 cycle
	sub b,1,a				; 1 cycle
	sth a,2,*AR_Z				; 1 cycle
	.endloop

;-------------------------------------------------------------------------
; Final iteration: - this code is same as above loop, except 
; last instruction omitted
;-------------------------------------------------------------------------

	ld *AR_Z,15,a				; 1 cycle 
	ld *AR_Z,t				; 1 cycle
	mpy *sp(SP_XNORM),b			; 1 cycle
	sth b,1,*AR_Z				; 1 cycle
	mpy *AR_Z,b				; 1 cycle
	sub b,1,a				; 1 cycle

;-------------------------------------------------------------------------
; Make sure vlaue is in range 8000h <= Ym <= 7fffh
;-------------------------------------------------------------------------

	st	#07000h,*AR_Z			; 2 cycles	
	add	*AR_Z,16,a			; 1 cycle
	sub	*AR_Z,16,a			; 1 cycle
	sub	*AR_Z,16,a			; 1 cycle
	add	*AR_Z,16,a			; 1 cycle
	
;-------------------------------------------------------------------------
; Adjust sign of result
;-------------------------------------------------------------------------

	sth	a, #3, *AR_Z			; 1 cycle
	nop
	nop
	nop
	nop
	nop
	nop

;-------------------------------------------------------------------------
; Multiply numerator by reciprocal of denominator
;-------------------------------------------------------------------------

	ld	#0, b				; 1 cycle	
	mpy 	*AR_Z, *AR_X+, a		; 1 cycle ; Numerator high  * denominator high
	macsu	*AR_X+, *AR_Z, b		; 1 cycle ; Denominator low * numerator high

	rsbx	sxm				; 1 cycle
	add	b, -16, a			; 1 cycle ; add H + L

	sfta	a, #1, a			; 1 cycle
	ssbx 	sxm				; 1 cycle
	add	#08000h, a			; 2 cycles
	nop
	nop
	nop
	nop
	exp	a				; 1 cycle	     
	ld	#0, b				; 1 cycle		     
	nop					; 1 cycle
	nop
	nop
	nop
	nop
	nop
	nop
	ldm	t, b				; 1 cycle
	neg	b
	nop
	nop
	nop
	nop
        add	*AR_ZEXP, b, b			; 1 cycle
	nop
	nop
	nop
	nop
	nop
	norm	a				; 1 cycle
	bcd	L1, BGT				; 3 cycles
	stlm	b, T				; 1 cycle - delay slot
	nop					; 1 cycle - delay slot
	ld	*(AH), TS, a			; 1 cycle
	ld	#1, b				; 1 cycle
	bd	L2				; 2 cycles
	ld	*(AL), 16, a			; 1 cycle - delay slot
	nop					; 1 cycle - delay slot
	nop
L1:
	ld	#1, b				; 1 cycle
	ld	*(BL),TS,b			; 1 cycle

L2:
	stl	b, *AR_ZEXP			; 1 cycle
	sth	a, *AR_Z+			; 1 cycle

;-------------------------------------------------------------------------
; Check for MAX exponent
;-------------------------------------------------------------------------

	sub	*sp(SP_MAX_EXP), b, a		; 1 cycle
	mar	*AR_ZEXP+			; 1 cycle
	xc	1, AGT				; 1 cycle
	stl	b, *sp(SP_MAX_EXP)		; 1 cycle

	banz	LOOP,*AR_N-			; 4 cycles

;-------------------------------------------------------------------------
; Return to calling program, place MAX exponent value in accumulator A
;-------------------------------------------------------------------------
DONE:
	ld	*sp(SP_MAX_EXP), a		; 1 cycle
	frame	#FSZ				; 1 cycle
        POPM    ST1
        POPM    ST0
	popm	ar7				; 1 cycle
	popm	ar1				; 1 cycle
	.if __far_mode
	fretd					; 4 cycles
	.else
	retd					; 3 cycles
	.endif
	nop
	nop

;end of file. please do not remove. it is left here to ensure that no lines of code are removed by any editor

⌨️ 快捷键说明

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