[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-libc-dev] [ Bug #1720 ] memcmp bug ?
From: |
Marek Michalkiewicz |
Subject: |
Re: [avr-libc-dev] [ Bug #1720 ] memcmp bug ? |
Date: |
Mon, 18 Nov 2002 22:34:38 +0100 (CET) |
> Regarding:
>
> http://savannah.nongnu.org/bugs/?func=detailbug&bug_id=1720&group_id=2140
>
> Is this really a bug?
Both the glibc manual and SUSv2 say that the values compared are
interpreted as unsigned char, then the difference promoted to int.
So I don't think this is a bug.
> I'm leaning toward leaving the behaviour as is, but adding a note in the
> dox explaining the signed nature of the compare operation.
It's unsigned, actually :)
Note that for the example in the bug report:
*s1={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
*s2={0xFF,0x00,0x00,0x00,0x00,0x00};
the result is 0x00FF (carry is cleared, so the high byte is 0) and
this is correct (positive, because s1[1] > s2[2] when compared as
unsigned char).
> If the change should be made, I think it would be the following patch
> (don't sign extend the result). Is this patch correct?
I don't think so. The sign (from subtracting two "unsigned char"
values) is in the carry flag, and _that_ is extended to bits 8-15.
Yes, the result is wrong with -mint8, but fixing that is not so
simple. I guess something like this would work (not tested):
; ...
brcc .memcmp_loop
; strings are equal
clr ret_lo ; needed for the n==0 case
; return 0x0000
.memcmp_non_neg:
clr ret_hi
ret
.memcmp_done:
ldi ret_lo,1
brcc .memcmp_non_neg ; return 0x0001
ldi ret_lo,0xff
ldi ret_hi,0xff
ret ; return 0xFFFF
This way the result is correct as both 8-bit and 16-bit value.
Similar changes would be needed for strcmp() and a few others.
But, this is 5 more instructions than the current version, so
the question how important is to support -mint8 remains...
Marek