2007-05-02 01:07:00 +00:00
|
|
|
/*
|
2008-04-25 07:21:17 +00:00
|
|
|
* $Id: mem.c 164 2008-04-24 13:21:17Z baconevi $
|
2007-05-02 01:07:00 +00:00
|
|
|
*
|
|
|
|
* {License}
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <ase/cmn/mem.h>
|
|
|
|
|
2008-04-25 07:08:14 +00:00
|
|
|
#if defined(__SPU__)
|
|
|
|
#include <spu_intrinsics.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*#define IS_UNALIGNED(ptr) (((ase_size_t)ptr)%ASE_SIZEOF(ase_size_t))*/
|
|
|
|
#define IS_UNALIGNED(ptr) (((ase_size_t)ptr)&(ASE_SIZEOF(ase_size_t)-1))
|
2007-12-25 21:25:45 +00:00
|
|
|
#define IS_ALIGNED(ptr) (!IS_UNALIGNED(ptr))
|
|
|
|
|
2007-12-25 21:37:48 +00:00
|
|
|
#define IS_EITHER_UNALIGNED(ptr1,ptr2) \
|
2008-04-25 07:08:14 +00:00
|
|
|
(((ase_size_t)ptr1|(ase_size_t)ptr2)&(ASE_SIZEOF(ase_size_t)-1))
|
2007-12-25 21:37:48 +00:00
|
|
|
#define IS_BOTH_ALIGNED(ptr1,ptr2) (!IS_EITHER_UNALIGNED(ptr1,ptr2))
|
|
|
|
|
2007-05-02 01:07:00 +00:00
|
|
|
void* ase_memcpy (void* dst, const void* src, ase_size_t n)
|
|
|
|
{
|
2008-04-25 06:19:44 +00:00
|
|
|
#if defined(ASE_BUILD_FOR_SIZE)
|
|
|
|
ase_byte_t* d = (ase_byte_t*)dst;
|
|
|
|
ase_byte_t* s = (ase_byte_t*)src;
|
|
|
|
while (n-- > 0) *d++ = *s++;
|
|
|
|
return dst;
|
|
|
|
#else
|
|
|
|
ase_byte_t* d;
|
|
|
|
ase_byte_t* s;
|
2007-12-25 21:25:45 +00:00
|
|
|
|
2008-04-25 07:21:17 +00:00
|
|
|
if (n >= ASE_SIZEOF(ase_size_t) && IS_BOTH_ALIGNED(dst,src))
|
2007-12-25 21:25:45 +00:00
|
|
|
{
|
2008-04-25 07:21:17 +00:00
|
|
|
ase_size_t* du = (ase_size_t*)dst;
|
|
|
|
ase_size_t* su = (ase_size_t*)src;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2008-04-25 07:21:17 +00:00
|
|
|
while (n >= ASE_SIZEOF(ase_size_t))
|
2007-12-25 21:25:45 +00:00
|
|
|
{
|
2008-04-25 06:19:44 +00:00
|
|
|
*du++ = *su++;
|
2008-04-25 07:21:17 +00:00
|
|
|
n -= ASE_SIZEOF(ase_size_t);
|
2007-12-25 21:25:45 +00:00
|
|
|
}
|
|
|
|
|
2008-04-25 06:19:44 +00:00
|
|
|
d = (ase_byte_t*)du;
|
|
|
|
s = (ase_byte_t*)su;
|
2007-12-25 21:25:45 +00:00
|
|
|
}
|
2008-04-25 06:19:44 +00:00
|
|
|
else
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-04-25 06:19:44 +00:00
|
|
|
d = (ase_byte_t*)dst;
|
|
|
|
s = (ase_byte_t*)src;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2008-04-25 06:19:44 +00:00
|
|
|
while (n-- > 0) *d++ = *s++;
|
|
|
|
return dst;
|
|
|
|
#endif
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void* ase_memset (void* dst, int val, ase_size_t n)
|
|
|
|
{
|
2008-04-25 06:19:44 +00:00
|
|
|
#if defined(ASE_BUILD_FOR_SIZE)
|
2008-04-25 07:08:14 +00:00
|
|
|
|
2008-04-25 06:19:44 +00:00
|
|
|
ase_byte_t* d = (ase_byte_t*)dst;
|
|
|
|
while (n-- > 0) *d++ = (ase_byte_t)val;
|
|
|
|
return dst;
|
2008-04-25 07:08:14 +00:00
|
|
|
|
2008-04-25 06:19:44 +00:00
|
|
|
#elif defined(__SPU__)
|
2008-04-25 07:08:14 +00:00
|
|
|
|
|
|
|
/* a vector of 16 unsigned char cells */
|
|
|
|
vector unsigned char v16;
|
|
|
|
/* a pointer to such a vector */
|
|
|
|
vector unsigned char* vd;
|
|
|
|
ase_size_t rem;
|
|
|
|
|
|
|
|
/* fills all 16 unsigned char cells with the same value
|
|
|
|
* no need to use shift and bitwise-or owing to splats */
|
|
|
|
v16 = spu_splats((ase_byte_t)val);
|
|
|
|
|
|
|
|
/* spu SIMD instructions require 16-byte alignment */
|
|
|
|
rem = ((ase_size_t)dst) & (ASE_SIZEOF(v16)-1);
|
|
|
|
if (rem > 0)
|
|
|
|
{
|
|
|
|
ase_byte_t* d = (ase_byte_t*)dst;
|
2008-04-25 07:21:17 +00:00
|
|
|
|
|
|
|
do { *d++ = (ase_byte_t)val; }
|
|
|
|
while (n-- > 0 && ++rem <= ASE_SIZEOF(v16));
|
2008-04-25 07:08:14 +00:00
|
|
|
|
|
|
|
vd = (vector unsigned char*)d;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* do the vector copy */
|
|
|
|
while (n >= ASE_SIZEOF(v16))
|
|
|
|
{
|
|
|
|
*vd++ = v16;
|
|
|
|
n += ASE_SIZEOF(v16);
|
|
|
|
}
|
|
|
|
|
2008-04-25 06:19:44 +00:00
|
|
|
{
|
2008-04-25 07:08:14 +00:00
|
|
|
/* handle the trailing bytes */
|
|
|
|
ase_byte_t* d = (ase_byte_t*)dst;
|
|
|
|
while (n-- > 0) *d++ = (ase_byte_t)val;
|
2008-04-25 06:19:44 +00:00
|
|
|
}
|
|
|
|
|
2008-04-25 07:08:14 +00:00
|
|
|
return dst;
|
|
|
|
|
2008-04-25 06:19:44 +00:00
|
|
|
#else
|
2008-04-25 07:08:14 +00:00
|
|
|
|
2008-04-25 07:21:17 +00:00
|
|
|
ase_byte_t* d = (ase_byte_t*)dst;
|
|
|
|
ase_size_t rem;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2008-04-25 07:21:17 +00:00
|
|
|
rem = IS_UNALIGNED(dst);
|
|
|
|
if (rem > 0)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-04-25 07:21:17 +00:00
|
|
|
d = (ase_byte_t*)dst;
|
|
|
|
do { *d++ = (ase_byte_t)val;
|
|
|
|
printf ("unaligned...\n");
|
|
|
|
}
|
|
|
|
while (n-- > 0 && ++rem <= ASE_SIZEOF(ase_size_t));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n >= ASE_SIZEOF(ase_size_t))
|
|
|
|
{
|
|
|
|
ase_size_t* u = d;
|
|
|
|
ase_size_t uv = 0;
|
2008-04-25 06:19:44 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
if (val != 0)
|
|
|
|
{
|
2008-04-25 07:21:17 +00:00
|
|
|
for (i = 0; i < ASE_SIZEOF(ase_size_t); i++)
|
2008-04-25 06:19:44 +00:00
|
|
|
uv = (uv << 8) | (ase_byte_t)val;
|
|
|
|
}
|
|
|
|
|
2008-04-25 07:21:17 +00:00
|
|
|
while (n >= ASE_SIZEOF(ase_size_t))
|
2008-04-25 06:19:44 +00:00
|
|
|
{
|
2008-04-25 07:21:17 +00:00
|
|
|
printf ("block...\n");
|
2008-04-25 06:19:44 +00:00
|
|
|
*u++ = uv;
|
2008-04-25 07:21:17 +00:00
|
|
|
n -= ASE_SIZEOF(ase_size_t);
|
2008-04-25 06:19:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
d = (ase_byte_t*)u;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2008-04-25 07:21:17 +00:00
|
|
|
printf ("unaligned %lld...\n", (long long)n);
|
2008-04-25 06:19:44 +00:00
|
|
|
while (n-- > 0) *d++ = (ase_byte_t)val;
|
2007-05-02 01:07:00 +00:00
|
|
|
return dst;
|
2008-04-25 07:08:14 +00:00
|
|
|
|
2008-04-25 06:19:44 +00:00
|
|
|
#endif
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int ase_memcmp (const void* s1, const void* s2, ase_size_t n)
|
|
|
|
{
|
2008-04-25 06:19:44 +00:00
|
|
|
#if defined(ASE_BUILD_FOR_SIZE)
|
2007-12-29 06:39:01 +00:00
|
|
|
/*
|
2007-05-02 01:07:00 +00:00
|
|
|
const void* e;
|
|
|
|
|
|
|
|
if (n == 0) return 0;
|
|
|
|
|
|
|
|
e = (const ase_byte_t*)s1 + n - 1;
|
|
|
|
while (s1 < e && *(ase_byte_t*)s1 == *(ase_byte_t*)s2)
|
|
|
|
{
|
|
|
|
s1 = (ase_byte_t*)s1 + 1;
|
|
|
|
s2 = (ase_byte_t*)s2 + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return *((ase_byte_t*)s1) - *((ase_byte_t*)s2);
|
2007-12-29 06:39:01 +00:00
|
|
|
*/
|
|
|
|
|
2008-04-25 06:19:44 +00:00
|
|
|
const ase_byte_t* b1 = (const ase_byte_t*)s1;
|
|
|
|
const ase_byte_t* b2 = (const ase_byte_t*)s2;
|
|
|
|
|
|
|
|
while (n-- > 0)
|
|
|
|
{
|
|
|
|
if (*b1 != *b2) return *b1 - *b2;
|
|
|
|
b1++; b2++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
#else
|
|
|
|
const ase_byte_t* b1;
|
|
|
|
const ase_byte_t* b2;
|
|
|
|
|
2008-04-25 07:21:17 +00:00
|
|
|
if (n >= ASE_SIZEOF(ase_size_t) && IS_BOTH_ALIGNED(s1,s2))
|
2008-04-25 06:19:44 +00:00
|
|
|
{
|
2008-04-25 07:21:17 +00:00
|
|
|
const ase_size_t* u1 = (const ase_size_t*)s1;
|
|
|
|
const ase_size_t* u2 = (const ase_size_t*)s2;
|
2008-04-25 06:19:44 +00:00
|
|
|
|
2008-04-25 07:21:17 +00:00
|
|
|
while (n >= ASE_SIZEOF(ase_size_t))
|
2008-04-25 06:19:44 +00:00
|
|
|
{
|
2008-04-25 06:33:26 +00:00
|
|
|
if (*u1 != *u2) break;
|
2008-04-25 06:19:44 +00:00
|
|
|
u1++; u2++;
|
2008-04-25 07:21:17 +00:00
|
|
|
n -= ASE_SIZEOF(ase_size_t);
|
2008-04-25 06:19:44 +00:00
|
|
|
}
|
2008-04-25 06:33:26 +00:00
|
|
|
|
|
|
|
b1 = (const ase_byte_t*)u1;
|
|
|
|
b2 = (const ase_byte_t*)u2;
|
2008-04-25 06:19:44 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
b1 = (const ase_byte_t*)s1;
|
|
|
|
b2 = (const ase_byte_t*)s2;
|
|
|
|
}
|
2007-12-29 06:39:01 +00:00
|
|
|
|
2008-04-25 06:19:44 +00:00
|
|
|
while (n-- > 0)
|
2007-12-29 06:39:01 +00:00
|
|
|
{
|
2008-04-25 06:19:44 +00:00
|
|
|
if (*b1 != *b2) return *b1 - *b2;
|
|
|
|
b1++; b2++;
|
2007-12-29 06:39:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2008-04-25 06:19:44 +00:00
|
|
|
#endif
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|