]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Make this test work on PowerPC too.
authorJulian Seward <jseward@acm.org>
Sat, 4 Jul 2009 14:33:53 +0000 (14:33 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 4 Jul 2009 14:33:53 +0000 (14:33 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10412

memcheck/tests/Makefile.am
memcheck/tests/atomic_incs.c

index b7e6a8fd64896bc24241c8bead33d4dfbe22ee0b..212ca0f43248f6ad4abe2481edff1d802058e017 100644 (file)
@@ -185,6 +185,7 @@ EXTRA_DIST = \
 
 check_PROGRAMS = \
        addressable \
+       atomic_incs \
        badaddrvalue badfree badjump badjump2 \
        badloop badpoll badrw brk2 buflen_check \
        clientperm custom_alloc \
@@ -230,10 +231,6 @@ check_PROGRAMS = \
        wrap1 wrap2 wrap3 wrap4 wrap5 wrap6 wrap7 wrap7so.so wrap8 \
        writev
 
-if VGCONF_ARCHS_INCLUDE_X86
-check_PROGRAMS += atomic_incs
-endif
-
 
 AM_CFLAGS   += $(AM_FLAG_M3264_PRI)
 AM_CXXFLAGS += $(AM_FLAG_M3264_PRI)
index 07d6a066847b9d2c68815b331617ad394ed6e7ee..a9b71e8375e81146e73d13bf84bebd3e36a00280 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 #include <assert.h>
 #include <unistd.h>
 #include <sys/wait.h>
 
 #define NNN 3456987
 
+#define IS_8_ALIGNED(_ptr)   (0 == (((unsigned long)(_ptr)) & 7))
+
+
 __attribute__((noinline)) void atomic_add_8bit ( char* p, int n ) 
 {
+#if defined(VGA_x86)
    unsigned long block[2];
    block[0] = (unsigned long)p;
    block[1] = n;
-#if defined(VGA_x86)
    __asm__ __volatile__(
       "movl 0(%%esi),%%eax"      "\n\t"
       "movl 4(%%esi),%%ebx"      "\n\t"
@@ -27,23 +31,61 @@ __attribute__((noinline)) void atomic_add_8bit ( char* p, int n )
       : : "S"(&block[0])/* S means "esi only" */ : "memory","cc","eax","ebx"
    );
 #elif defined(VGA_amd64)
+   unsigned long block[2];
+   block[0] = (unsigned long)p;
+   block[1] = n;
    __asm__ __volatile__(
       "movq 0(%%rsi),%%rax"      "\n\t"
       "movq 8(%%rsi),%%rbx"      "\n\t"
       "lock; addb %%bl,(%%rax)"  "\n"
       : : "S"(&block[0])/* S means "rsi only" */ : "memory","cc","rax","rbx"
    );
+#elif defined(VGA_ppc32)
+   /* Nasty hack.  Does correctly atomically do *p += n, but only if p
+      is 8-aligned -- guaranteed by caller. */
+   unsigned long success;
+   do {
+      __asm__ __volatile__(
+         "lwarx  15,0,%1"    "\n\t"
+         "add    15,15,%2"   "\n\t"
+         "stwcx. 15,0,%1"    "\n\t"
+         "mfcr   %0"         "\n\t"
+         "srwi   %0,%0,29"   "\n\t"
+         "andi.  %0,%0,1"    "\n"
+         : /*out*/"=b"(success)
+         : /*in*/ "b"(p), "b"(((unsigned long)n) << 24)
+         : /*trash*/ "memory", "cc", "r15"
+      );
+   } while (success != 1);
+#elif defined(VGA_ppc64)
+   /* Nasty hack.  Does correctly atomically do *p += n, but only if p
+      is 8-aligned -- guaranteed by caller. */
+   unsigned long success;
+   do {
+      __asm__ __volatile__(
+         "ldarx  15,0,%1"    "\n\t"
+         "add    15,15,%2"   "\n\t"
+         "stdcx. 15,0,%1"    "\n\t"
+         "mfcr   %0"         "\n\t"
+         "srwi   %0,%0,29"   "\n\t"
+         "andi.  %0,%0,1"    "\n"
+         : /*out*/"=b"(success)
+         : /*in*/ "b"(p), "b"(((unsigned long)n) << 56)
+         : /*trash*/ "memory", "cc", "r15"
+      );
+   } while (success != 1);
 #else
 # error "Unsupported arch"
 #endif
 }
 
+
 __attribute__((noinline)) void atomic_add_16bit ( short* p, int n ) 
 {
+#if defined(VGA_x86)
    unsigned long block[2];
    block[0] = (unsigned long)p;
    block[1] = n;
-#if defined(VGA_x86)
    __asm__ __volatile__(
       "movl 0(%%esi),%%eax"      "\n\t"
       "movl 4(%%esi),%%ebx"      "\n\t"
@@ -51,12 +93,49 @@ __attribute__((noinline)) void atomic_add_16bit ( short* p, int n )
       : : "S"(&block[0])/* S means "esi only" */ : "memory","cc","eax","ebx"
    );
 #elif defined(VGA_amd64)
+   unsigned long block[2];
+   block[0] = (unsigned long)p;
+   block[1] = n;
    __asm__ __volatile__(
       "movq 0(%%rsi),%%rax"      "\n\t"
       "movq 8(%%rsi),%%rbx"      "\n\t"
       "lock; addw %%bx,(%%rax)"  "\n"
       : : "S"(&block[0])/* S means "rsi only" */ : "memory","cc","rax","rbx"
    );
+#elif defined(VGA_ppc32)
+   /* Nasty hack.  Does correctly atomically do *p += n, but only if p
+      is 8-aligned -- guaranteed by caller. */
+   unsigned long success;
+   do {
+      __asm__ __volatile__(
+         "lwarx  15,0,%1"    "\n\t"
+         "add    15,15,%2"   "\n\t"
+         "stwcx. 15,0,%1"    "\n\t"
+         "mfcr   %0"         "\n\t"
+         "srwi   %0,%0,29"   "\n\t"
+         "andi.  %0,%0,1"    "\n"
+         : /*out*/"=b"(success)
+         : /*in*/ "b"(p), "b"(((unsigned long)n) << 16)
+         : /*trash*/ "memory", "cc", "r15"
+      );
+   } while (success != 1);
+#elif defined(VGA_ppc64)
+   /* Nasty hack.  Does correctly atomically do *p += n, but only if p
+      is 8-aligned -- guaranteed by caller. */
+   unsigned long success;
+   do {
+      __asm__ __volatile__(
+         "ldarx  15,0,%1"    "\n\t"
+         "add    15,15,%2"   "\n\t"
+         "stdcx. 15,0,%1"    "\n\t"
+         "mfcr   %0"         "\n\t"
+         "srwi   %0,%0,29"   "\n\t"
+         "andi.  %0,%0,1"    "\n"
+         : /*out*/"=b"(success)
+         : /*in*/ "b"(p), "b"(((unsigned long)n) << 48)
+         : /*trash*/ "memory", "cc", "r15"
+      );
+   } while (success != 1);
 #else
 # error "Unsupported arch"
 #endif
@@ -64,10 +143,10 @@ __attribute__((noinline)) void atomic_add_16bit ( short* p, int n )
 
 __attribute__((noinline)) void atomic_add_32bit ( int* p, int n ) 
 {
+#if defined(VGA_x86)
    unsigned long block[2];
    block[0] = (unsigned long)p;
    block[1] = n;
-#if defined(VGA_x86)
    __asm__ __volatile__(
       "movl 0(%%esi),%%eax"       "\n\t"
       "movl 4(%%esi),%%ebx"       "\n\t"
@@ -75,12 +154,47 @@ __attribute__((noinline)) void atomic_add_32bit ( int* p, int n )
       : : "S"(&block[0])/* S means "esi only" */ : "memory","cc","eax","ebx"
    );
 #elif defined(VGA_amd64)
+   unsigned long block[2];
+   block[0] = (unsigned long)p;
+   block[1] = n;
    __asm__ __volatile__(
       "movq 0(%%rsi),%%rax"       "\n\t"
       "movq 8(%%rsi),%%rbx"       "\n\t"
       "lock; addl %%ebx,(%%rax)"  "\n"
       : : "S"(&block[0])/* S means "rsi only" */ : "memory","cc","rax","rbx"
    );
+#elif defined(VGA_ppc32)
+   unsigned long success;
+   do {
+      __asm__ __volatile__(
+         "lwarx  15,0,%1"    "\n\t"
+         "add    15,15,%2"   "\n\t"
+         "stwcx. 15,0,%1"    "\n\t"
+         "mfcr   %0"         "\n\t"
+         "srwi   %0,%0,29"   "\n\t"
+         "andi.  %0,%0,1"    "\n"
+         : /*out*/"=b"(success)
+         : /*in*/ "b"(p), "b"(n)
+         : /*trash*/ "memory", "cc", "r15"
+      );
+   } while (success != 1);
+#elif defined(VGA_ppc64)
+   /* Nasty hack.  Does correctly atomically do *p += n, but only if p
+      is 8-aligned -- guaranteed by caller. */
+   unsigned long success;
+   do {
+      __asm__ __volatile__(
+         "ldarx  15,0,%1"    "\n\t"
+         "add    15,15,%2"   "\n\t"
+         "stdcx. 15,0,%1"    "\n\t"
+         "mfcr   %0"         "\n\t"
+         "srwi   %0,%0,29"   "\n\t"
+         "andi.  %0,%0,1"    "\n"
+         : /*out*/"=b"(success)
+         : /*in*/ "b"(p), "b"(((unsigned long)n) << 32)
+         : /*trash*/ "memory", "cc", "r15"
+      );
+   } while (success != 1);
 #else
 # error "Unsupported arch"
 #endif
@@ -88,20 +202,35 @@ __attribute__((noinline)) void atomic_add_32bit ( int* p, int n )
 
 __attribute__((noinline)) void atomic_add_64bit ( long long int* p, int n ) 
 {
-  // this is a bit subtle.  It relies on the fact that, on a 64-bit platform,
-  // sizeof(unsigned long long int) == sizeof(unsigned long) == sizeof(void*) 
+#if defined(VGA_x86) || defined(VGA_ppc32)
+   /* do nothing; is not supported */
+#elif defined(VGA_amd64)
+   // this is a bit subtle.  It relies on the fact that, on a 64-bit platform,
+   // sizeof(unsigned long long int) == sizeof(unsigned long) == sizeof(void*) 
    unsigned long long int block[2];
    block[0] = (unsigned long long int)(unsigned long)p;
    block[1] = n;
-#if defined(VGA_x86)
-   /* do nothing; is not supported */
-#elif defined(VGA_amd64)
    __asm__ __volatile__(
       "movq 0(%%rsi),%%rax"      "\n\t"
       "movq 8(%%rsi),%%rbx"      "\n\t"
       "lock; addq %%rbx,(%%rax)" "\n"
       : : "S"(&block[0])/* S means "rsi only" */ : "memory","cc","rax","rbx"
    );
+#elif defined(VGA_ppc64)
+   unsigned long success;
+   do {
+      __asm__ __volatile__(
+         "ldarx  15,0,%1"    "\n\t"
+         "add    15,15,%2"   "\n\t"
+         "stdcx. 15,0,%1"    "\n\t"
+         "mfcr   %0"         "\n\t"
+         "srwi   %0,%0,29"   "\n\t"
+         "andi.  %0,%0,1"    "\n"
+         : /*out*/"=b"(success)
+         : /*in*/ "b"(p), "b"(n)
+         : /*trash*/ "memory", "cc", "r15"
+      );
+   } while (success != 1);
 #else
 # error "Unsupported arch"
 #endif
@@ -132,6 +261,13 @@ int main ( int argc, char** argv )
    p32 = (int*)(page+512);
    p64 = (long long int*)(page+768);
 
+   assert( IS_8_ALIGNED(p8) );
+   assert( IS_8_ALIGNED(p16) );
+   assert( IS_8_ALIGNED(p32) );
+   assert( IS_8_ALIGNED(p64) );
+
+   memset(page, 0, 1024);
+
    *p8  = 0;
    *p16 = 0;
    *p32 = 0;
@@ -175,12 +311,12 @@ int main ( int argc, char** argv )
    assert(WIFEXITED(status));
 
    printf("FINAL VALUES:  8 bit %d,  16 bit %d,  32 bit %d,  64 bit %lld\n",
-          (int)(*p8), (int)(*p16), *p32, *p64 );
+          (int)(*(signed char*)p8), (int)(*p16), *p32, *p64 );
 
-   if (-74 == (int)(*p8) 
+   if (-74 == (int)(*(signed char*)p8) 
        && 32694 == (int)(*p16) 
        && 6913974 == *p32
-       && (0LL == *p64 || 682858642110 == *p64)) {
+       && (0LL == *p64 || 682858642110LL == *p64)) {
       printf("PASS\n");
    } else {
       printf("FAIL -- see source code for expected values\n");