// 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;
   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).
   
   VALGRIND_GET_VBITS(&res, &shres, 8);
   res2 = res;
   VALGRIND_MAKE_MEM_DEFINED(&res2, 8);      // avoid the 'undefined' warning
   assert(res2 == shres);
   return res;
}

U1 make_defined ( U1 x )
{
   volatile U1 xx = x;
   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;
   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;

}
