Vincent Lefevre <vinc...@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 _______________________________________________ gmp-bugs mailing list gmp-bugs@gmplib.org https://gmplib.org/mailman/listinfo/gmp-bugs