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>