forked from len0rd/rockbox
added memcmp function to make rockbox compilable with latest gcc versions without using libc
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2304 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
6ac83901a5
commit
306c316433
1 changed files with 113 additions and 0 deletions
113
firmware/common/memcmp.c
Normal file
113
firmware/common/memcmp.c
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
FUNCTION
|
||||||
|
<<memcmp>>---compare two memory areas
|
||||||
|
|
||||||
|
INDEX
|
||||||
|
memcmp
|
||||||
|
|
||||||
|
ANSI_SYNOPSIS
|
||||||
|
#include <string.h>
|
||||||
|
int memcmp(const void *<[s1]>, const void *<[s2]>, size_t <[n]>);
|
||||||
|
|
||||||
|
TRAD_SYNOPSIS
|
||||||
|
#include <string.h>
|
||||||
|
int memcmp(<[s1]>, <[s2]>, <[n]>)
|
||||||
|
void *<[s1]>;
|
||||||
|
void *<[s2]>;
|
||||||
|
size_t <[n]>;
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
This function compares not more than <[n]> characters of the
|
||||||
|
object pointed to by <[s1]> with the object pointed to by <[s2]>.
|
||||||
|
|
||||||
|
|
||||||
|
RETURNS
|
||||||
|
The function returns an integer greater than, equal to or
|
||||||
|
less than zero according to whether the object pointed to by
|
||||||
|
<[s1]> is greater than, equal to or less than the object
|
||||||
|
pointed to by <[s2]>.
|
||||||
|
|
||||||
|
PORTABILITY
|
||||||
|
<<memcmp>> is ANSI C.
|
||||||
|
|
||||||
|
<<memcmp>> requires no supporting OS subroutines.
|
||||||
|
|
||||||
|
QUICKREF
|
||||||
|
memcmp ansi pure
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
|
||||||
|
#define UNALIGNED(X, Y) \
|
||||||
|
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
|
||||||
|
|
||||||
|
/* How many bytes are copied each iteration of the word copy loop. */
|
||||||
|
#define LBLOCKSIZE (sizeof (long))
|
||||||
|
|
||||||
|
/* Threshhold for punting to the byte copier. */
|
||||||
|
#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
|
||||||
|
|
||||||
|
int
|
||||||
|
_DEFUN (memcmp, (m1, m2, n),
|
||||||
|
_CONST _PTR m1 _AND
|
||||||
|
_CONST _PTR m2 _AND
|
||||||
|
size_t n)
|
||||||
|
{
|
||||||
|
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
|
||||||
|
unsigned char *s1 = (unsigned char *) m1;
|
||||||
|
unsigned char *s2 = (unsigned char *) m2;
|
||||||
|
|
||||||
|
while (n--)
|
||||||
|
{
|
||||||
|
if (*s1 != *s2)
|
||||||
|
{
|
||||||
|
return *s1 - *s2;
|
||||||
|
}
|
||||||
|
s1++;
|
||||||
|
s2++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
unsigned char *s1 = (unsigned char *) m1;
|
||||||
|
unsigned char *s2 = (unsigned char *) m2;
|
||||||
|
unsigned long *a1;
|
||||||
|
unsigned long *a2;
|
||||||
|
|
||||||
|
/* If the size is too small, or either pointer is unaligned,
|
||||||
|
then we punt to the byte compare loop. Hopefully this will
|
||||||
|
not turn up in inner loops. */
|
||||||
|
if (!TOO_SMALL(n) && !UNALIGNED(s1,s2))
|
||||||
|
{
|
||||||
|
/* Otherwise, load and compare the blocks of memory one
|
||||||
|
word at a time. */
|
||||||
|
a1 = (unsigned long*) s1;
|
||||||
|
a2 = (unsigned long*) s2;
|
||||||
|
while (n >= LBLOCKSIZE)
|
||||||
|
{
|
||||||
|
if (*a1 != *a2)
|
||||||
|
break;
|
||||||
|
a1++;
|
||||||
|
a2++;
|
||||||
|
n -= LBLOCKSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check m mod LBLOCKSIZE remaining characters */
|
||||||
|
|
||||||
|
s1 = (char*)a1;
|
||||||
|
s2 = (char*)a2;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (n--)
|
||||||
|
{
|
||||||
|
if (*s1 != *s2)
|
||||||
|
return *s1 - *s2;
|
||||||
|
s1++;
|
||||||
|
s2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#endif /* not PREFER_SIZE_OVER_SPEED */
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue