1 /* Test MPN_INCR_U and MPN_DECR_U.
2 
3 Copyright 2001, 2002 Free Software Foundation, Inc.
4 
5 This file is part of the GNU MP Library test suite.
6 
7 The GNU MP Library test suite is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 3 of the License,
10 or (at your option) any later version.
11 
12 The GNU MP Library test suite is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15 Public License for more details.
16 
17 You should have received a copy of the GNU General Public License along with
18 the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 
23 #include "gmp-impl.h"
24 #include "tests.h"
25 
26 
27 /* The i386 MPN_INCR_U and MPN_DECR_U have special cases for "n" being a
28    compile-time constant 1, so that's exercised explicitly.  */
29 
30 
31 #define M     GMP_NUMB_MAX
32 #define SIZE  ((mp_size_t) 10)
33 
34 
35 void
check_one(const char * name,int i,mp_srcptr src,mp_limb_t n,mp_srcptr got,mp_srcptr want,mp_size_t size)36 check_one (const char *name, int i,
37            mp_srcptr src, mp_limb_t n,
38            mp_srcptr got, mp_srcptr want, mp_size_t size)
39 {
40   if (! refmpn_equal_anynail (got, want, size))
41     {
42       printf ("Wrong at %s i=%d\n", name, i);
43       mpn_trace ("  src", src,  size);
44       mpn_trace ("    n", &n,   (mp_size_t) 1);
45       mpn_trace ("  got", got,  size);
46       mpn_trace (" want", want, size);
47       abort ();
48     }
49 }
50 
51 
52 void
check_incr_data(void)53 check_incr_data (void)
54 {
55   static const struct {
56     mp_limb_t        n;
57     const mp_limb_t  src[SIZE];
58     const mp_limb_t  want[SIZE];
59   } data[] = {
60     { 1, { 0 },   { 1 } },
61     { 1, { 123 }, { 124 } },
62     { 2, { 0 },   { 2 } },
63     { 2, { 123 }, { 125 } },
64     { M, { 0 },   { M } },
65 
66     { 1, { M, 0 },   { 0,   1 } },
67     { 1, { M, 123 }, { 0,   124 } },
68     { 2, { M, 0 },   { 1,   1 } },
69     { 2, { M, 123 }, { 1,   124 } },
70     { M, { M, 0 },   { M-1, 1 } },
71     { M, { M, 123 }, { M-1, 124 } },
72 
73     { 1, { M, M, 0 },   { 0,   0, 1 } },
74     { 1, { M, M, 123 }, { 0,   0, 124 } },
75     { 2, { M, M, 0 },   { 1,   0, 1 } },
76     { 2, { M, M, 123 }, { 1,   0, 124 } },
77     { M, { M, M, 0 },   { M-1, 0, 1 } },
78     { M, { M, M, 123 }, { M-1, 0, 124 } },
79 
80     { 1, { M, M, M, 0 },   { 0,   0, 0, 1 } },
81     { 1, { M, M, M, 123 }, { 0,   0, 0, 124 } },
82     { 2, { M, M, M, 0 },   { 1,   0, 0, 1 } },
83     { 2, { M, M, M, 123 }, { 1,   0, 0, 124 } },
84     { M, { M, M, M, 0 },   { M-1, 0, 0, 1 } },
85     { M, { M, M, M, 123 }, { M-1, 0, 0, 124 } },
86 
87     { 1, { M, M, M, M, 0 },   { 0,   0, 0, 0, 1 } },
88     { 1, { M, M, M, M, 123 }, { 0,   0, 0, 0, 124 } },
89     { 2, { M, M, M, M, 0 },   { 1,   0, 0, 0, 1 } },
90     { 2, { M, M, M, M, 123 }, { 1,   0, 0, 0, 124 } },
91     { M, { M, M, M, M, 0 },   { M-1, 0, 0, 0, 1 } },
92     { M, { M, M, M, M, 123 }, { M-1, 0, 0, 0, 124
93 #if defined (__hpux) && ! defined (__GNUC__)
94     /* Some versions (at least HP92453-01 B.11.11.23709.GP) of the
95        HP C compilers fail to zero-fill aggregates as the ISO C standard
96        requires (cf 6.5.7 Initialization).  Compensate here:  */
97 				, 0, 0, 0, 0, 0
98 #endif
99     } }
100   };
101 
102   mp_limb_t  got[SIZE];
103   int   i;
104 
105   for (i = 0; i < numberof (data); i++)
106     {
107       refmpn_copyi (got, data[i].src, SIZE);
108       MPN_INCR_U (got, SIZE, data[i].n);
109       check_one ("check_incr (general)", i,
110                  data[i].src, data[i].n,
111                  got, data[i].want, SIZE);
112 
113       if (data[i].n == 1)
114         {
115           refmpn_copyi (got, data[i].src, SIZE);
116           MPN_INCR_U (got, SIZE, CNST_LIMB(1));
117           check_one ("check_incr (const 1)", i,
118                      data[i].src, data[i].n,
119                      got, data[i].want, SIZE);
120         }
121     }
122 }
123 
124 void
check_decr_data(void)125 check_decr_data (void)
126 {
127   static const struct {
128     mp_limb_t        n;
129     const mp_limb_t  src[SIZE];
130     const mp_limb_t  want[SIZE];
131   } data[] = {
132     { 1,   { 1 },   { 0   } },
133     { 1,   { 123 }, { 122 } },
134     { 1,   { M },   { M-1 } },
135     { 2,   { 2 },   { 0   } },
136     { 2,   { 123 }, { 121 } },
137     { M,   { M },   { 0   } },
138     { M-1, { M },   { 1   } },
139 
140     { 1,   { 0,   1   }, { M,   0   } },
141     { 1,   { 0,   123 }, { M,   122 } },
142     { 1,   { 0,   M   }, { M,   M-1 } },
143     { 2,   { 0,   123 }, { M-1, 122 } },
144     { 2,   { 1,   123 }, { M,   122 } },
145     { M,   { 0,   123 }, { 1,   122 } },
146     { M,   { M-1, M   }, { M,   M-1 } },
147 
148     { 1,   { 0,   0, 1   }, { M,   M, 0   } },
149     { 1,   { 0,   0, 123 }, { M,   M, 122 } },
150     { 1,   { 0,   0, M   }, { M,   M, M-1 } },
151     { 2,   { 0,   0, 123 }, { M-1, M, 122 } },
152     { 2,   { 1,   0, 123 }, { M,   M, 122 } },
153     { M,   { 0,   0, 123 }, { 1,   M, 122 } },
154     { M,   { M-1, 0, M   }, { M,   M, M-1 } },
155 
156     { 1,   { 0,   0, 0, 1   }, { M,   M, M, 0   } },
157     { 1,   { 0,   0, 0, 123 }, { M,   M, M, 122 } },
158     { 1,   { 0,   0, 0, M   }, { M,   M, M, M-1 } },
159     { 2,   { 0,   0, 0, 123 }, { M-1, M, M, 122 } },
160     { 2,   { 1,   0, 0, 123 }, { M,   M, M, 122 } },
161     { M,   { 0,   0, 0, 123 }, { 1,   M, M, 122 } },
162     { M,   { M-1, 0, 0, M   }, { M,   M, M, M-1 } },
163 
164     { 1,   { 0,   0, 0, 0, 1   }, { M,   M, M, M, 0   } },
165     { 1,   { 0,   0, 0, 0, 123 }, { M,   M, M, M, 122 } },
166     { 1,   { 0,   0, 0, 0, M   }, { M,   M, M, M, M-1 } },
167     { 2,   { 0,   0, 0, 0, 123 }, { M-1, M, M, M, 122 } },
168     { 2,   { 1,   0, 0, 0, 123 }, { M,   M, M, M, 122 } },
169     { M,   { 0,   0, 0, 0, 123 }, { 1,   M, M, M, 122 } },
170     { M,   { M-1, 0, 0, 0, M   }, { M,   M, M, M, M-1 } },
171 
172     { 1,   { 0,   0, 0, 0, 0, 1   }, { M,   M, M, M, M, 0   } },
173     { 1,   { 0,   0, 0, 0, 0, 123 }, { M,   M, M, M, M, 122 } },
174     { 1,   { 0,   0, 0, 0, 0, M   }, { M,   M, M, M, M, M-1 } },
175     { 2,   { 0,   0, 0, 0, 0, 123 }, { M-1, M, M, M, M, 122 } },
176     { 2,   { 1,   0, 0, 0, 0, 123 }, { M,   M, M, M, M, 122 } },
177     { M,   { 0,   0, 0, 0, 0, 123 }, { 1,   M, M, M, M, 122 } },
178     { M,   { M-1, 0, 0, 0, 0, M   }, { M,   M, M, M, M, M-1
179 #if defined (__hpux) && ! defined (__GNUC__)
180     /* For explanation of this garbage, see previous function.  */
181 				       , 0, 0, 0, 0
182 #endif
183     } }
184   };
185 
186   mp_limb_t  got[SIZE];
187   int   i;
188 
189   for (i = 0; i < numberof (data); i++)
190     {
191       refmpn_copyi (got, data[i].src, SIZE);
192       MPN_DECR_U (got, SIZE, data[i].n);
193       check_one ("check_decr_data", i,
194                  data[i].src, data[i].n,
195                  got, data[i].want, SIZE);
196 
197       if (data[i].n == 1)
198         {
199           refmpn_copyi (got, data[i].src, SIZE);
200           MPN_DECR_U (got, SIZE, CNST_LIMB(1));
201           check_one ("check_decr (const 1)", i,
202                      data[i].src, data[i].n,
203                      got, data[i].want, SIZE);
204         }
205     }
206 }
207 
208 
209 int
main(void)210 main (void)
211 {
212   tests_start ();
213   mp_trace_base = -16;
214 
215   check_incr_data ();
216   check_decr_data ();
217 
218   tests_end ();
219   exit (0);
220 }
221