Truncated match.
PICList
Thread
'Signed 16-bit Operations'
1997\09\18@140249
by
fdalton
Thanks to all of you who had so much fun answering
my previous stupid newbie question about bit masks.
Now, I am faced with another such question that is
undoubtedly "newbie" as well.
Does anyone have efficient code that will simply
COMPARE two 16-bit SIGNED integers without too
much temporary register usage?
Is there anywhere I can look for the answers to
these kinds of questions so that I don't have to
waste precious LISTSERV bandwidth? There must
be some kind of compendium of all of these bit
banging tricks and routine math operations somewhere.
--
------------------------------------------------------
/\ Frank Dalton (spam_OUTfdaltonTakeThisOuT
pineinst.com)
//\\ Pine Instrument Company
///\\\ 101 Industrial Drive
////\\\\ Grove City, PA 16127
|| (412) 458-6391
|| http://www.pineinst.com
------------------------------------------------------
1997\09\18@153345
by
Walter Banks
All compares on a PIC can be done with just the w register
as the only temporary. On the PIC parts compares in
general sould be done by comparing individual bytes
whenever possible, A little attention to detail is worth it.
I believe the MPC compiler has a total of 55 different
code sequences related to 8 and 16 bit compares.
Walter Banks
> Does anyone have efficient code that will simply
> COMPARE two 16-bit SIGNED integers without too
> much temporary register usage?
1997\09\18@164012
by
Clyde Smith-Stubbs
|
On Thu, Sep 18, 1997 at 01:24:45PM -0400, Frank Dalton wrote:
> Does anyone have efficient code that will simply
> COMPARE two 16-bit SIGNED integers without too
> much temporary register usage?
Not really a newbie question - it's harder than it looks.
I'm giving away the family jools here :-)
The problem is that subtraction of signed numbers can cause
overflow; the solution is to make them unsigned, i.e. add
32768 to each number, thus bringing them into the range 0-65535,
and now you can subtract without fear of overflow, using the carry
flag as the sign of the result. Adding 32768 is as easy as toggling
the most significant bit of the number. Here's sample (compiler-generated)
code for testing i <= j which is actually turned around to be
!(j < i)
;x.c: 6: if(i <= j)
movf _j+1,w ;get the most significant byte
xorlw 128 ;make it an unsigned number
movwf btemp ;save
movf _i+1,w ;ditto the other operand
xorlw 128
subwf btemp,w ;subtract to compare
movf _i,w ;get ready to compare low bytes
btfsc 3,2 ;if hi bytes not equal, we're done
subwf _j,w
btfss 3,0 ;now C bit is set if i <= j
> Is there anywhere I can look for the answers to
> these kinds of questions so that I don't have to
Nope, this is the right place.
Of course you can save all this heartache by using a comp... oops,
better not be too blatant!
Cheers, Clyde
--
Clyde Smith-Stubbs | HI-TECH Software
Email: .....clydeKILLspam
@spam@htsoft.com | Phone Fax
WWW: http://www.htsoft.com/ | USA: (408) 490 2885 (408) 490 2885
PGP: finger clyde
KILLspamhtsoft.com | AUS: +61 7 3354 2411 +61 7 3354 2422
---------------------------------------------------------------------------
ANSI C for the PIC! Now shipping! See http://www.htsoft.com for more info.
1997\09\18@183316
by
John Payson
> ;x.c: 6: if(i <= j)
> movf _j+1,w ;get the most significant byte
> xorlw 128 ;make it an unsigned number
> movwf btemp ;save
> movf _i+1,w ;ditto the other operand
> xorlw 128
> subwf btemp,w ;subtract to compare
> movf _i,w ;get ready to compare low bytes
> btfsc 3,2 ;if hi bytes not equal, we're done
???????
> subwf _j,w
> btfss 3,0 ;now C bit is set if i <= j
Doesn't "movf _i,w" trash Z? Perhaps you mistyped that?
Hmm... my attempt:
movf iH,w
subwf jH,w
btfss Z
goto Comp2
movf iL,w
subwf jL,w
Comp2: ; We've done an unsigned compare to this point.
rrf KZ,w ; KZ=known-zero address
xorwf iH,w
xorwf iL,w
addlw 128
; Carry flag now holds compare result
Probably not the best way, and pre-adding the 128 is certainly the way to
go if at least one of the operands is a temp-value (which can safely be
trashed). But it's still interesting to see some other approaches.
1997\09\18@192249
by
Clyde Smith-Stubbs
|
On Thu, Sep 18, 1997 at 05:19:56PM -0500, John Payson wrote:
> Doesn't "movf _i,w" trash Z? Perhaps you mistyped that?
Yeah, I was being (too) clever. I looked at the compiler output and thought
I could improve on it.
It should have read:
;x.c: 6: if(i <= j)
movf _j+1,w ;get the most significant byte
xorlw 128 ;make it an unsigned number
movwf btemp ;save
movf _i+1,w ;ditto the other operand
xorlw 128
subwf btemp,w ;subtract to compare
btfss 3,2 ;if hi bytes not equal, we're done
goto u15
movf _i,w ;get ready to compare low bytes
subwf _j,w
u15
btfss 3,0 ;now C bit is set if i <= j
Of course when comparing with a constant, the temp location is not
required.
>
>
> Hmm... my attempt:
>
Interesting - same number of instructions, but avoids using the temp
location, but does require the known-zero, which not all PICs have.
Clyde
--
Clyde Smith-Stubbs | HI-TECH Software
Email: .....clydeKILLspam
.....htsoft.com | Phone Fax
WWW: http://www.htsoft.com/ | USA: (408) 490 2885 (408) 490 2885
PGP: finger EraseMEclydespam_OUT
TakeThisOuThtsoft.com | AUS: +61 7 3354 2411 +61 7 3354 2422
---------------------------------------------------------------------------
ANSI C for the PIC! Now shipping! See http://www.htsoft.com for more info.
1997\09\18@213114
by
John Payson
|
> > Hmm... my attempt:
> >
>
> Interesting - same number of instructions, but avoids using the temp
> location, but does require the known-zero, which not all PICs have.
It's true that not all PICs have a hardware known-zero. Nonetheless, you
might want to consider having the compiler allocate one. You could use
the same location to hold things like the loop counter for shifting oper-
ations, the byte counter for structure copying, etc. if you ensured that
it was always zero in the "general" context. In fact, having a loop counter
which is always zero when not in a loop can be useful if your loops have
power-of-two repetition counts (e.g. rather than saying:
movlw 8
movwf KZloop
loop
...
decfsz KZloop
goto loop
you could replace the first two instructions with:
bsf KZloop,3
Note that in addition to the "rrf kz,w" instruction used to read C into the
MSB of W, there is also a very useful "rlf KZ,w" which is very nice when
doing arithmetic:
movf SourceL,w
addwf DestL,w
rlf KZ,w
addwf SourceH,w
addwf DestH,w
Note that the carry out of that instruction sequence won't be valid, but the
trick can be used for the high byte of any multi-byte addition (not generally
useful for subtraction, though). While it "only" saves one cycle per add-
ition, 16-bit additions are probably one of the more common things people will
be doing.
By the way, it's possible to do a 3-cycle add-constant-with-propagating-carry:
; If const == 0, use this
rlf KZ,w
addwf dest
; If const != 255 use this:
rlf KZ,w
addlw const
addwf dest
; If const == 255, use this:
movlw 255
btfss C
addwf dest
All of these lend themselves well to dest=src+const constructs:
; If const == 0, use this
rlf KZ,w
addwf src,w
movwf dest
; If const != 255, use this
rlf KZ,w
addlw const
addwf src,w
movwf dest
; If const == 255, use this
movf source,w
btfss C
addlw 255
movwf dest
I don't think it's possible to do better than those.
1997\09\18@223210
by
Clyde Smith-Stubbs
|
On Thu, Sep 18, 1997 at 07:50:09PM -0500, John Payson wrote:
> It's true that not all PICs have a hardware known-zero. Nonetheless, you
> might want to consider having the compiler allocate one. You could use
The trouble with allocating a RAM location as a zero is that you have
to ensure it is in fact always zero (some of your suggestions make it
non zero temporarily) or be prepared to save and restore it on interrupts.
An easier approach is to use a known-zero location on chips that have it,
and do things other ways on other chips. This is already on our to-do list
(thanks to your earlier suggestions!)
Clyde
--
Clyde Smith-Stubbs | HI-TECH Software
Email: clyde
spam_OUThtsoft.com | Phone Fax
WWW: http://www.htsoft.com/ | USA: (408) 490 2885 (408) 490 2885
PGP: finger @spam@clydeKILLspam
htsoft.com | AUS: +61 7 3354 2411 +61 7 3354 2422
---------------------------------------------------------------------------
ANSI C for the PIC! Now shipping! See http://www.htsoft.com for more info.
1997\09\19@015946
by
John Payson
|
> On Thu, Sep 18, 1997 at 07:50:09PM -0500, John Payson wrote:
>
> > It's true that not all PICs have a hardware known-zero. Nonetheless, you
> > might want to consider having the compiler allocate one. You could use
>
> The trouble with allocating a RAM location as a zero is that you have
> to ensure it is in fact always zero (some of your suggestions make it
> non zero temporarily) or be prepared to save and restore it on interrupts.
Well, there are three approaches:
[1] "CLRF" a certain address at startup and never write to it during
program execution; use that address for nothing else. This may not
pose a problem, since the parts that lack a convenient hardware KZ
generally have a fair bit of RAM. On something like the '622, you
could use $7F; it's hardware-KZ in one page and you could CLRF it
in the other.
[2] Save/restore it during the interrupt routine (kinda a bummer of an
idea, really, but it would be possible)
[3] For that and all other non-hardware compiler temps, allocate a sep-
erate copy for use during ISR's. This would make it necessary to
link in twice any routine that's needed by both an ISR and the main
program, but I wouldn't think that should be a problem. Far better
than saving/restoring a lot of compiler-temp variables.
If you're not well-equipped for [3], I think [1] may be the best way to
go.
> An easier approach is to use a known-zero location on chips that have it,
> and do things other ways on other chips. This is already on our to-do list
> (thanks to your earlier suggestions!)
While I can imagine that a few applications on the 16C74 could have a fit
if you stole a register for use as KZ (to which you never wrote other than
a CLRF on startup) I'd certainly want the ability to have the compiler
generate code using that if I had any RAM at all to spare (after all, any
RAM the compiler doesn't do something with will never be used--EVER).
Perhaps a compiler option?
1997\09\19@175220
by
Eric van Es
John Payson wrote:
> > On Thu, Sep 18, 1997 at 07:50:09PM -0500, John Payson wrote:
> > > It's true that not all PICs have a hardware known-zero.
> Nonetheless, you
> > > might want to consider having the compiler allocate one. You
> could use
Would someone be so kind as to explain what exactly the significance of
a known zero is?
>From what I've seen, I can deduct that you use it as a fixed reference
point to which you can compare all your arithmic and answers?
Cheers!
--
Eric van Es | Cape Town, South Africa
KILLspamvanesKILLspam
ilink.nis.za | http://www.nis.za/~vanes
LOOKING FOR TEMPORARY / HOLIDAY ACCOMODATION?
http://www.nis.za/~vanes/accom.htm
1997\09\19@182230
by
Andrew Warren
|
Eric van Es <RemoveMEPICLISTTakeThisOuT
MITVMA.MIT.EDU> wrote:
> Would someone be so kind as to explain what exactly the significance
> of a known zero [register] is?
Eric:
If you know that a register contains 00, you can often use that
knowledge to optimize your code... For example, let's say that you
want to copy the state of the Carry flag into the W register. Here's
one way:
MOVLW 0 ;Assume that carry's clear, so W = 0.
SKPNC ;If it IS clear, skip ahead.
MOVLW 1 ;Otherwise, W = 1.
If you're REALLY clever, you can do this:
MOVF STATUS,W
ANDLW 00000001B ;Carry flag happens to occupy the LSB
;of the STATUS register.
Both of those solutions, however, take more time and space than the
following, which depends upon the existance of a register known to
contain 00:
RLF KNOWNZERO,W
-Andy
=== Meet other PICLIST members at the Embedded Systems Conference:
=== 6:30 pm on Wednesday, 1 October, at Bytecraft Limited's booth.
===
=== For more information on the Embedded Systems Conference,
=== see: http://www.embedsyscon.com/
=== Andrew Warren - spamBeGonefastfwdspamBeGone
ix.netcom.com
=== Fast Forward Engineering - Vista, California
=== http://www.geocities.com/SiliconValley/2499
1997\09\19@183233
by
John Payson
|
> John Payson wrote:
>
> > > On Thu, Sep 18, 1997 at 07:50:09PM -0500, John Payson wrote:
> > > > It's true that not all PICs have a hardware known-zero.
> > Nonetheless, you
> > > > might want to consider having the compiler allocate one. You
> > could use
>
> Would someone be so kind as to explain what exactly the significance of
> a known zero is?
> >From what I've seen, I can deduct that you use it as a fixed reference
> point to which you can compare all your arithmic and answers?
A known-zero location is useful for the following two instructions:
rlf KZ,w ; W will be 0 if carry clear, 1 if carry set
rrf KZ,w ; W will be 0 if carry clear, 128 if carry set
If you have a loop counter that's always left at zero when you're not
using it, you can replace:
movlw 8
movwf counter
with
bsf counter,3
or likewise for counts of 1, 2, 4, etc. or 255 [use comf or decf]; in
addition, the normal "decfsnz loop" behavior is to loop precisely 256
times if the counter is zero at the start.
1997\09\20@110354
by
mikesmith_oz.nosp*m
On 19 Sep 97 at 11:46, Clyde Smith-Stubbs wrote:
> On Thu, Sep 18, 1997 at 07:50:09PM -0500, John Payson wrote:
>
> > It's true that not all PICs have a hardware known-zero. Nonetheless, you
> > might want to consider having the compiler allocate one. You could use
>
> The trouble with allocating a RAM location as a zero is that you
> have to ensure it is in fact always zero (some of your suggestions
> make it non zero temporarily) or be prepared to save and restore it
> on interrupts.
If it's a hardware KZ, I presume you mean it can't be set Non-Z?
If this is so, how could John Payson's dec loop work, since you
couldn't set it up.
>
> An easier approach is to use a known-zero location on chips that
> have it, and do things other ways on other chips. This is already on
> our to-do list (thanks to your earlier suggestions!)
What are some example KZ's?
MikeS
<mikesmith_oz@nosp*m.relaymail.net>
(remove the you know what before replying)
More... (looser matching)
- Last day of these posts
- In 1997
, 1998 only
- Today
- New search...