Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 May 2009 15:50:33 +0530
From:      venki kaps <venkiece2005@gmail.com>
To:        Mark Tinguely <tinguely@casselton.net>
Cc:        channa.kad@gmail.com, freebsd-arm@freebsd.org
Subject:   Re: strncmp issue
Message-ID:  <6d53329e0905050320q5c7480e9h4bcb629222fce16@mail.gmail.com>
In-Reply-To: <6d53329e0905050004k27d957bve15d37113b5fedbb@mail.gmail.com>
References:  <515c64960905032352j25edfbcajb3d146fa769b97bb@mail.gmail.com> <200905041259.n44CxtV2077931@casselton.net> <6d53329e0905050004k27d957bve15d37113b5fedbb@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
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@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@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
>>
>>
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6d53329e0905050320q5c7480e9h4bcb629222fce16>