// This program is a thorough test of the LOADVn/STOREVn shadow memory
// operations.

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "tests/sys_mman.h"
#include "memcheck/memcheck.h"

// All the sizes here are in *bytes*, not bits.

typedef unsigned char        U1;
typedef unsigned short       U2;
typedef unsigned int         U4;
typedef unsigned long long   U8;

typedef float                F4;
typedef double               F8;

typedef unsigned long        UWord;

#define PAGE_SIZE 4096ULL


// XXX: should check the error cases for SET/GET_VBITS also

// For the byte 'x', build a value of 'size' bytes from that byte, eg:
//   size 1 --> x
//   size 2 --> xx
//   size 4 --> xxxx
//   size 8 --> xxxxxxxx
// where the 0 bits are seen by Memcheck as defined, and the 1 bits are
// seen as undefined (ie. the value of each bit matches its V bit, ie. the
// resulting value is the same as its metavalue).
//
U8 build(int size, U1 byte)
{
   int i;
   U8 mask = 0;
   U8 shres;
   U8 res = 0xffffffffffffffffULL, res2;
   (void)VALGRIND_MAKE_MEM_UNDEFINED(&res, 8);
   assert(1 == size || 2 == size || 4 == size || 8 == size);

   for (i = 0; i < size; i++) {
      mask <<= 8;
      mask |= (U8)byte;
   }

   res &= mask;      
   
   // res is now considered partially defined, but we know exactly what its
   // value is (it happens to be the same as its metavalue).
   
   (void)VALGRIND_GET_VBITS(&res, &shres, 8);
   res2 = res;
   (void)VALGRIND_MAKE_MEM_DEFINED(&res2, 8);  // avoid the 'undefined' warning
   assert(res2 == shres);
   return res;
}

U1 make_defined ( U1 x )
{
   volatile U1 xx = x;
   (void)VALGRIND_MAKE_MEM_DEFINED(&xx, 1);
   return xx;
}

void check(U1* arr, int n, char* who)
{
   int i;
   U1* shadow = malloc(n);
   U1 arr_i;
   U8 sum = 0;
   (void)VALGRIND_GET_VBITS(arr, shadow, n);
   for (i = 0; i < n; i++) {
      arr_i = make_defined(arr[i]);
      if (arr_i != shadow[i]) {
          fprintf(stderr, "\n\nFAILURE: %s, byte %d -- "
                          "is 0x%x, should be 0x%x\n\n",
                          who, i, shadow[i], arr[i]);
          exit(1);
      }
      sum += (U8)arr_i;
   }
   free(shadow);
   printf("test passed, sum = %llu (%9.5f per byte)\n", 
	  sum, (F8)sum / (F8)n);
}

static inline U4 randomU4 ( void )
{
   static U4 n = 0;
   /* From "Numerical Recipes in C" 2nd Edition */
   n = 1664525UL * n + 1013904223UL;
   return n;
}

static inline U1 randomU1 ( void )
{
   return 0xFF & (randomU4() >> 13);
}

#define N_BYTES  300000
#define N_EVENTS (5 * N_BYTES)


void do_test_at ( U1* arr )
{
   int i;

   U4 mv1 = 0, mv2 = 0, mv4 = 0, mv8 = 0, mv4f = 0, mv8f = 0;

   /* Fill arr with random bytes whose shadows match them. */
   if (0) printf("-------- arr = %p\n", arr);

   printf("initialising\n");
   for (i = 0; i < N_BYTES; i++)
      arr[i] = (U1)build(1, randomU1());

   printf("post-initialisation check\n");
   check(arr, N_BYTES, "after initialisation");

   /* Now do huge numbers of memory copies. */
   printf("doing copies\n");
   for (i = 0; i < N_EVENTS; i++) {
      U4 ty, src, dst;
      ty  = (randomU4() >> 13) % 5;
     tryagain:
      src = (randomU4() >>  1) % N_BYTES;
      dst = (randomU4() >>  3) % N_BYTES;
      switch (ty) {
         case 0: { // U1
            *(U1*)(arr+dst) = *(U1*)(arr+src);
	    mv1++;
            break;
         }
         case 1: { // U2
            if (src+2 >= N_BYTES || dst+2 >= N_BYTES) 
               goto tryagain;
            *(U2*)(arr+dst) = *(U2*)(arr+src);
	    mv2++;
            break;
         }
         case 2: { // U4
            if (src+4 >= N_BYTES || dst+4 >= N_BYTES) 
               goto tryagain;
            *(U4*)(arr+dst) = *(U4*)(arr+src);
	    mv4++;
            break;
         }
         case 3: { // U8
            if (src+8 >= N_BYTES || dst+8 >= N_BYTES) 
               goto tryagain;
            *(U8*)(arr+dst) = *(U8*)(arr+src);
	    mv8++;
            break;
         }
         /* Don't bother with 32-bit floats.  These cause
            horrible complications, as discussed in sh-mem.c. */
         /*
         case 4: { // F4
            if (src+4 >= N_BYTES || dst+4 >= N_BYTES) 
               goto tryagain;
            *(F4*)(arr+dst) = *(F4*)(arr+src);
	    mv4f++;
            break;
         }
         */
         case 4: { // F8
            if (src+8 >= N_BYTES || dst+8 >= N_BYTES) 
               goto tryagain;
#if defined(__i386__)
	    /* Copying via an x87 register causes the test to fail,
               because (I think) some obscure values that are FP
               denormals get changed during the copy due to the FPU
               normalising, or rounding, or whatever, them.  This
               causes them to no longer bit-for-bit match the
               accompanying metadata.  Yet we still need to do a
               genuine 8-byte load/store to test the relevant memcheck
               {LOADV8,STOREV8} routines.  Hence use the MMX registers
               instead, as copying through them should be
               straightforward.. */
            __asm__ __volatile__(
               "movq (%1), %%mm2\n\t"
               "movq %%mm2, (%0)\n\t"
               "emms"
               : : "r"(arr+dst), "r"(arr+src) : "memory"
            );
#else
            /* Straightforward.  On amd64, this gives a load/store of
               the bottom half of an xmm register.  On ppc32/64 this
               is a straighforward load/store of an FP register. */
            *(F8*)(arr+dst) = *(F8*)(arr+src);
#endif
	    mv8f++;
            break;
         }
         default:
	   fprintf(stderr, "sh-mem-random: bad size\n");
	   exit(0);
      }
   }

   printf("final check\n");
   check(arr, N_BYTES, "final check");

   printf("counts 1/2/4/8/F4/F8: %d %d %d %d %d %d\n", 
          mv1, mv2, mv4, mv8, mv4f, mv8f);
}



int main(void)
{
   U1* arr;

   if (0 == RUNNING_ON_VALGRIND) {
      fprintf(stderr, "error: this program only works when run under Valgrind\n");
      exit(1);
   }

   printf("-------- testing non-auxmap range --------\n");

   arr = malloc(N_BYTES);
   assert(arr);
   do_test_at(arr);
   free(arr);

   if (sizeof(void*) == 8) {
      // 64-bit platform.
      int tries;
      int nbytes_p;
      // (U1*)(UWord)constULL funny casting to keep gcc quiet on
      // 32-bit platforms
      U1* huge_addr = (U1*)(UWord)0x6600000000ULL;  // 408GB
      // Note, kernel 2.6.? on Athlon64 refuses fixed mmap requests
      // at above 512GB.

      printf("-------- testing auxmap range --------\n");

      nbytes_p = (N_BYTES + PAGE_SIZE) & ~(PAGE_SIZE-1);

      for (tries = 0; tries < 10; tries++) {
         arr = mmap(huge_addr, nbytes_p, PROT_READ|PROT_WRITE, 
                    MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
	 if (arr != MAP_FAILED)
            break;
	 // hmm. fudge the address and try again.
         huge_addr += (randomU4() & ~(PAGE_SIZE-1));
      }

      if (tries >= 10) {
	   fprintf(stderr, "sh-mem-random: can't mmap hi-mem\n");
	   exit(0);
      }
      assert(arr != MAP_FAILED);

      do_test_at(arr);
   }

   return 0;

}
