1 /*
2 Copyright 2020 Free Software Foundation, Inc.
3
4 This file is part of the GNU MP Library test suite.
5
6 The GNU MP Library test suite is free software; you can redistribute it
7 and/or modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 3 of the License,
9 or (at your option) any later version.
10
11 The GNU MP Library test suite is distributed in the hope that it will be
12 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14 Public License for more details.
15
16 You should have received a copy of the GNU General Public License along with
17 the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdio.h>
22
23 typedef unsigned long mp_limb_t; /* neat */
24
25 void
one(const char * op,size_t ind,mp_limb_t m0,mp_limb_t s0)26 one (const char *op, size_t ind, mp_limb_t m0, mp_limb_t s0)
27 {
28 printf ("static void f%zu(mp_limb_t*r1p,mp_limb_t*r0p){", ind);
29 printf ("mp_limb_t r1,r0;");
30 printf ("%s(r1,r0,0,%ld,0,%ld);", op, (long) m0, (long) s0);
31 printf ("*r1p=r1;*r0p=r0;");
32 printf ("}\n");
33 }
34
35 mp_limb_t ops[1000];
36
37 enum what_t {ADD, SUB};
38
39 int
main(int argc,char ** argv)40 main (int argc, char **argv)
41 {
42 size_t n_operands = 0;
43 size_t n_functions = 0;
44 const char *op;
45 enum what_t what;
46
47 if (argc == 2 && strcmp (argv[1], "add") == 0)
48 {
49 op = "add_ssaaaa";
50 what = ADD;
51 }
52 else if (argc == 2 && strcmp (argv[1], "sub") == 0)
53 {
54 op = "sub_ddmmss";
55 what = SUB;
56 }
57 else
58 {
59 fprintf (stderr, "what do yuo want me to do?\n");
60 exit (1);
61 }
62
63 for (int i = 0; i < 16; i++)
64 {
65 ops[n_operands++] = 1 << i;
66 ops[n_operands++] = -(1 << i);
67 ops[n_operands++] = (1 << i) - 1;
68 ops[n_operands++] = -(1 << i) - 1;
69 }
70
71 printf ("#include <stdlib.h>\n");
72 printf ("#include <stdio.h>\n");
73 printf ("#include \"gmp-impl.h\"\n");
74 printf ("#include \"longlong.h\"\n");
75
76 /* Print out ops[] definition. */
77 printf ("static const int ops[%zu] = {\n", n_operands);
78 for (int i = 0; i < n_operands; i++)
79 {
80 printf ("%ld,", (long) ops[i]);
81 if ((i + 1) % 4 == 0)
82 puts ("");
83 }
84 printf ("};\n");
85
86 /* Generate functions and print them. */
87 for (int i = 0; i < n_operands; i++)
88 {
89 for (int j = 0; j < n_operands; j++)
90 {
91 one (op, n_functions++, ops[i], ops[j]);
92 }
93 }
94
95 /* Print out function pointer table. */
96 printf ("typedef void (*func_t) (mp_limb_t*, mp_limb_t*);\n");
97 printf ("static const func_t funcs[%zu] = {\n", n_functions);
98 for (size_t i = 0; i < n_functions; i++)
99 {
100 printf ("f%zu,", i);
101 if ((i + 1) % 16 == 0)
102 puts ("");
103 }
104 printf ("};\n");
105
106 /* Print out table of reference results. */
107 printf ("static const int ref[%zu][2] = {\n", n_functions);
108 for (int i = 0; i < n_operands; i++)
109 {
110 for (int j = 0; j < n_operands; j++)
111 {
112 if (what == ADD)
113 printf ("{%6ld,%2ld},", (long) ( ops[i] + ops[j]), (long) ((mp_limb_t) ((ops[i] + ops[j]) < ops[i])));
114 else /* SUB */
115 printf ("{%6ld,%2ld},", (long) ( ops[i] - ops[j]), (long) (-(mp_limb_t) (ops[i] < ops[j])));
116 if ((i * n_operands + j) % 8 == 0)
117 puts ("");
118 }
119 }
120 printf ("};\n");
121
122 printf ("int main ()\n{\n");
123 printf (" mp_limb_t r1, r0;\n");
124 printf (" int err = 0;\n");
125 printf (" size_t ind = 0;\n");
126 printf (" for (size_t i = 0; i < %zu; i++)\n", n_functions);
127 printf (" {\n");
128 printf (" int ii = i / %zu, jj = i %% %zu;\n", n_operands, n_operands);
129 printf (" funcs[i](&r1, &r0);\n");
130 printf (" if (r0 != (mp_limb_signed_t) ref[ind][0] || r1 != (mp_limb_signed_t) ref[ind][1]) {\n");
131 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");
132 printf (" err++;\n");
133 printf (" }\n");
134 printf (" ind++;\n");
135 printf (" }\n");
136
137 printf (" return err != 0;\n");
138 printf ("}\n");
139 return 0;
140 }
141