Truncated match.
PICList
Thread
'Decrement 4 byte variables, redux'
2000\02\06@023223
by
Rich Leggitt
|
Hi all - with Andy's cool trick I'm down to 10 cycles typical with return
in Z. Any other ideas? - Rich
; given address of 32 bit little-endian counter in W,
; decrement the counter and return Z set if zero
; 99.2% of the time, this takes 10 cycles w/call
dec32 movwf FSR ; FSR -> v
decfsz INDF,f ; v[0]--
goto dec32nz
; here, v[0] just became 0, check the others
incf FSR,f ; get v[1]
movf INDF,w
incf FSR,f ; OR v[2]
iorwf INDF,w
incf FSR,f ; OR v[3]
iorwf INDF,w
return ; return Z set if so
; here, v[0] is non-zero, make sure we return with Z=0
dec32nz clrz ; in case Z was set on entry...
incfsz INDF,w ; now, did v[0] underflow?
return ; no (this is 99.2% path)
incf FSR,f ; yes, advance to v[1]
decfsz INDF,f ; dec v[1]
incfsz INDF,w ; underflow?
return ;
incf FSR,f ; yes, advance to v[2]
decfsz INDF,f ; dec v[2]
incfsz INDF,w ; underflow?
return ;
incf FSR,f ; yes, advance to v[3]
decfsz INDF,f ; dec v[3]
return ; return
return ; in either case
2000\02\06@074322
by
Dmitry Kiryashov
Hi Rich.
incf FSR,F will destroy zero flag.
Let's try to use incfsz FSR,F instead.
WBR Dmitry.
PS. modified variant of your code:
; given address of 32 bit little-endian counter in W,
; decrement the counter and return Z set if zero
; 99.2% of the time, this takes 10 cycles w/call
dec32:
movwf FSR
decfsz INDF,F
goto dec32nz
incf FSR,F
movfw INDF
incf FSR,F
iorwf INDF,W
incf FSR,F
iorwf INDF,W ;get _Z finally
return
dec32nz:
clrz ;set _Z=0
incfsz INDF,W
return
incfsz FSR,F ;doesn't corrupt _Z
decfsz INDF,F
incfsz INDF,W
return
incfsz FSR,F ;...
decfsz INDF,F
incfsz INDF,W
return
incfsz FSR,F ;...
decfsz INDF,F
return
return
2000\02\06@121240
by
Rich Leggitt
On Sun, 6 Feb 2000, Dmitry Kiryashov wrote:
> incf FSR,F will destroy zero flag.
Assuming FSR doesn't roll over, won't it just *clear* the Z flag?
> Let's try to use incfsz FSR,F instead.
Thanks Dmitry - Rich
2000\02\06@180559
by
Dmitry Kiryashov
Hi Rich.
Here is 32bit increment counter. It's a little bit
shorter so it can be used if time|memory is critical.
WBR Dmitry.
inc32:
movwf FSR
clrz
incfsz INDF,F
return
incfsz FSR,F
incfsz INDF,F
return
incfsz FSR,F
incfsz INDF,F
return
incfsz FSR,F
incf INDF,F
return
2000\02\07@131253
by
Scott Dattalo
|
On Sun, 6 Feb 2000, Dmitry Kiryashov wrote:
> Hi Rich.
>
> incf FSR,F will destroy zero flag.
> Let's try to use incfsz FSR,F instead.
>
> WBR Dmitry.
>
>
> PS. modified variant of your code:
>
> ; given address of 32 bit little-endian counter in W,
> ; decrement the counter and return Z set if zero
> ; 99.2% of the time, this takes 10 cycles w/call
actually, it's 13 cycles if you take the call and return into account and
11 cycles w/o call.
{Quote hidden}> dec32:
> movwf FSR
> decfsz INDF,F
> goto dec32nz
>
> incf FSR,F
> movfw INDF
>
> incf FSR,F
> iorwf INDF,W
>
> incf FSR,F
> iorwf INDF,W ;get _Z finally
> return
>
> dec32nz:
> clrz ;set _Z=0
> incfsz INDF,W
> return
>
> incfsz FSR,F ;doesn't corrupt _Z
> decfsz INDF,F
> incfsz INDF,W
> return
>
> incfsz FSR,F ;...
> decfsz INDF,F
> incfsz INDF,W
> return
>
> incfsz FSR,F ;...
> decfsz INDF,F
> return
> return
>
If Dmitry's optimized then chances are nobody can do much better. However,
I thought it'd be interesting to see this same thing done with 18cxxx
instruction set. I know it doesn't help you in the least, but it is
instructional
; 10-16 cycles
dec32:
movwf FSR0L ; the fsr's (three of them) on the 18cxxx
clrf FSR0H ; are 16bits wide
decf POSTINC0,F,1 ;Indirect access that increments the fsr.
bz dec32nz
movf POSTINC0,w,1
iorwf POSTINC0,w,1
iorwf POSTINC0,w,1
return
dec32nz
;decf on the 18cxxx parts affects C
skpc
decf POSTINC0,F,1
skpc
decf POSTINC0,F,1
skpc
decf POSTINC0,F,1
setz
return
There are probably a couple of things you can do to minimize the second
part...
Scott
2000\02\07@161504
by
Rich Leggitt
On Mon, 7 Feb 2000, Scott Dattalo wrote:
> actually, it's 13 cycles if you take the call and return into account and
> 11 cycles w/o call.
Really? What am I missing?
> > dec32: 2 cycles to get here
> > movwf FSR 3 cycles
> > decfsz INDF,F 4 cycles (since no skip)
> > goto dec32nz 6 cycles
> >
...
> > dec32nz:
> > clrz ;set _Z=0 7 cycles
> > incfsz INDF,W 8 cycles (since no skip)
> > return 10 cycles
> >
>
> If Dmitry's optimized then chances are nobody can do much better. However,
> I thought it'd be interesting to see this same thing done with 18cxxx
> instruction set. I know it doesn't help you in the least, but it is
> instructional
Ah, never done 18cxxx before, POSTINC looks useful... :)
- Rich
2000\02\07@170314
by
Rich Leggitt
On Sun, 6 Feb 2000, Dmitry Kiryashov wrote:
> Here is 32bit increment counter. It's a little bit shorter so it can
> be used if time|memory is critical.
Hey, I like it, all I have to do is negate the initial counter value upon
receipt:
neg32: movwf FSR ; 32 bit 2's complement
comf INDF,f ; i.e. invert and increment
incf FSR,f
comf INDF,f
incf FSR,f
comf INDF,f
incf FSR,f
comf INDF,f
; fall thru
inc32:
movwf FSR
clrz
incfsz INDF,F
return
incfsz FSR,F
incfsz INDF,F
return
incfsz FSR,F
incfsz INDF,F
return
incfsz FSR,F
incf INDF,F
return
And as a bonus: negative zero sets Z, so I can dump the code to test for
receipt of a zero count... VERY COOL! Thanks.
- Rich
2000\02\07@183704
by
Scott Dattalo
|
On Mon, 7 Feb 2000, Rich Leggitt wrote:
> On Mon, 7 Feb 2000, Scott Dattalo wrote:
>
> > actually, it's 13 cycles if you take the call and return into account and
> > 11 cycles w/o call.
> Really? What am I missing?
I was counting time along the wrong path of execution. You're right. I
also optimized for the wrong path (and there were two polarity errors with
the Z bit). Okay I got the mistakes out of the way.
dec32:
movwf FSR0L ; the fsr's (three of them) on the 18cxxx
clrf FSR0H ; are 16bits wide
decf POSTINC0,F,1 ;Indirect access that increments the fsr.
bnz dec32nz ;this was bz
;The lsbyte is zero , so we don't need to propogate the borrow
;but we need to see if the higher bytes are zero.
movf POSTINC0,w,1 ;The first byte is zero
iorwf POSTINC0,w,1 ;check the next three
iorwf POSTINC0,w,1
return
dec32nz
;decf on the 18cxxx parts affects C
skpnc
return
decf POSINC0,F,1
skpc
decf POSTINC0,F,1
skpc
decf POSTINC0,F,1
clrz ;was setz
return
-------------
On Mon, 7 Feb 2000, Rich Leggitt wrote:
> On Sun, 6 Feb 2000, Dmitry Kiryashov wrote:
>
> > Here is 32bit increment counter. It's a little bit shorter so it can
> > be used if time|memory is critical.
>
> Hey, I like it, all I have to do is negate the initial counter value
upon
{Quote hidden}> receipt:
>
> neg32: movwf FSR ; 32 bit 2's complement
> comf INDF,f ; i.e. invert and increment
> incf FSR,f
> comf INDF,f
> incf FSR,f
> comf INDF,f
> incf FSR,f
> comf INDF,f
> ; fall thru
> inc32:
> movwf FSR
> clrz
> incfsz INDF,F
> return
> incfsz FSR,F
> incfsz INDF,F
> return
> incfsz FSR,F
> incfsz INDF,F
> return
> incfsz FSR,F
> incf INDF,F
> return
this would look like:
neg32:
movwf fsr0l
clrf fsr0h
comf postinc0,f,1
comf postinc0,f,1
comf postinc0,f,1
comf postinc0,f,1
inc32:
movwf fsr0l
clrf fsr0h
clrz
incfsz postinc0,f,1
return
incfsz postinc0,f,1
return
incfsz postinc0,f,1
return
incf postinc0,f,1
return
another way:
inc32:
movwf fsr0l
clrf fsr0h
subwf wreg,w,1 ;zero W and set the carry
addwfc postinc0,f,1
addwfc postinc0,f,1
addwfc postinc0,f,1
addwfc indf0,f,1
movf postdec0,w,1
iorwf postdec0,w,1
iorwf postdec0,w,1
iorwf indf0,w,1
return
but it's a cycle longer. (but it's isochronous, and could be cascaded
since fsr0 points to the beginning byte).
Scott
More... (looser matching)
- Last day of these posts
- In 2000
, 2001 only
- Today
- New search...