This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] strcmp on ARM needs to treat char as unsigned


On ARM char is unsigned, so strcmp needs to perform the comparison of
differing chars on that basis, for example (char)0xff > (char)0x01.
Unfortunately, the tricks I was playing in one of the sub-cases (both
strings aligned) was slightly too clever and the result was that it
treated chars as signed, but only if the strings had a mutual common
alignment.

I have one more patch, for big-endian strcmp (this function has become
the bane of my life recently), that I'll post shortly.

With acknowledgement to the guys at CodeSourcery, who found this problem
(and most of the others).

Fixed thus:

2009-03-23  Richard Earnshaw  <rearnsha@arm.com>

	* libc/machine/arm/strcmp.c (strcmp): Treat char as unsigned.


Index: strcmp.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/machine/arm/strcmp.c,v
retrieving revision 1.2
diff -p -r1.2 strcmp.c
*** strcmp.c	16 Mar 2009 20:12:30 -0000	1.2
--- strcmp.c	23 Mar 2009 16:23:56 -0000
*************** __attribute__((naked)) strcmp (const cha
*** 112,118 ****
        "it	eq\n\t"
        SHFT2LSB"eq r3, r3, #8\n\t"
        "beq	2b\n\t"
!       "sub	r0, r0, r3, "SHFT2MSB" #24\n\t"
  #ifndef __thumb2__
        "ldr	r4, [sp], #4\n\t"
  #endif
--- 112,137 ----
        "it	eq\n\t"
        SHFT2LSB"eq r3, r3, #8\n\t"
        "beq	2b\n\t"
!       /* On a big-endian machine, r0 contains the desired byte in bits
! 	 0-7; on a little-endian machine they are in bits 24-31.  In
! 	 both cases the other bits in r0 are all zero.  For r3 the
! 	 interesting byte is at the other end of the word, but the
! 	 other bits are not necessarily zero.  We need a signed result
! 	 representing the differnece in the unsigned bytes, so for the
! 	 little-endian case we can't just shift the interesting bits
! 	 up.  */
! #ifdef __ARMEB__
!       "sub	r0, r0, r3, lsr #24\n\t"
! #else
!       "and	r3, r3, #255\n\t"
! #ifdef __thumb2__
!       /* No RSB instruction in Thumb2 */
!       "lsr	r0, r0, #24\n\t"
!       "sub	r0, r0, r3\n\t"
! #else
!       "rsb	r0, r3, r0, lsr #24\n\t"
! #endif
! #endif
  #ifndef __thumb2__
        "ldr	r4, [sp], #4\n\t"
  #endif

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]