strncmp issue
venki kaps
venkiece2005 at gmail.com
Tue May 5 10:20:35 UTC 2009
Conditional compares are difficult but compilers are very good at:
if (len == 0) return 0;
cmp r2, 0
moveq r0, #0
moveq pc, lr
while (r0 = *s1++, r1 = *s2++, ip = r0 + len; ip == r0 && r0 >= 1 && r0 ==
r1);
add ip, r0, r2
loop
ldrb r0, [s1],#1
ldrb r1, [s2],#1
cmp ip, r0
cmp r0,#1
cmpcs r0,r1
beq loop
subroutine here
Regards,
Venkappa
On Tue, May 5, 2009 at 12:34 PM, venki kaps <venkiece2005 at gmail.com> wrote:
> Hi,
>
> I have tested strncmp("abcdefg", "abcdefh", 6) without beq 2f.
> It returns zero not -1.
>
> I have checked with conditional assembler but not normal assembler.
> The beq 2f is required for normal assembler.
> Right/Wrong?
>
> However also checked with strncmp.c implementation:
>
> int strnncmp(const char *s1, const char *s2, size_t n) {
> if (n == 0)
> return (0);
> do {
> if (*s1 != *s2++)
> return (*(const unsigned char *)s1 -
> *(const unsigned char *)--s2);
> if (*s1++ == 0)
> break;
> } while (--n != 0);
> return (0);
> }
> the equivalent assembly code:
>
> cmp r2, #0
> mov ip, r0
> beq 2f
> 1:
> ldrb r0, [ip, #0]
> ldrb r3, [r1], #1
> add ip, ip, #1
> cmp r0, r3
> bne 3f
> cmp r0, #0
> beq 2f
> subs r2, r2, #1
> bne 1b
> 2:
> mov r0, #0
> mov pc, lr
> 3:
> ldrb r3, [r1, #-1]
> rsb r0, r3, r0 /* operand2 - operand1 */
> mov pc, lr
>
> The results are same.
>
> what could you suggest?
>
> Thanks & Regards,
> Venkappa
>
> On Mon, May 4, 2009 at 6:29 PM, Mark Tinguely <tinguely at casselton.net>wrote:
>
>>
>> Hi, the propose code by both of you two:
>>
>> /* if (len == 0) return 0 */
>> cmp r2, #0
>> moveq r0, #0
>> moveq pc, lr
>>
>> /* ip == last src address to compare */
>> add ip, r0, r2
>> 1:
>> ldrb r2, [r0], #1
>> ldrb r3, [r1], #1
>> cmp ip, r0
>> cmp r2, #1
>> cmpcs r2, r3
>> beq 1b
>> sub r0, r2, r3
>>
>> That was one of my failed attempts. I to was hoping to not add the branch
>> to cut down in cycles. A person has to test every possible call to
>> strncmp.
>> This will fail on a positive string length less than strlen length of the
>> input strings:
>>
>> strncmp("abcdefg", "abcdefh", 6)
>>
>> Will return (-1) str1 < str2 at 6 characters which is wrong.
>>
>>
>> /* if (len == 0) return 0 */
>> cmp r2, #0
>> moveq r0, #0
>> moveq pc, lr
>>
>> /* ip == last src address to compare */
>> add ip, r0, r2
>> 1:
>> ldrb r2, [r0], #1
>> ldrb r3, [r1], #1
>> cmp ip, r0
>> beq 2f <- stops in the case where strlen(s1) > len
>> cmp r2, #1 <- stops thea NULL case, we can't just
>> change
>> the comparison because below we loop on
>> an equality and can end up in a big loop
>>
>> cmpcs r2, r3 <- compare characters.
>> beq 1b
>> 2:
>> sub r0, r2, r3
>>
>>
>
More information about the freebsd-arm
mailing list