bug in longlong.h for aarch64 sub_ddmmss

Torbjörn Granlund tg at gmplib.org
Wed Jun 17 13:44:44 UTC 2020


Vincent Lefevre <vincent at vinc17.net> writes:

  Note: in the tests, it is important to test the macro on constants
  in order to test the "if" case.

A crude test generator:

#include <stdlib.h>
#include <stdio.h>
#include "gmp-impl.h"

void
one (size_t ind, mp_limb_t m0, mp_limb_t s0)
{
  printf ("void f%zu(mp_limb_t* r1p, mp_limb_t* r0p) {\n", ind);
  printf ("mp_limb_t r1, r0;\n");
  printf ("sub_ddmmss (r1, r0, 0, %ld, 0, %ld);\n", (long) m0, (long) s0);
  printf ("*r1p = r1;  *r0p = r0;\n");
  printf ("}\n");
}

mp_limb_t ops[1000];
mp_limb_t res1[1000];
mp_limb_t res0[1000];

int
main ()
{
  size_t n_operands = 0;
  size_t n_functions = 0;

  for (int i = 0; i < 16; i++)
    {
      ops[n_operands++] = 1 << i;
      ops[n_operands++] = -(1 << i);
      ops[n_operands++] = (1 << i) - 1;
      ops[n_operands++] = -(1 << i) - 1;
    }

  printf ("#include <stdlib.h>\n");
  printf ("#include <stdio.h>\n");
  printf ("#include \"gmp-impl.h\"\n");
  printf ("#include \"longlong.h\"\n");

  /* Generate functions and print them.  */
  for (int i = 0; i < n_operands; i++)
    {
      for (int j = 0; j < n_operands; j++)
	{
	  one (n_functions++, ops[i], ops[j]);
	}
    }

#if 1
  /* Print out ops[] definition.  */
  printf ("int ops[%zu] = {\n", n_operands);
  for (int i = 0; i < n_operands; i++)
    {
      printf ("%ld,", (long) ops[i]);
      if ((i + 1) % 4 == 0)
	puts ("");
    }
  printf ("};\n");
#endif

  /* Print out function pointer table.  */
  printf ("typedef void (*func_t) (mp_limb_t*, mp_limb_t*);\n");
  printf ("func_t funcs[%zu] = {\n", n_functions);
  for (size_t i = 0; i < n_functions; i++)
    {
      printf ("f%zu,", i);
      if ((i + 1) % 16 == 0)
	puts ("");
    }
  printf ("};\n");

  /* Print out table of reference results.  */
  printf ("mp_limb_t ref[%zu][2] = {\n", n_functions);
  for (int i = 0; i < n_operands; i++)
    {
      for (int j = 0; j < n_operands; j++)
	{
	  printf ("{0x%llx,0x%llx},\n", (unsigned long long) ( ops[i] - ops[j]), (unsigned long long) (-(mp_limb_t) (ops[i] < ops[j])));
	}
    }
  printf ("};\n");


  printf ("int main ()\n{\n");
  printf ("  mp_limb_t r1, r0;\n");
  printf ("  int err = 0;\n");
  printf ("  size_t ind = 0;\n");
  printf ("  for (size_t i = 0; i < %zu; i++)\n", n_functions);
  printf ("    {\n");
  printf ("      int ii = i / %zu, jj = i %% %zu;\n", n_operands, n_operands);
  printf ("      funcs[i](&r1, &r0);\n");
  printf ("      if (r0 != ref[ind][0] || r1 != ref[ind][1]) {\n");
  printf ("         gmp_printf (\"error for f%%zu(0x%%Mx,0x%%Mx): want (0x%%Mx,0x%%Mx) got (0x%%Mx,0x%%Mx)\\n\", i, ops[ii], ops[jj], ref[ind][1], ref[ind][0], r1, r0);\n");
  printf ("         err++;\n");
  printf ("       }\n");
  printf ("      ind++;\n");
  printf ("    }\n");


  printf ("  return err != 0;\n");
  printf ("}\n");
  return 0;
}


-- 
Torbjörn
Please encrypt, key id 0xC8601622


More information about the gmp-bugs mailing list