mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-20 11:29:24 +00:00
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1847 91177308-0d34-0410-b5e6-96231b3b80d8
133 lines
3.1 KiB
C
133 lines
3.1 KiB
C
//===-- string.c - String functions for the LLVM libc Library -----*- C -*-===//
|
|
//
|
|
// A lot of this code is ripped gratuitously from glibc and libiberty.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include <stdlib.h>
|
|
void *malloc(unsigned);
|
|
void free(void *);
|
|
|
|
unsigned strlen(const char *Str) {
|
|
int Count = 0;
|
|
while (*Str) { ++Count; ++Str; }
|
|
return Count;
|
|
}
|
|
|
|
char *strdup(const char *str) {
|
|
int Len = strlen(str);
|
|
char *Result = (char*)malloc((Len+1)*sizeof(char));
|
|
memcpy(Result, str, Len+1);
|
|
return Result;
|
|
}
|
|
|
|
char *strcpy(char *s1, const char *s2) {
|
|
while ((*s1++ = *s2++));
|
|
return s1;
|
|
}
|
|
|
|
char *strcat(char *s1, const char *s2) {
|
|
strcpy(s1+strlen(s1), s2);
|
|
return s1;
|
|
}
|
|
|
|
|
|
/* Compare S1 and S2, returning less than, equal to or
|
|
greater than zero if S1 is lexicographically less than,
|
|
equal to or greater than S2. */
|
|
int strcmp (const char *p1, const char *p2) {
|
|
register const unsigned char *s1 = (const unsigned char *) p1;
|
|
register const unsigned char *s2 = (const unsigned char *) p2;
|
|
unsigned char c1, c2;
|
|
|
|
do
|
|
{
|
|
c1 = (unsigned char) *s1++;
|
|
c2 = (unsigned char) *s2++;
|
|
if (c1 == '\0')
|
|
return c1 - c2;
|
|
}
|
|
while (c1 == c2);
|
|
|
|
return c1 - c2;
|
|
}
|
|
|
|
// http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/generic/?cvsroot=glibc
|
|
|
|
typedef unsigned int op_t;
|
|
#define OPSIZ 4
|
|
|
|
void *memset (void *dstpp, int c, size_t len) {
|
|
long long int dstp = (long long int) dstpp;
|
|
|
|
if (len >= 8)
|
|
{
|
|
size_t xlen;
|
|
op_t cccc;
|
|
|
|
cccc = (unsigned char) c;
|
|
cccc |= cccc << 8;
|
|
cccc |= cccc << 16;
|
|
if (OPSIZ > 4)
|
|
/* Do the shift in two steps to avoid warning if long has 32 bits. */
|
|
cccc |= (cccc << 16) << 16;
|
|
|
|
/* There are at least some bytes to set.
|
|
No need to test for LEN == 0 in this alignment loop. */
|
|
while (dstp % OPSIZ != 0)
|
|
{
|
|
((unsigned char *) dstp)[0] = c;
|
|
dstp += 1;
|
|
len -= 1;
|
|
}
|
|
|
|
/* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */
|
|
xlen = len / (OPSIZ * 8);
|
|
while (xlen > 0)
|
|
{
|
|
((op_t *) dstp)[0] = cccc;
|
|
((op_t *) dstp)[1] = cccc;
|
|
((op_t *) dstp)[2] = cccc;
|
|
((op_t *) dstp)[3] = cccc;
|
|
((op_t *) dstp)[4] = cccc;
|
|
((op_t *) dstp)[5] = cccc;
|
|
((op_t *) dstp)[6] = cccc;
|
|
((op_t *) dstp)[7] = cccc;
|
|
dstp += 8 * OPSIZ;
|
|
xlen -= 1;
|
|
}
|
|
len %= OPSIZ * 8;
|
|
|
|
/* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */
|
|
xlen = len / OPSIZ;
|
|
while (xlen > 0)
|
|
{
|
|
((op_t *) dstp)[0] = cccc;
|
|
dstp += OPSIZ;
|
|
xlen -= 1;
|
|
}
|
|
len %= OPSIZ;
|
|
}
|
|
|
|
/* Write the last few bytes. */
|
|
while (len > 0)
|
|
{
|
|
((unsigned char *) dstp)[0] = c;
|
|
dstp += 1;
|
|
len -= 1;
|
|
}
|
|
|
|
return dstpp;
|
|
}
|
|
|
|
void *memcpy(void *dstpp, const void *srcpp, size_t len) {
|
|
char *dstp = (char*)dstpp;
|
|
char *srcp = (char*) srcpp;
|
|
unsigned i;
|
|
|
|
for (i = 0; i < len; ++i)
|
|
dstp[i] = srcp[i];
|
|
|
|
return dstpp;
|
|
}
|