blob: 75a0f014e95086e89d591780a23b837b2707cab7 [file] [log] [blame]
Austin Schuhdace2a62020-08-18 10:56:48 -07001/* Test for mullo function.
2
3Copyright 2009 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library test suite.
6
7The GNU MP Library test suite is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 3 of the License,
10or (at your option) any later version.
11
12The GNU MP Library test suite is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15Public License for more details.
16
17You should have received a copy of the GNU General Public License along with
18the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */
19
20
21#include <stdlib.h>
22#include <stdio.h>
23
24#include "gmp-impl.h"
25#include "tests.h"
26
27/* Sizes are up to 2^SIZE_LOG limbs */
28#ifndef SIZE_LOG
29#define SIZE_LOG 10
30#endif
31
32#ifndef COUNT
33#define COUNT 10000
34#endif
35
36#define MAX_N (1L << SIZE_LOG)
37#define MIN_N (1)
38
39int
40main (int argc, char **argv)
41{
42 mp_ptr ap, bp, refp, pp, scratch;
43 int count = COUNT;
44 int test;
45 gmp_randstate_ptr rands;
46 TMP_DECL;
47 TMP_MARK;
48
49 TESTS_REPS (count, argv, argc);
50
51 tests_start ();
52 rands = RANDS;
53
54#define mpn_mullo_itch(n) (0)
55
56 ap = TMP_ALLOC_LIMBS (MAX_N);
57 bp = TMP_ALLOC_LIMBS (MAX_N);
58 refp = TMP_ALLOC_LIMBS (MAX_N * 2);
59 pp = 1+TMP_ALLOC_LIMBS (MAX_N + 2);
60 scratch
61 = 1+TMP_ALLOC_LIMBS (mpn_mullo_itch (MAX_N) + 2);
62
63 for (test = 0; test < count; test++)
64 {
65 unsigned size_min;
66 unsigned size_range;
67 mp_size_t n;
68 mp_size_t itch;
69 mp_limb_t p_before, p_after, s_before, s_after;
70
71 for (size_min = 1; (1L << size_min) < MIN_N; size_min++)
72 ;
73
74 /* We generate an in the MIN_N <= n <= (1 << size_range). */
75 size_range = size_min
76 + gmp_urandomm_ui (rands, SIZE_LOG + 1 - size_min);
77
78 n = MIN_N
79 + gmp_urandomm_ui (rands, (1L << size_range) + 1 - MIN_N);
80
81 mpn_random2 (ap, n);
82 mpn_random2 (bp, n);
83 mpn_random2 (pp-1, n + 2);
84 p_before = pp[-1];
85 p_after = pp[n];
86
87 itch = mpn_mullo_itch (n);
88 ASSERT_ALWAYS (itch <= mpn_mullo_itch (MAX_N));
89 mpn_random2 (scratch-1, itch+2);
90 s_before = scratch[-1];
91 s_after = scratch[itch];
92
93 mpn_mullo_n (pp, ap, bp, n);
94 mpn_mul_n (refp, ap, bp, n);
95 if (pp[-1] != p_before || pp[n] != p_after
96 || scratch[-1] != s_before || scratch[itch] != s_after
97 || mpn_cmp (refp, pp, n) != 0)
98 {
99 printf ("ERROR in test %d, n = %d",
100 test, (int) n);
101 if (pp[-1] != p_before)
102 {
103 printf ("before pp:"); mpn_dump (pp -1, 1);
104 printf ("keep: "); mpn_dump (&p_before, 1);
105 }
106 if (pp[n] != p_after)
107 {
108 printf ("after pp:"); mpn_dump (pp + n, 1);
109 printf ("keep: "); mpn_dump (&p_after, 1);
110 }
111 if (scratch[-1] != s_before)
112 {
113 printf ("before scratch:"); mpn_dump (scratch-1, 1);
114 printf ("keep: "); mpn_dump (&s_before, 1);
115 }
116 if (scratch[itch] != s_after)
117 {
118 printf ("after scratch:"); mpn_dump (scratch + itch, 1);
119 printf ("keep: "); mpn_dump (&s_after, 1);
120 }
121 mpn_dump (ap, n);
122 mpn_dump (bp, n);
123 mpn_dump (pp, n);
124 mpn_dump (refp, n);
125
126 abort();
127 }
128 }
129 TMP_FREE;
130 tests_end ();
131 return 0;
132}