1/* Test MPN_INCR_U and MPN_DECR_U.
2
3Copyright 2001, 2002 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library.
6
7The GNU MP Library is free software; you can redistribute it and/or modify
8it under the terms of the GNU Lesser General Public License as published by
9the Free Software Foundation; either version 3 of the License, or (at your
10option) any later version.
11
12The GNU MP Library is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15License for more details.
16
17You should have received a copy of the GNU Lesser General Public License
18along with the GNU MP Library.  If not, see http://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
36void
37check_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
53void
54check_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
125void
126check_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
210int
211main (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