summaryrefslogtreecommitdiff
path: root/tests/devel/gen-test-longlong_h.c
blob: a8f94b4b75dcaf12f6adc7c3125fedc2d2df30bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

typedef unsigned long mp_limb_t; /* neat */

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

mp_limb_t ops[1000];

enum what_t {ADD, SUB};

int
main (int argc, char **argv)
{
  size_t n_operands = 0;
  size_t n_functions = 0;
  const char *op;
  enum what_t what;

  if (argc == 2 && strcmp (argv[1], "add") == 0)
    {
      op = "add_ssaaaa";
      what = ADD;
    }
  else if (argc == 2 && strcmp (argv[1], "sub") == 0)
    {
      op = "sub_ddmmss";
      what = SUB;
    }
  else
    {
      fprintf (stderr, "what do yuo want me to do?\n");
      exit (1);
    }

  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");

  /* Print out ops[] definition.  */
  printf ("static const 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");

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

  /* Print out function pointer table.  */
  printf ("typedef void (*func_t) (mp_limb_t*, mp_limb_t*);\n");
  printf ("static const 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 ("static const int ref[%zu][2] = {\n", n_functions);
  for (int i = 0; i < n_operands; i++)
    {
      for (int j = 0; j < n_operands; j++)
	{
	  if (what == ADD)
	    printf ("{%6ld,%2ld},", (long) ( ops[i] + ops[j]), (long) ((mp_limb_t) ((ops[i] + ops[j]) < ops[i])));
	  else     /* SUB */
	    printf ("{%6ld,%2ld},", (long) ( ops[i] - ops[j]), (long) (-(mp_limb_t) (ops[i] < ops[j])));
	  if ((i * n_operands + j) % 8 == 0)
	    puts ("");
	}
    }
  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 != (mp_limb_signed_t) ref[ind][0] || r1 != (mp_limb_signed_t) ref[ind][1]) {\n");
  printf ("         printf (\"error for f%%zu(%%d,%%d): want (%%d,%%d) got (%%d,%%d)\\n\", i, (int) ops[ii], (int) ops[jj], ref[ind][1], ref[ind][0], (int) r1, (int) r0);\n");
  printf ("         err++;\n");
  printf ("       }\n");
  printf ("      ind++;\n");
  printf ("    }\n");

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