Date: Mon, 4 May 2009 12:33:45 +0530 From: venki kaps <venkiece2005@gmail.com> To: tinguely@casselton.net Cc: freebsd-arm@freebsd.org Subject: Regarding strncmp fix Message-ID: <6d53329e0905040003sf72dddax16512347142ade3c@mail.gmail.com>
next in thread | raw e-mail | index | archive | help
Hi, This is my idea only. strncmp problem report: ======================== In the following below website: *http://archive.netbsd.se/?ml=freebsd-arm&a=2009-04&m=10547557* Hi, I am using the freebsd implementation of strncmp for ARM which is an assembly implementation. I have a small doubt, when i tested the strncmp by passing the third argument: 'n' as -1 the return values is '0' instead it should '-1'. When the third argument to strncmp is as below: ret = strncmp("a","b",-1) I think the assembly implementation in > src/lib/libc/arm/string/strncmp.S file needs to be modified to take care of the above condition. In the current implementation /* if ((len - 1) subs r2, r2, #1 movmi r0, #0 RETc(mi) This should be changed to check as below /* if ((len ) /* Assembly code here */ FreeBSD source: =============== ENTRY(strncmp) /* if ((len - 1) < 0) return 0 */ subs r2, r2, #1 movmi r0, #0 RETc(mi) /* ip == last src address to compare */ add ip, r0, r2 1: ldrb r2, [r0], #1 ldrb r3, [r1], #1 cmp ip, r0 cmpcs r2, #1 cmpcs r2, r3 beq 1b sub r0, r2, r3 RET Tinguely has given one solution for this: ENTRY(strncmp) /* if (len == 0) return 0 */ cmp r2, #0 moveq r0, #0 RETeq /* ip == last src address to compare */ add ip, r0, r2 1: ldrb r2, [r0], #1 ldrb r3, [r1], #1 cmp ip, r0 - cmpcs r2, #1 + beq 2f + cmp r2, #1 cmpcs r2, r3 beq 1b +2: sub r0, r2, r3 RET The above fix is nice. But small change in the fix: ENTRY(strncmp) /* if (len == 0) return 0 */ cmp r2, #0 moveq r0, #0 RETeq /* ip == last src address to compare */ add ip, r0, r2 1: ldrb r2, [r0], #1 ldrb r3, [r1], #1 cmp ip, r0 - cmpcs r2, #1 + cmp r2, #1 /* to igonre Carry falg set (unsigned higher or same) */ cmpcs r2, r3 beq 1b sub r0, r2, r3 RET Branch to 2f is not required since conditional assemblers automatically calls subroutine when compare fails. And also we can reduce no. of cycles(3 cycles) since 3 cycles required to branch. But I have one smaller query: Will it support the above code in the ARM-thumb mode? NOTE: Thumb mode and traditional mode instruction sets are different. Thumb mode implementation: /* if (len == 0) return 0 */ cmp r2, #0 bne 1f mov r0, #0 RET 1: /* ip == last src address to compare */ add ip, r0, r2 2: cmp ip, r0 beq 3f ldrb r2, [r0] add r0, r0, #1 ldrb r3, [r1] add r1, r1, #1 cmp r2, #0 beq 3f cmp r2, r3 beq 2b 3: sub r0, r2, r3 RET Will need to support both thumb mode as well as traditional mode? Example: #ifdef __thumb__ /* thumb code here */ #else /* traditional code here */ #endif Thanks & Regards, Venkappa
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6d53329e0905040003sf72dddax16512347142ade3c>