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.h"
24 #include "gmp-impl.h"
25 #include "tests.h"
26 
27 
28 /* The i386 MPN_INCR_U and MPN_DECR_U have special cases for "n" being a
29    compile-time constant 1, so that's exercised explicitly.  */
30 
31 
32 #define M     GMP_NUMB_MAX
33 #define SIZE  ((mp_size_t) 10)
34 
35 
36 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)37 check_one (const char *name, int i,
38            mp_srcptr src, mp_limb_t n,
39            mp_srcptr got, mp_srcptr want, mp_size_t size)
40 {
41   if (! refmpn_equal_anynail (got, want, size))
42     {
43       printf ("Wrong at %s i=%d\n", name, i);
44       mpn_trace ("  src", src,  size);
45       mpn_trace ("    n", &n,   (mp_size_t) 1);
46       mpn_trace ("  got", got,  size);
47       mpn_trace (" want", want, size);
48       abort ();
49     }
50 }
51 
52 
53 void
check_incr_data(void)54 check_incr_data (void)
55 {
56   static const struct {
57     mp_limb_t        n;
58     const mp_limb_t  src[SIZE];
59     const mp_limb_t  want[SIZE];
60   } data[] = {
61     { 1, { 0 },   { 1 } },
62     { 1, { 123 }, { 124 } },
63     { 2, { 0 },   { 2 } },
64     { 2, { 123 }, { 125 } },
65     { M, { 0 },   { M } },
66 
67     { 1, { M, 0 },   { 0,   1 } },
68     { 1, { M, 123 }, { 0,   124 } },
69     { 2, { M, 0 },   { 1,   1 } },
70     { 2, { M, 123 }, { 1,   124 } },
71     { M, { M, 0 },   { M-1, 1 } },
72     { M, { M, 123 }, { M-1, 124 } },
73 
74     { 1, { M, M, 0 },   { 0,   0, 1 } },
75     { 1, { M, M, 123 }, { 0,   0, 124 } },
76     { 2, { M, M, 0 },   { 1,   0, 1 } },
77     { 2, { M, M, 123 }, { 1,   0, 124 } },
78     { M, { M, M, 0 },   { M-1, 0, 1 } },
79     { M, { M, M, 123 }, { M-1, 0, 124 } },
80 
81     { 1, { M, M, M, 0 },   { 0,   0, 0, 1 } },
82     { 1, { M, M, M, 123 }, { 0,   0, 0, 124 } },
83     { 2, { M, M, M, 0 },   { 1,   0, 0, 1 } },
84     { 2, { M, M, M, 123 }, { 1,   0, 0, 124 } },
85     { M, { M, M, M, 0 },   { M-1, 0, 0, 1 } },
86     { M, { M, M, M, 123 }, { M-1, 0, 0, 124 } },
87 
88     { 1, { M, M, M, M, 0 },   { 0,   0, 0, 0, 1 } },
89     { 1, { M, M, M, M, 123 }, { 0,   0, 0, 0, 124 } },
90     { 2, { M, M, M, M, 0 },   { 1,   0, 0, 0, 1 } },
91     { 2, { M, M, M, M, 123 }, { 1,   0, 0, 0, 124 } },
92     { M, { M, M, M, M, 0 },   { M-1, 0, 0, 0, 1 } },
93     { M, { M, M, M, M, 123 }, { M-1, 0, 0, 0, 124
94 #if defined (__hpux) && ! defined (__GNUC__)
95     /* Some versions (at least HP92453-01 B.11.11.23709.GP) of the
96        HP C compilers fail to zero-fill aggregates as the ISO C standard
97        requires (cf 6.5.7 Initialization).  Compensate here:  */
98 				, 0, 0, 0, 0, 0
99 #endif
100     } }
101   };
102 
103   mp_limb_t  got[SIZE];
104   int   i;
105 
106   for (i = 0; i < numberof (data); i++)
107     {
108       refmpn_copyi (got, data[i].src, SIZE);
109       MPN_INCR_U (got, SIZE, data[i].n);
110       check_one ("check_incr (general)", i,
111                  data[i].src, data[i].n,
112                  got, data[i].want, SIZE);
113 
114       if (data[i].n == 1)
115         {
116           refmpn_copyi (got, data[i].src, SIZE);
117           MPN_INCR_U (got, SIZE, CNST_LIMB(1));
118           check_one ("check_incr (const 1)", i,
119                      data[i].src, data[i].n,
120                      got, data[i].want, SIZE);
121         }
122     }
123 }
124 
125 void
check_decr_data(void)126 check_decr_data (void)
127 {
128   static const struct {
129     mp_limb_t        n;
130     const mp_limb_t  src[SIZE];
131     const mp_limb_t  want[SIZE];
132   } data[] = {
133     { 1,   { 1 },   { 0   } },
134     { 1,   { 123 }, { 122 } },
135     { 1,   { M },   { M-1 } },
136     { 2,   { 2 },   { 0   } },
137     { 2,   { 123 }, { 121 } },
138     { M,   { M },   { 0   } },
139     { M-1, { M },   { 1   } },
140 
141     { 1,   { 0,   1   }, { M,   0   } },
142     { 1,   { 0,   123 }, { M,   122 } },
143     { 1,   { 0,   M   }, { M,   M-1 } },
144     { 2,   { 0,   123 }, { M-1, 122 } },
145     { 2,   { 1,   123 }, { M,   122 } },
146     { M,   { 0,   123 }, { 1,   122 } },
147     { M,   { M-1, M   }, { M,   M-1 } },
148 
149     { 1,   { 0,   0, 1   }, { M,   M, 0   } },
150     { 1,   { 0,   0, 123 }, { M,   M, 122 } },
151     { 1,   { 0,   0, M   }, { M,   M, M-1 } },
152     { 2,   { 0,   0, 123 }, { M-1, M, 122 } },
153     { 2,   { 1,   0, 123 }, { M,   M, 122 } },
154     { M,   { 0,   0, 123 }, { 1,   M, 122 } },
155     { M,   { M-1, 0, M   }, { M,   M, M-1 } },
156 
157     { 1,   { 0,   0, 0, 1   }, { M,   M, M, 0   } },
158     { 1,   { 0,   0, 0, 123 }, { M,   M, M, 122 } },
159     { 1,   { 0,   0, 0, M   }, { M,   M, M, M-1 } },
160     { 2,   { 0,   0, 0, 123 }, { M-1, M, M, 122 } },
161     { 2,   { 1,   0, 0, 123 }, { M,   M, M, 122 } },
162     { M,   { 0,   0, 0, 123 }, { 1,   M, M, 122 } },
163     { M,   { M-1, 0, 0, M   }, { M,   M, M, M-1 } },
164 
165     { 1,   { 0,   0, 0, 0, 1   }, { M,   M, M, M, 0   } },
166     { 1,   { 0,   0, 0, 0, 123 }, { M,   M, M, M, 122 } },
167     { 1,   { 0,   0, 0, 0, M   }, { M,   M, M, M, M-1 } },
168     { 2,   { 0,   0, 0, 0, 123 }, { M-1, M, M, M, 122 } },
169     { 2,   { 1,   0, 0, 0, 123 }, { M,   M, M, M, 122 } },
170     { M,   { 0,   0, 0, 0, 123 }, { 1,   M, M, M, 122 } },
171     { M,   { M-1, 0, 0, 0, M   }, { M,   M, M, M, M-1 } },
172 
173     { 1,   { 0,   0, 0, 0, 0, 1   }, { M,   M, M, M, M, 0   } },
174     { 1,   { 0,   0, 0, 0, 0, 123 }, { M,   M, M, M, M, 122 } },
175     { 1,   { 0,   0, 0, 0, 0, M   }, { M,   M, M, M, M, M-1 } },
176     { 2,   { 0,   0, 0, 0, 0, 123 }, { M-1, M, M, M, M, 122 } },
177     { 2,   { 1,   0, 0, 0, 0, 123 }, { M,   M, M, M, M, 122 } },
178     { M,   { 0,   0, 0, 0, 0, 123 }, { 1,   M, M, M, M, 122 } },
179     { M,   { M-1, 0, 0, 0, 0, M   }, { M,   M, M, M, M, M-1
180 #if defined (__hpux) && ! defined (__GNUC__)
181     /* For explanation of this garbage, see previous function.  */
182 				       , 0, 0, 0, 0
183 #endif
184     } }
185   };
186 
187   mp_limb_t  got[SIZE];
188   int   i;
189 
190   for (i = 0; i < numberof (data); i++)
191     {
192       refmpn_copyi (got, data[i].src, SIZE);
193       MPN_DECR_U (got, SIZE, data[i].n);
194       check_one ("check_decr_data", i,
195                  data[i].src, data[i].n,
196                  got, data[i].want, SIZE);
197 
198       if (data[i].n == 1)
199         {
200           refmpn_copyi (got, data[i].src, SIZE);
201           MPN_DECR_U (got, SIZE, CNST_LIMB(1));
202           check_one ("check_decr (const 1)", i,
203                      data[i].src, data[i].n,
204                      got, data[i].want, SIZE);
205         }
206     }
207 }
208 
209 
210 int
main(void)211 main (void)
212 {
213   tests_start ();
214   mp_trace_base = -16;
215 
216   check_incr_data ();
217   check_decr_data ();
218 
219   tests_end ();
220   exit (0);
221 }
222