Regarding strncmp fix
venki kaps
venkiece2005 at gmail.com
Mon May 4 07:27:05 UTC 2009
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
More information about the freebsd-arm
mailing list