Example #1
0
void* 
Memory::SetBytes(
    void* b, int c, size_t n)
{
    if(n < 1) return NULL;
#if defined(VD_USE_ASMLIB)
    return A_memset(b, c, n);
#else
    return ::memset(b, c, n);
#endif
}
Example #2
0
int main () {

    int ao, bo, os, len;
    int version;
    const int pagesize = 0x1000;  // 4 kbytes
    const int n = 16*pagesize;
    char a[n], b[n], c[n];
    int instrset = InstructionSet();

    // CacheBypassLimit = 5;
    printf("\nmemcpy cache limit = 0x%X, memset cache limit 0x%X\n", 
        (int)GetMemcpyCacheLimit(), (int)GetMemsetCacheLimit());

    printf("\nTest memcpy");

    int i, x = 91;
    for (i=0; i<n; i++) {
        x += 23;
        a[i] = (char)x;
    }

    A_memset(b, -1, n);

    SetMemcpyCacheLimit(0);  // default

#if 1 
    // Test memcpy for correctness
    // Loop through versions
    for (version = 0; version < NUMFUNC; version++) {

        printf("\n%s", DispatchNames[version]);
        if (instrset < isetreq[version]) {
            // instruction set not supported
            printf(" skipped"); continue;
        }

        for (len=0; len<514; len++) {
            for (ao = 0; ao <=20; ao++) {
                for (bo = 0; bo <=32; bo++) {
                    A_memset(b, -1, len+96);
                    (*memcpyTab[version])(b+bo, a+ao, len);
                    if (bo && b[bo-1] != -1) error("A", ao, bo, len);
                    if (b[bo+len] != -1) error("B", ao, bo, len);
                    if (len==0) continue;
                    if (b[bo] != a[ao]) error("C", ao, bo, len);
                    if (b[bo+len-1] != a[ao+len-1]) error("D", ao, bo, len);
                    if (memcmp(b+bo, a+ao, len)) error("E", ao, bo, len);
                }
            }
        }
        // check false memory dependence branches
        len = 300;
        A_memcpy(b, a, 3*pagesize);
        for (ao = pagesize-300; ao < pagesize+200; ao++) {
            for (bo = 3*pagesize; bo <=3*pagesize+33; bo++) {
                A_memset(b+bo-64, -1, len+128);
                (*memcpyTab[version])(b+bo, b+ao, len);
                if (b[bo-1] != -1) error("A1", ao, bo, len);
                if (b[bo+len] != -1) error("B1", ao, bo, len);
                if (memcmp(b+bo, b+ao, len)) error("E1", ao, bo, len);
            }
        }
        // check false memory dependence branches with overlap
        // src > dest and overlap: must copy forwards
        len = pagesize+1000;
        for (ao = 2*pagesize; ao <=2*pagesize+33; ao++) {
            for (bo = pagesize-200; bo < pagesize+300; bo++) {
                A_memcpy(b, a, 4*pagesize);
                A_memcpy(c, a, 4*pagesize);
                (*memcpyTab[version])(b+bo, b+ao, len);
                //memcpy(c+bo, c+ao, len);  // Most library versions of memcpy are actually memmove
                memcpySSE2(c+bo, c+ao, len);            
                if (memcmp(b, c, 4*pagesize)) {
                    error("E2", ao-pagesize, bo-2*pagesize, len);
                }
            }
        }
        // check false memory dependence branches with overlap
        // dest > src and overlap: undefined behavior
#if 1
        len = pagesize+1000;
        for (ao = pagesize-200; ao < pagesize+200; ao++) {
            for (bo = 2*pagesize; bo <=2*pagesize+33; bo++) {
                A_memcpy(b, a, 4*pagesize);
                A_memcpy(c, a, 4*pagesize);
                (*memcpyTab[version])(b+bo, b+ao, len);
                //memcpy(c+bo, c+ao, len);  // MS Most library versions of memcpy are actually memmove
                memcpySSE2(c+bo, c+ao, len);
                if (memcmp(b, c, 4*pagesize)) {
                    error("E3", ao-pagesize, bo-2*pagesize, len);
                }
            }
        }
#endif
    }
    printf("\n\nTest memmove");

    // Test memmove for correctness
    for (i=0; i<n; i++) {
        x += 23;
        a[i] = char(x);
    }

    // Loop through versions
    for (version = 0; version < NUMFUNC; version++) {
        printf("\n%s", DispatchNames[version]);
        if (instrset < isetreq[version]) {
            // instruction set not supported
            printf(" skipped"); continue;
        }

        // move forward
        for (len=0; len<400; len++) {
            for (bo = 0; bo <=33; bo++) {
                for (os = 0; os <= 33; os++) {
                    A_memcpy(b, a, len+100);
                    (*memmoveTab[version])(b+bo+os, b+bo, len);
                    for (i=0; i<bo+os; i++) if (b[i]!=a[i]) error("E", i, bo, os, len);
                    for (i=bo+os; i<bo+os+len; i++) if (b[i] != a[i-os]) error("F", i, bo, os, len);
                    for (;i < bo+os+len+20; i++) if (b[i]!=a[i]) error("G", i, bo, os, len);
                }
            }
        }
        // move backwards
        for (len=0; len<400; len++) {
            for (bo = 0; bo <=33; bo++) {
                for (os = 0; os < 33; os++) {
                    A_memcpy(b, a, len+96);
                    (*memmoveTab[version])(b+bo, b+bo+os, len);
                    for (i=0; i<bo; i++) if (b[i]!=a[i]) error("H", i, bo, os, len);
                    for (i=bo; i<bo+len; i++) if (b[i] != a[i+os]) error("I", i, bo, os, len);
                    for (;i < bo+len+20; i++) if (b[i]!=a[i]) error("J", i, bo, os, len);
                }
            }
        }
    }

    printf("\n\nSame, with non-temporal moves");
    SetMemcpyCacheLimit(1); // bypass cache

    // Loop through versions
    for (version = 0; version < NUMFUNC; version++) {

        printf("\n%s", DispatchNames[version]);
        if (instrset < isetreq[version]) {
            // instruction set not supported
            printf(" skipped"); continue;
        }

        for (len=0; len<514; len++) {
            for (ao = 0; ao <=20; ao++) {
                for (bo = 0; bo <=32; bo++) {
                    A_memset(b, -1, len+96);
                    (*memcpyTab[version])(b+bo, a+ao, len);
                    if (bo && b[bo-1] != -1) error("A", ao, bo, len);
                    if (b[bo+len] != -1) error("B", ao, bo, len);
                    if (len==0) continue;
                    if (b[bo] != a[ao]) error("C", ao, bo, len);
                    if (b[bo+len-1] != a[ao+len-1]) error("D", ao, bo, len);
                    if (memcmp(b+bo, a+ao, len)) error("E", ao, bo, len);
                }
            }
        }
        // check false memory dependence branches
        len = 300;
        A_memcpy(b, a, 3*pagesize);
        for (ao = pagesize-200; ao < pagesize+200; ao++) {
            for (bo = 3*pagesize; bo <=3*pagesize+33; bo++) {
                A_memset(b+bo-64, -1, len+128);
                (*memcpyTab[version])(b+bo, b+ao, len);
                if (b[bo-1] != -1) error("A1", ao, bo, len);
                if (b[bo+len] != -1) error("B1", ao, bo, len);
                if (memcmp(b+bo, b+ao, len)) error("E1", ao, bo, len);
            }
        }
        // check false memory dependence branches with overlap
        // src > dest and overlap: must copy forwards
        len = pagesize+1000;
        for (ao = 2*pagesize; ao <=2*pagesize+33; ao++) {
            for (bo = pagesize-200; bo < pagesize+200; bo++) {
                A_memcpy(b, a, 4*pagesize);
                A_memcpy(c, a, 4*pagesize);
                (*memcpyTab[version])(b+bo, b+ao, len);
                //memcpy(c+bo, c+ao, len);  // Most library versions of memcpy are actually memmove
                memcpySSE2(c+bo, c+ao, len);            
                if (memcmp(b, c, 4*pagesize)) {
                    error("E2", ao-pagesize, bo-2*pagesize, len);
                }
            }
        }
        // (check false memory dependence branches with overlap. skipped)
    }
    printf("\n\nTest memmove");

    // Test memmove for correctness
    for (i=0; i<n; i++) {
        x += 23;
        a[i] = char(x);
    }

    // Loop through versions
    for (version = 0; version < NUMFUNC; version++) {
        printf("\n%s", DispatchNames[version]);
        if (instrset < isetreq[version]) {
            // instruction set not supported
            printf(" skipped"); continue;
        }

        // move forward
        for (len=0; len<400; len++) {
            for (bo = 0; bo <=33; bo++) {
                for (os = 0; os <= 33; os++) {
                    A_memcpy(b, a, len+100);
                    (*memmoveTab[version])(b+bo+os, b+bo, len);
                    for (i=0; i<bo+os; i++) if (b[i]!=a[i]) error("E", i, bo, os, len);
                    for (i=bo+os; i<bo+os+len; i++) if (b[i] != a[i-os]) error("F", i, bo, os, len);
                    for (;i < bo+os+len+20; i++) if (b[i]!=a[i]) error("G", i, bo, os, len);
                }
            }
        }
        // move backwards
        for (len=0; len<400; len++) {
            for (bo = 0; bo <=33; bo++) {
                for (os = 0; os < 33; os++) {
                    A_memcpy(b, a, len+96);
                    (*memmoveTab[version])(b+bo, b+bo+os, len);
                    for (i=0; i<bo; i++) if (b[i]!=a[i]) error("H", i, bo, os, len);
                    for (i=bo; i<bo+len; i++) if (b[i] != a[i+os]) error("I", i, bo, os, len);
                    for (;i < bo+len+20; i++) if (b[i]!=a[i]) error("J", i, bo, os, len);
                }
            }
        }
    }
#endif
    SetMemcpyCacheLimit(0);  // back to default
    SetMemsetCacheLimit(0);

    printf("\n\nTest memset");

    // test memset
    const int val1 = 0x4C, val2 = 0xA2, len2 = 1024;
    for (version = 0; version < MEMSETFUNCS; version++) {
        memsetF * func = memsetTab[version];
        printf("\n%s", memsetNames[version]);
        if (instrset < memsetreq[version]) {
            // instruction set not supported
            printf(" skipped"); continue;
        }
        for (os = 0; os < 34; os++) {
            for (len = 0; len < 500; len++) {
                memset(a, val1, len2);
                memset(a+os, val2, len);
                (*func)(b, val1, len2);
                (*func)(b+os, val2, len);
                if (memcmp(a, b, len2)) {
                    error("MS", version, os, len);
                }
            }
        }
        for (len=0; len<200; len++) {
            for (os = 0; os <= 33; os++) {
                A_memcpy(b, a, len+64);
                A_memset(b+os, 55, len);
                for (i=0; i<os; i++) if (b[i] != a[i]) error("K", i, os, len);
                for (; i<os+len; i++) if (b[i] != 55) error("L", i, os, len);
                for (; i<os+len+17; i++) if (b[i] != a[i]) error("M", i, os, len);
            }
        }
    }

    printf("\n\nSame, with non-temporal moves");
    SetMemsetCacheLimit(1);   // bypass cache

    for (version = 0; version < MEMSETFUNCS; version++) {
        memsetF * func = memsetTab[version];
        printf("\n%s", memsetNames[version]);
        if (instrset < memsetreq[version]) {
            // instruction set not supported
            printf(" skipped"); continue;
        }
        for (os = 0; os < 34; os++) {
            for (len = 0; len < 500; len++) {
                memset(a, val1, len2);
                memset(a+os, val2, len);
                (*func)(b, val1, len2);
                (*func)(b+os, val2, len);
                if (memcmp(a, b, len2)) {
                    error("MS", version, os, len);
                }
            }
        }
    }
    SetMemsetCacheLimit(0);   // back to default

    printf("\n\nTest strlen");

    // test strlen
    for (len=0; len<400; len++) {
        for (os = 0; os <= 32; os++) {
            A_memset(b, 0, len+64);
            A_memset(b+os, 'a', len);
            x = A_strlen(b+os);
            if (x != len) error("N", 0, os, len);
            A_memset(b, 1, len+64);
            b[os+len] = 0;
            x = A_strlen(b+os);
            if (x != len) error("O", 0, os, len);
        }
    }

    printf("\n\nTest strcpy and strcat");

    // test strcpy and strcat
    for (i=0; i<n; i++) {
        x += 23;
        a[i] = char(x) | 1;
    }
    for (len=0; len<400; len++) {
        for (os = 0; os <= 16; os++) {
            for (i=0; i<33; i++) {
                A_memmove(b, a, len+64);
                b[os+len] = 0;
                A_strcpy(c+5, b+os);
                if (A_strlen(c+5) != len) error("P", 0, os, len);
                A_memmove(b+55, a, i+4);
                b[55+i] = 0;
                A_strcat(c+5, b+55);
                if (A_strlen(c+5) != len+i) error("R", 0, os, len);
            }
        }
    }
    printf("\n\nSuccess\n");

    return 0;
}
Example #3
0
int main () {

   // test InstructionSet()
   printf("\nInstructionSet = %i",   InstructionSet());

   // test cpuid_abcd
   int abcd[4]; char s[16];
   cpuid_abcd(abcd, 0);
   *(int*)(s+0) = abcd[1];             // ebx
   *(int*)(s+4) = abcd[3];             // edx
   *(int*)(s+8) = abcd[2];             // ecx
   s[12] = 0;                          // terminate string
   printf("\nVendor string  = %s", s);

   // test ProcessorName()
   printf("\nProcessorName  = %s",   ProcessorName());

   // test CpuType
   int vendor, family, model;
   CpuType(&vendor, &family, &model);
   printf("\nCpuType: vendor %i, family 0x%X, model 0x%X", vendor, family, model);

   // test DataCacheSize
   printf("\nData cache size: L1 %ikb, L2 %ikb, L3 %ikb", 
      (int)DataCacheSize(1)/1024, (int)DataCacheSize(2)/1024, (int)DataCacheSize(3)/1024);
   
   // test ReadTSC()
   ReadTSC();
   int tsc = (int)ReadTSC();
   tsc = (int)ReadTSC() - tsc;
   printf("\nReadTSC takes %i clocks\n\n", tsc);  
   
   // test Round();
   double d;
   for (d = -1; d <= 1; d += 0.5) {
      printf("Round %f = %i = %i\n", d, Round(d), Round(float(d)));
   }

   // Test memory and string functions
   int i, n;
   const int strsize = 256;
   char string1[strsize], string2[strsize];
   const char * teststring = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890 @`'{}[]()<>";

   // Initialize strings
   A_memset(string1, 0, strsize);
   A_memset(string2, 0, strsize);

   // Test A_strcpy, A_strcat, A_strlen
   A_strcpy(string1, teststring);
   n = strsize/(int)A_strlen(teststring);
   for (i = 0; i < n-1; i++) {
      A_strcat(string1, teststring);
   }
   if (A_strlen(string1) != n * A_strlen(teststring)) Failure("A_strcpy, A_strcat, A_strlen");

   // Test A_stricmp
   A_memcpy(string2, string1, strsize);
   string2[4] ^= 0x20;  string1[30] ^= 0x20; // Change case
   if (A_stricmp(string1, string2) != 0)  Failure("A_stricmp");
   string2[8] += 2;  // Make strings different
   if (A_stricmp(string1, string2) >= 0)  Failure("A_stricmp");
   string2[7] -= 2;  // Make strings different
   if (A_stricmp(string1, string2) <= 0)  Failure("A_stricmp");

   // test A_strtolower and A_strtoupper
   A_strcpy(string1, teststring);
   A_strcpy(string2, teststring);
   A_strtolower(string1);
   A_strtoupper(string2);
   printf("\nstring converted to lower and upper case:\n%s\n%s\n%s", 
      teststring, string1, string2);

   // test strspn and strcspn
   int n1, n2;
   const int nset = 4;
   const char * tset[] = {"abc", "", "01234567890123456789", "abcdefghijklmnopqrstuvwxyz"};
   for (i = 0; i < nset; i++) {
      n1 = A_strspn(teststring, tset[i]);
      n2 = strspn(teststring, tset[i]);
      if (n1 != n2) Failure("A_strspn");
      n1 = A_strcspn(teststring, tset[i]);
      n2 = strcspn(teststring, tset[i]);
      if (n1 != n2) Failure("A_strcspn");
   }

   // Test A_memmove with overlapping source and destination
   A_memcpy(string2, string1, strsize);

   A_memcpy(string1+5, string1+12, 12);
   memcpy  (string2+5, string2+12, 12);
   if (A_stricmp(string1, string2) != 0)  Failure("memcpy");

   A_memcpy(string1+5, string1+12, 130);
   memcpy  (string2+5, string2+12, 130);
   if (A_stricmp(string1, string2) != 0)  Failure("memcpy");

   A_memmove(string1+5, string1+2, 12);
   memmove  (string2+5, string2+2, 12);
   if (A_stricmp(string1, string2) != 0)  Failure("A_memmove");

   A_memmove(string1+3, string1+8, 12);
   memmove  (string2+3, string2+8, 12);
   if (A_stricmp(string1, string2) != 0)  Failure("A_memmove");
 
   A_memmove(string1+41, string1+30, 100);
   memmove  (string2+41, string2+30, 100);
   if (A_stricmp(string1, string2) != 0)  Failure("A_memmove");

   A_memmove(string1+32, string1+48, 177);
   memmove  (string2+32, string2+48, 177);
   if (A_stricmp(string1, string2) != 0)  Failure("A_memmove");

   printf("\n\nTests passed OK\n");

   return 0;
}
Example #4
0
/* Asm replacment for memset */
void * __cdecl memset_nontemporal_tt ( void *dest, int c, size_t count )
{
	return A_memset(dest, c, count);
}