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