📄 add.asm
字号:
;***********************************************************
; Version 2.20.01
;***********************************************************
;*****************************************************************************
; Function: add.asm
; Description: vector add
;
; Copyright Texas instruments Inc, 1998
;-----------------------------------------------------------------------------
; Revision History:
; 1.00 R. Piedra, 8/31/98. Original version
; 2.00 - Li Yuan, 4/09/02. fixed overflow flag setup at the end of code.
;
;*****************************************************************************
.mmregs
; Far-mode adjustment
.if __far_mode
offset .set 1 ; far mode uses one extra location for ret addr ll
.else
offset .set 0
.endif
.asg (0), ret_addr
; x in A
.asg (3 + offset), arg_y
.asg (4 + offset), arg_z
.asg (5 + offset), arg_n
.asg (6 + offset), arg_scale
; register usage
; ar0: addr. idx
.asg ar2, ar_x
.asg ar3, ar_y
.asg ar4, ar_z
.asg ar5, ar_temp
;*****************************************************************************
.def _add
.text
_add
; Preserve registers
;-------------------
PSHM ST0 ; 1 cycle
PSHM ST1 ; 1 cycle
RSBX OVA ; 1 cycle
RSBX OVB ; 1 cycle
ssbx sxm ; sign extension on (1)
ld #0,ASM ; clear ASM (st||ld) (1)
stm #0,bk ; bk = 0 (1)
; Get arguments
;--------------
stlm a, ar_x ; pointer to x (1)
mvdk *sp(arg_y),*(ar_y) ; pointer to y (2)
mvdk *sp(arg_z),*(ar_z) ; pointer to z (2)
ld *sp(arg_scale),b ; b = scale parameter (1)
ld *sp(arg_n),-1,a ; a = n/2 (1)
sub #2,a ; (2)
stlm a, brc ; brc = n/2 -2 (1)
xc 1, bneq ; if a=0 (no scaling) skip (1)
ld #-1,ASM ; ASM = -1 --> div by 2 (1)
ld *sp(arg_n), a ; a = n (1)
stm #3,ar0 ; array index (2)
; Compute z(0) and z(1) outside
; -----------------------------
_start:
add *ar_x+, *ar_y+,a ; ah = x(0) + y(0) (1)
sth a, ASM, *ar_z+ ; z(0) = x(0) + y(0) (1)
; Compute (n/2) -1 elements
; -------------------------
rptbd eloop-1 ; (2)
add *ar_x+, *ar_y+,a ; ah = x(1) + y(1) (1)
mar *ar_x+ ; points to x(3), y(2), z(1) (1)
st a,*ar_z+ ; write z(1) (1)
|| ld *ar_x-,B ; bh = x(3) and point to x(2)
add *ar_x+0%,*ar_y+,a ; ah = x(2) + y(2) (1)
; point to x(5), y(3)
st a,*ar_z+ ; write z(2) (1)
|| add *ar_y+,a ; ah = (b=x(3)) + y(3)
eloop
; for n=4 or 5 --> points to y(4), z(3) x(5)
; Store last computed element
; ---------------------------
sth a, ASM, *ar_z+ ; store last output z(3) (1)
; Check if n is even
; ------------------
ld *sp(arg_n),a ; (1)
and #1,a ; (1)
bc end, aeq ; if a=0 --> even , then done (5;taken)
; (3;notaken)
; If n is odd, one more element to compute
; ----------------------------------------
mar *ar_x- ; point to last x(n-1) (1)
add *ar_x, *ar_y, a ; if n=5 --> a = x(4) + a(4) (1)
sth a, ASM, *ar_z+ ; (1)
; Return
;--------
end:
_end
ld #0,a ; (1)
xc 1, AOV ; return overflow flag (2)
ld #1,a ; (1)
POPM ST1 ; 1 cycle
POPM ST0 ; 1 cycle
.if __far_mode
fret ; (6)
.else
ret ; (5)
.endif
;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 + -