summaryrefslogtreecommitdiff
path: root/tests/devel/gen-test-longlong_h.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/devel/gen-test-longlong_h.c')
-rw-r--r--tests/devel/gen-test-longlong_h.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/tests/devel/gen-test-longlong_h.c b/tests/devel/gen-test-longlong_h.c
new file mode 100644
index 000000000..a8f94b4b7
--- /dev/null
+++ b/tests/devel/gen-test-longlong_h.c
@@ -0,0 +1,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;
+}