📄 maxidx.asm
字号:
;***********************************************************
; Version 2.20.01
;***********************************************************
;****************************************************************
; Function: maxidx
; Description: index of the maximum element of a vector
;
; Copyright Texas instruments Inc, 1998
;----------------------------------------------------------------
; Revision History:
; 1.00, R.Piedra, 8/31/98 - Modified from original TIF 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), xsave ; preserve &x(0)
.asg (1), brcsave ; preserve max index value
.asg (2), max ; preserve max value
.asg (5), ret_addr ; stack description
; x in A
.asg (6 + offset), arg_n
; register usage
.asg ar0, ar_idx ; hold the max index
.asg ar2, ar_x
.asg ar3, ar_max ; pointer to max value location
.asg ar4, ar_brcsave ; pointer to brc value location
.asg ar5, ar_ah ; pointer to a (accumulator)
;****************************************************************
.def _maxidx
.text
_maxidx
PSHM ST0 ; 1 cycle
PSHM ST1 ; 1 cycle
RSBX OVA ; 1 cycle
RSBX OVB ; 1 cycle
; Preserve space for local variables and init ARs
; -----------------------------------------------
frame -1 ; stack space for maxval (1)
mvdm sp, ar_max ; ar_max = pointer to max loc (2)
frame -1 ; stack space for brcval (1)
mvdm sp, ar_brcsave ; ar_brcsave =pointer to brc loc(2)
stm #9h, ar_ah ; ar_ah : pointer to acc ah (2)
frame -1 ; preserve space for xsave (1)
; Get arguments and set modes
; ---------------------------
ssbx sxm ; sign extension on (1)
ld #0,ASM ; clear ASM (1)
stl a,*sp(xsave) ; get ar_x: pointer to x (1)
stlm a, ar_x ; (1)
ld *sp(arg_n),-1, b ; b = n/2 (1)
sub #2,b ; b = n/2-2 (2)
stl b, *ar_brcsave ; *ar_brcsave = n/2 - 2 (1)
sub #1,b ; b = n/2 -3 (2)
stlm b, brc ; brc = n/2 -3 (1)
_start:
dld *ar_x+,b ; bh = x(0) bl = x(1) (1)
dld *ar_x+,a ; ah = x(2) al = x(3) (1)
cmps b, *ar_max ; max = max(x(0), x(1)) (1)
cmps a, *ar_ah ; ah = max(x(2), x(3)) (1)
rptbd eloop-1 ; (2)
sub *ar_ah,*ar_max,b ; compare ah with max in memory (1)
saccd a,*ar_max,bgeq ; overwrite max with ah if ah>maxval (1)
dld *ar_x+,a ; get next 2 inputs (1) 2r
srccd *ar_brcsave,bgeq ; save brc if ah>max (1) 1w
cmps a,*ar_ah ; ah = max(al,ah) (1) 1w
sub *ar_ah,*ar_max,b ; compare ah with max in mem (1) 2r
; pipeline hit: 1w + 1w + 2r in same
; daram block. p7-35 ; of c54x UG
saccd a,*ar_max,bgeq ; overwrite max with ah if ah>max (1)1w
eloop
; Update last ar_brcsave
; ----------------------
ld *sp(arg_n),a ; a = n (1)
nop ; pipeline (2 slots for cond) (1)
xc 2, bgeq ; (1)
st #-1, *ar_brcsave ; (2)
; Check if n even or odd
; ----------------------
; a = n
and #1,a,b ; n = even -> a=0 (2)
; n = odd -> a=1
bc recoveridx, beq ; go to recoveridx if n=even(a=0) (5/3)
sub #1,a ; a = n - 1 (2)
; n = odd --> extra location to check
; ----------------------------------------------
sub *ar_x, *ar_max, b ; bh = x(n-1) - max (1)
; enable this 4 lines if want to recover max value info
; nop ; pipeline (xc 2 slots)
; nop
; xc 1,bgeq ; if max > new value --> skip
; mvdd *ar_x, *ar_max ; last element is new max
; a = n-1 (already )
bc end,bgeq ; if x(n-1) new max, a = n-1 (5/3)
recoveridx:
; n = even (a = n)
; n = odd but x(n-1) is not a new max (a = n-1)
; in both cases info in ar_brcsave
; Recover pair-index value; pair_idx = neg(ar_brc-(nx/2-2)) = nx/2-2-ar_brc
; idx = 2*pair_idx = nx -4 -2*ar_brc
; ----------------------------------------------------------------
sub #4,a ; if even --> a = n - 4 (2)
; if odd --> a = n - 3
sub *ar_brcsave,1,a ; idx = a - 2*ar_brc (2)
; Recover pointer to max value
; ----------------------------
.asg ar_ah,ar_temp
ld *sp(xsave),b ; b = &x (1)
add a,b ; b = idx + &x[0] (1)
stlm b,ar_temp ; ar_temp points to the max pair (1)
nop ; pipeline (1)
nop ; (1)
; Select max element inside pair max(0) max(1)
; --------------------------------------------
dld *ar_temp+,b ; b = max(0) max(1) (1)
nop ; pipeline (1)
; cmps could be deleted(idx return only)
cmps b,*ar_max ; if max(0)>max(1) -> tc=0 (1)
nop ; pipeline(xc 2 slots) (1)
nop ; (1)
xc 2,tc ; (1)
add #1,a ; adjust idx by one if max(1) is max (2)
end:
_end:
frame +3 ; adjust of local vars (1)
POPM ST1
POPM ST0
.if __far_mode
fret ; (6)
.else
ret ; (6)
.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 + -