Blame tests/devel/copy.c

Packit 5c3484
/*
Packit 5c3484
Copyright 1999-2001, 2004, 2009, 2011 Free Software Foundation, Inc.
Packit 5c3484
Packit 5c3484
This file is part of the GNU MP Library test suite.
Packit 5c3484
Packit 5c3484
The GNU MP Library test suite is free software; you can redistribute it
Packit 5c3484
and/or modify it under the terms of the GNU General Public License as
Packit 5c3484
published by the Free Software Foundation; either version 3 of the License,
Packit 5c3484
or (at your option) any later version.
Packit 5c3484
Packit 5c3484
The GNU MP Library test suite is distributed in the hope that it will be
Packit 5c3484
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 5c3484
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Packit 5c3484
Public License for more details.
Packit 5c3484
Packit 5c3484
You should have received a copy of the GNU General Public License along with
Packit 5c3484
the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
Packit 5c3484
Packit 5c3484
#include <stdlib.h>
Packit 5c3484
#include <string.h>
Packit 5c3484
#include <stdio.h>
Packit 5c3484
#include "gmp.h"
Packit 5c3484
#include "gmp-impl.h"
Packit 5c3484
#include "tests.h"
Packit 5c3484
Packit 5c3484
#ifdef OPERATION_copyi
Packit 5c3484
#define func MPN_COPY_INCR
Packit 5c3484
#define reffunc refmpn_copyi
Packit 5c3484
#define funcname "MPN_COPY_INCR"
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
#ifdef OPERATION_copyd
Packit 5c3484
#define func MPN_COPY_DECR
Packit 5c3484
#define reffunc refmpn_copyd
Packit 5c3484
#define funcname "MPN_COPY_DECR"
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
#if defined (USG) || defined (__SVR4) || defined (_UNICOS) || defined (__hpux)
Packit 5c3484
#include <time.h>
Packit 5c3484
Packit 5c3484
int
Packit 5c3484
cputime ()
Packit 5c3484
{
Packit 5c3484
  if (CLOCKS_PER_SEC < 100000)
Packit 5c3484
    return clock () * 1000 / CLOCKS_PER_SEC;
Packit 5c3484
  return clock () / (CLOCKS_PER_SEC / 1000);
Packit 5c3484
}
Packit 5c3484
#else
Packit 5c3484
#include <sys/types.h>
Packit 5c3484
#include <sys/time.h>
Packit 5c3484
#include <sys/resource.h>
Packit 5c3484
Packit 5c3484
int
Packit 5c3484
cputime ()
Packit 5c3484
{
Packit 5c3484
  struct rusage rus;
Packit 5c3484
Packit 5c3484
  getrusage (0, &rus;;
Packit 5c3484
  return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
Packit 5c3484
}
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
static void print_posneg (mp_limb_t);
Packit 5c3484
static void mpn_print (mp_ptr, mp_size_t);
Packit 5c3484
Packit 5c3484
#define LXW ((int) (2 * sizeof (mp_limb_t)))
Packit 5c3484
#define M * 1000000
Packit 5c3484
Packit 5c3484
#ifndef CLOCK
Packit 5c3484
#error "Don't know CLOCK of your machine"
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
#ifndef OPS
Packit 5c3484
#define OPS (CLOCK/5)
Packit 5c3484
#endif
Packit 5c3484
#ifndef SIZE
Packit 5c3484
#define SIZE 496
Packit 5c3484
#endif
Packit 5c3484
#ifndef TIMES
Packit 5c3484
#define TIMES OPS/(SIZE+1)
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
int
Packit 5c3484
main (int argc, char **argv)
Packit 5c3484
{
Packit 5c3484
  mp_ptr s1, dx, dy;
Packit 5c3484
  int i;
Packit 5c3484
  long t0, t;
Packit 5c3484
  unsigned int test;
Packit 5c3484
  mp_size_t size;
Packit 5c3484
  unsigned int ntests;
Packit 5c3484
Packit 5c3484
  s1 = malloc (SIZE * sizeof (mp_limb_t));
Packit 5c3484
  dx = malloc ((SIZE + 2) * sizeof (mp_limb_t));
Packit 5c3484
  dy = malloc ((SIZE + 2) * sizeof (mp_limb_t));
Packit 5c3484
Packit 5c3484
  ntests = ~(unsigned) 0;
Packit 5c3484
  if (argc == 2)
Packit 5c3484
    ntests = strtol (argv[1], 0, 0);
Packit 5c3484
Packit 5c3484
  for (test = 1; test <= ntests; test++)
Packit 5c3484
    {
Packit 5c3484
#if TIMES == 1 && ! defined (PRINT)
Packit 5c3484
      if (test % (SIZE > 100000 ? 1 : 100000 / SIZE) == 0)
Packit 5c3484
	{
Packit 5c3484
	  printf ("\r%u", test);
Packit 5c3484
	  fflush (stdout);
Packit 5c3484
	}
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
#ifdef RANDOM
Packit 5c3484
      size = random () % SIZE + 1;
Packit 5c3484
#else
Packit 5c3484
      size = SIZE;
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
      dx[0] = 0x87654321;
Packit 5c3484
      dy[0] = 0x87654321;
Packit 5c3484
      dx[size+1] = 0x12345678;
Packit 5c3484
      dy[size+1] = 0x12345678;
Packit 5c3484
Packit 5c3484
#if TIMES != 1
Packit 5c3484
      mpn_random (s1, size);
Packit 5c3484
Packit 5c3484
      t0 = cputime();
Packit 5c3484
      for (i = 0; i < TIMES; i++)
Packit 5c3484
	func (dx+1, s1, size);
Packit 5c3484
      t = cputime() - t0;
Packit 5c3484
      printf (funcname ":    %5ldms (%.3f cycles/limb)\n",
Packit 5c3484
	      t, ((double) t * CLOCK) / (TIMES * size * 1000.0));
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
#ifndef NOCHECK
Packit 5c3484
      mpn_random2 (s1, size);
Packit 5c3484
Packit 5c3484
#ifdef PRINT
Packit 5c3484
      mpn_print (s1, size);
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
      /* Put garbage in the destination.  */
Packit 5c3484
      for (i = 0; i < size; i++)
Packit 5c3484
	{
Packit 5c3484
	  dx[i+1] = 0xdead;
Packit 5c3484
	  dy[i+1] = 0xbeef;
Packit 5c3484
	}
Packit 5c3484
Packit 5c3484
      reffunc (dx+1, s1, size);
Packit 5c3484
      func (dy+1, s1, size);
Packit 5c3484
Packit 5c3484
#ifdef PRINT
Packit 5c3484
      mpn_print (dx+1, size);
Packit 5c3484
      mpn_print (dy+1, size);
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
      if (mpn_cmp (dx, dy, size+2) != 0
Packit 5c3484
	  || dx[0] != 0x87654321 || dx[size+1] != 0x12345678)
Packit 5c3484
	{
Packit 5c3484
	  mp_size_t s, e;
Packit 5c3484
	  for (s = 0;; s++)
Packit 5c3484
	    if ((unsigned long long) (dx+1)[s] != (unsigned long long) (dy+1)[s])
Packit 5c3484
	      break;
Packit 5c3484
	  for (e = size - 1;; e--)
Packit 5c3484
	    if ((unsigned long long) (dx+1)[e] != (unsigned long long) (dy+1)[e])
Packit 5c3484
	      break;
Packit 5c3484
#ifndef PRINT
Packit 5c3484
	  for (i = s; i <= e; i++)
Packit 5c3484
	    {
Packit 5c3484
	      printf ("%6d: ", i);
Packit 5c3484
	      printf ("%0*llX ", LXW, (unsigned long long) (dx+1)[i]);
Packit 5c3484
	      printf ("%0*llX ", LXW, (unsigned long long) (dy+1)[i]);
Packit 5c3484
	      print_posneg ((dy+1)[i] - (dx+1)[i]);
Packit 5c3484
	      printf ("\n");
Packit 5c3484
	    }
Packit 5c3484
#endif
Packit 5c3484
	  printf ("\n");
Packit 5c3484
	  if (dy[0] != 0x87654321)
Packit 5c3484
	    printf ("clobbered at low end\n");
Packit 5c3484
	  if (dy[size+1] != 0x12345678)
Packit 5c3484
	    printf ("clobbered at high end\n");
Packit 5c3484
	  printf ("TEST NUMBER %u\n", test);
Packit 5c3484
	  abort();
Packit 5c3484
	}
Packit 5c3484
#endif
Packit 5c3484
    }
Packit 5c3484
  exit (0);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
static void
Packit 5c3484
print_posneg (mp_limb_t d)
Packit 5c3484
{
Packit 5c3484
  char buf[LXW + 2];
Packit 5c3484
  if (d == 0)
Packit 5c3484
    printf (" %*X", LXW, 0);
Packit 5c3484
  else if (-d < d)
Packit 5c3484
    {
Packit 5c3484
      sprintf (buf, "%llX", (unsigned long long) -d);
Packit 5c3484
      printf ("%*s-%s", LXW - (int) strlen (buf), "", buf);
Packit 5c3484
    }
Packit 5c3484
  else
Packit 5c3484
    {
Packit 5c3484
      sprintf (buf, "%llX", (unsigned long long) d);
Packit 5c3484
      printf ("%*s+%s", LXW - (int) strlen (buf), "", buf);
Packit 5c3484
    }
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
static void
Packit 5c3484
mpn_print (mp_ptr p, mp_size_t size)
Packit 5c3484
{
Packit 5c3484
  mp_size_t i;
Packit 5c3484
Packit 5c3484
  for (i = size - 1; i >= 0; i--)
Packit 5c3484
    {
Packit 5c3484
#ifdef _LONG_LONG_LIMB
Packit 5c3484
      printf ("%0*lX%0*lX", (int) (sizeof(mp_limb_t)),
Packit 5c3484
	      (unsigned long) (p[i] >> (GMP_LIMB_BITS/2)),
Packit 5c3484
	      (int) (sizeof(mp_limb_t)), (unsigned long) (p[i]));
Packit 5c3484
#else
Packit 5c3484
      printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
Packit 5c3484
#endif
Packit 5c3484
#ifdef SPACE
Packit 5c3484
      if (i != 0)
Packit 5c3484
	printf (" ");
Packit 5c3484
#endif
Packit 5c3484
    }
Packit 5c3484
  puts ("");
Packit 5c3484
}