Platon Technologies
not logged in Login Registration
EnglishSlovak
open source software development celebrating 10 years of open source development! Thursday, March 28, 2024

File: [Platon] / libplaton / platon / str / strmmx.c (download)

Revision 1.13, Sat Apr 24 10:32:06 2010 UTC (13 years, 11 months ago) by nepto


Changes since 1.12: +28 -6 lines

Avoid MMX-related functions on Sparc

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <platon/str/strmmx.h>

/* Function for align string length to multiple of 8 
 */
static int align(const int n)
{
    return ((n >> 3) + (n % 8 != 0)) << 3;
}

char *PLATON_FUNC(strcpymmx)(void *dest, const void *src)
{
    int len = strlen(src);
    char *ret = PLATON_FUNC(memcpymmx)(dest, src, len);
    ret[len] = '\0';
    return ret;
}

char *PLATON_FUNC(strncpymmx)(void *dest, const void *src, size_t n)
{
    char *ret = PLATON_FUNC(memcpymmx)(dest, src, n);
    ret[n] = '\0';
    return ret;
}

#if defined(__sparc__)

/* XXX: this should be done probably through macros, if possible */

void *PLATON_FUNC(memcpymmx)(void *dest, const void *src, size_t n)
{
    return memcpy(dest, src, n);
}

void *PLATON_FUNC(memsetmmx)(void *s, int c, size_t n)
{
    return memset(s, c, n);
}

int PLATON_FUNC(memcmpmmx)(const void *s1, const void *s2, size_t n)
{
    return memcmp(s1, s2, n);
}

#else

/* Function copy memory regions using MMX */
void *PLATON_FUNC(memcpymmx)(void *dest, const void *src, size_t n)
{
    if ((n % 8) != 0)
        n = align(n);
    n = n >> 3;
    __asm__ __volatile__("1:\n\t"
            "movq (%%eax),%%mm0\n\t"
            "movq %%mm0,(%%ebx)\n\t"
            "addl $8,%%eax\n\t"
            "addl $8,%%ebx\n\t"
            "loop 1b\n\t"::"a"(src), "b"(dest), "c"(n)
            :"memory");
    return dest;
}

/* Function set every item of buffer to char 'c' using MMX */
void *PLATON_FUNC(memsetmmx)(void *s, int c, size_t n)
{
    char set[8];
    set[0] = set[1] = set[2] = set[3] = set[4] = set[5] = set[6] = set[7] = c;
    if ((n % 8) != 0)
        n = align(n);
    n = n >> 3;
    __asm__ __volatile__("movq (%%ebx),%%mm0\n\t"
            "1:\n\t"
            "movq %%mm0,(%%eax)\n\t"
            "addl $8,%%eax\n\t"
            "loop 1b\n\t"::"a"(s), "b"(&set), "c"(n)
            :"memory");
    return s;
}

/* Function compare two memory regions using MMX, returns 0 or 1 */
int PLATON_FUNC(memcmpmmx)(const void *s1, const void *s2, size_t n)
{
    if ((n % 8) != 0)
        n = align(n);
    n = n >> 3;
    __asm__ __volatile__("1:\n\t"
            "movq (%%eax),%%mm0\n\t"
            "movq (%%ebx),%%mm1\n\t"
            "addl $8,%%eax\n\t"
            "addl $8,%%ebx\n\t"
            "pcmpeqw %%mm0,%%mm1\n\t"
            "movd %%mm1,%%edx\n\t"
            "cmpl $0xFFFFFFFF,%%edx\n\t"
            "jne 2f\n\t"
            "loop 1b\n\t"
            "jmp 3f\n\t"
            "2:\n\t"
            "movl $1,%%eax\n\t"
            "leave\n\t"
            "ret\n\t" "3:\n\t"::"a"(s1), "b"(s1), "c"(n));
    return 0;
}

#endif /* #if defined(__sparc__) */

#if defined(SELF) || defined(SELFTEST) || defined(SELF_MMX)

int main(int argc, char *argv[])
{
    char *pole1, *pole2;
    int n, bsize;
    register int i;

    if (argc < 3) {
        fprintf(stderr, "Use: %s <buffersize> <memory>\n", argv[0]);
        return 1;
    }

    bsize = atoi(argv[1]);
    pole1 = (char *) malloc(bsize);
    pole2 = (char *) malloc(bsize);
    n = atoi(argv[2]) / bsize;
    PLATON_FUNC(memsetmmx)(pole1, 'A', bsize);
    for (i = 0; i <= n; i++)
        PLATON_FUNC(memcpymmx)(pole2, pole1, bsize);

    return 0;
}

#endif


Platon Group <platon@platon.org> http://platon.org/
Copyright © 2002-2006 Platon Group
Site powered by Metafox CMS
Go to Top