| version 1.5, 2002/07/15 18:46:41 |
version 1.6, 2002/07/15 19:38:14 |
|
|
| #include <unistd.h> |
#include <unistd.h> |
| #include "strmmx.h" |
#include "strmmx.h" |
| |
|
| char *strcpymmx(void *dest, const void *src) |
static int align(const int n) |
| { |
{ |
| int len = strlen(src); |
return ((n >> 3) + (n % 8 != 0)) << 3; |
| char *ret = memcpymmx(dest, src, len); |
|
| ret[len] = '\0'; |
|
| return ret; |
|
| } |
} |
| char *strncpymmx(void *dest, const void *src, size_t n) |
|
| |
char *strcpymmx(void *dest, const void *src) |
| { |
{ |
| char *ret = memcpymmx(dest, src, n); |
int len = strlen(src); |
| ret[n] = '\0'; |
char *ret = memcpymmx(dest, src, len); |
| return ret; |
ret[len] = '\0'; |
| |
return ret; |
| } |
} |
| |
char *strncpymmx(void *dest, const void *src, size_t n) |
| static int align(const int n) |
|
| { |
{ |
| return ((n >> 3) + (n % 8 != 0)) << 3; |
char *ret = memcpymmx(dest, src, n); |
| |
ret[n] = '\0'; |
| |
return ret; |
| } |
} |
| |
|
| void *memcpymmx(void *dest, const void *src, size_t n) |
void *memcpymmx(void *dest, const void *src, size_t n) |
| { |
{ |
| if ((n % 8) != 0) |
if ((n % 8) != 0) |
| n = align(n); |
n = align(n); |
| n = n >> 3; |
n = n >> 3; |
| __asm__ __volatile__("1:\n\t" |
__asm__ __volatile__("1:\n\t" |
| "movq (%%eax),%%mm0\n\t" |
"movq (%%eax),%%mm0\n\t" |
| "movq %%mm0,(%%ebx)\n\t" |
"movq %%mm0,(%%ebx)\n\t" |
| "addl $8,%%eax\n\t" |
"addl $8,%%eax\n\t" |
| "addl $8,%%ebx\n\t" |
"addl $8,%%ebx\n\t" |
| "loop 1b\n\t"::"a"(src), "b"(dest), "c"(n) |
"loop 1b\n\t"::"a"(src), "b"(dest), "c"(n) |
| :"memory"); |
:"memory"); |
| return dest; |
return dest; |
| } |
} |
| |
|
| void *memsetmmx(void *s, int c, size_t n) |
void *memsetmmx(void *s, int c, size_t n) |
| { |
{ |
| char set[8]; |
char set[8]; |
| set[0] = set[1] = set[2] = set[3] = set[4] = set[5] = set[6] = set[7] = c; |
set[0] = set[1] = set[2] = set[3] = set[4] = set[5] = set[6] = set[7] = c; |
| if ((n % 8) != 0) |
if ((n % 8) != 0) |
| n = align(n); |
n = align(n); |
| n = n >> 3; |
n = n >> 3; |
| __asm__ __volatile__("movq (%%ebx),%%mm0\n\t" |
__asm__ __volatile__("movq (%%ebx),%%mm0\n\t" |
| "1:\n\t" |
"1:\n\t" |
| "movq %%mm0,(%%eax)\n\t" |
"movq %%mm0,(%%eax)\n\t" |
| "addl $8,%%eax\n\t" |
"addl $8,%%eax\n\t" |
| "loop 1b\n\t"::"a"(s), "b"(&set), "c"(n) |
"loop 1b\n\t"::"a"(s), "b"(&set), "c"(n) |
| :"memory"); |
:"memory"); |
| return s; |
return s; |
| } |
} |
| |
|
| /* function returns only 1 or 0 */ |
/* function returns only 1 or 0 */ |
| int memcmpmmx(const void *s1, const void *s2, size_t n) |
int memcmpmmx(const void *s1, const void *s2, size_t n) |
| { |
{ |
| if ((n % 8) != 0) |
if ((n % 8) != 0) |
| n = align(n); |
n = align(n); |
| n = n >> 3; |
n = n >> 3; |
| __asm__ __volatile__("1:\n\t" |
__asm__ __volatile__("1:\n\t" |
| "movq (%%eax),%%mm0\n\t" |
"movq (%%eax),%%mm0\n\t" |
| "movq (%%ebx),%%mm1\n\t" |
"movq (%%ebx),%%mm1\n\t" |
| "addl $8,%%eax\n\t" |
"addl $8,%%eax\n\t" |
| "addl $8,%%ebx\n\t" |
"addl $8,%%ebx\n\t" |
| "pcmpeqw %%mm0,%%mm1\n\t" |
"pcmpeqw %%mm0,%%mm1\n\t" |
| "movd %%mm1,%%edx\n\t" |
"movd %%mm1,%%edx\n\t" |
| "cmpl $0xFFFFFFFF,%%edx\n\t" |
"cmpl $0xFFFFFFFF,%%edx\n\t" |
| "jne 2f\n\t" |
"jne 2f\n\t" |
| "loop 1b\n\t" |
"loop 1b\n\t" |
| "jmp 3f\n\t" |
"jmp 3f\n\t" |
| "2:\n\t" |
"2:\n\t" |
| "movl $1,%%eax\n\t" |
"movl $1,%%eax\n\t" |
| "leave\n\t" |
"leave\n\t" |
| "ret\n\t" "3:\n\t"::"a"(s1), "b"(s1), "c"(n)); |
"ret\n\t" "3:\n\t"::"a"(s1), "b"(s1), "c"(n)); |
| return 0; |
return 0; |
| } |
} |
| |
|
| #if defined(SELF) || defined(SELFTEST) || defined(SELF_MMX) |
#if defined(SELF) || defined(SELFTEST) || defined(SELF_MMX) |
| Line 86 int memcmpmmx(const void *s1, const void |
|
| Line 86 int memcmpmmx(const void *s1, const void |
|
| /* testujeme memcpymmx */ |
/* testujeme memcpymmx */ |
| int main(int argc, char *argv[]) |
int main(int argc, char *argv[]) |
| { |
{ |
| char *pole1, *pole2; |
char *pole1, *pole2; |
| int n, bsize; |
int n, bsize; |
| register int i; |
register int i; |
| if (argc == 1) { |
|
| fprintf(stderr, "Use: %s buffersize memory\n", argv[0]); |
if (argc < 3) { |
| exit(0); |
fprintf(stderr, "Use: %s <buffersize> <memory>\n", argv[0]); |
| } |
return 1; |
| bsize = atoi(argv[1]); |
} |
| pole1 = (char *) malloc(bsize); |
|
| pole2 = (char *) malloc(bsize); |
bsize = atoi(argv[1]); |
| n = atoi(argv[2]) / bsize; |
pole1 = (char *) malloc(bsize); |
| memsetmmx(pole1, 'A', bsize); |
pole2 = (char *) malloc(bsize); |
| for (i = 0; i <= n; i++) |
n = atoi(argv[2]) / bsize; |
| memcpymmx(pole2, pole1, bsize); |
memsetmmx(pole1, 'A', bsize); |
| exit(0); |
for (i = 0; i <= n; i++) |
| |
memcpymmx(pole2, pole1, bsize); |
| |
|
| |
return 0; |
| } |
} |
| |
|
| #endif |
#endif |