1 1.1 mrg /* Test mpn_add_1 and mpn_sub_1. 2 1.1 mrg 3 1.1 mrg Copyright 2001, 2002 Free Software Foundation, Inc. 4 1.1 mrg 5 1.1.1.2 mrg This file is part of the GNU MP Library test suite. 6 1.1 mrg 7 1.1.1.2 mrg The GNU MP Library test suite is free software; you can redistribute it 8 1.1.1.2 mrg and/or modify it under the terms of the GNU General Public License as 9 1.1.1.2 mrg published by the Free Software Foundation; either version 3 of the License, 10 1.1.1.2 mrg or (at your option) any later version. 11 1.1.1.2 mrg 12 1.1.1.2 mrg The GNU MP Library test suite is distributed in the hope that it will be 13 1.1.1.2 mrg useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1.1.2 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15 1.1.1.2 mrg Public License for more details. 16 1.1 mrg 17 1.1.1.2 mrg You should have received a copy of the GNU General Public License along with 18 1.1.1.3 mrg the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ 19 1.1 mrg 20 1.1 mrg #include <stdio.h> 21 1.1 mrg #include <stdlib.h> 22 1.1 mrg 23 1.1 mrg #include "gmp-impl.h" 24 1.1 mrg #include "tests.h" 25 1.1 mrg 26 1.1 mrg 27 1.1 mrg #define M GMP_NUMB_MAX 28 1.1 mrg #define ASIZE 10 29 1.1 mrg #define MAGIC 0x1234 30 1.1 mrg 31 1.1 mrg #define SETUP() \ 32 1.1 mrg do { \ 33 1.1 mrg refmpn_random (got, data[i].size); \ 34 1.1 mrg got[data[i].size] = MAGIC; \ 35 1.1 mrg } while (0) 36 1.1 mrg 37 1.1 mrg #define SETUP_INPLACE() \ 38 1.1 mrg do { \ 39 1.1 mrg refmpn_copyi (got, data[i].src, data[i].size); \ 40 1.1 mrg got[data[i].size] = MAGIC; \ 41 1.1 mrg } while (0) 42 1.1 mrg 43 1.1 mrg #define VERIFY(name) \ 44 1.1 mrg do { \ 45 1.1 mrg verify (name, i, data[i].src, data[i].n, \ 46 1.1 mrg got_c, data[i].want_c, \ 47 1.1 mrg got, data[i].want, data[i].size); \ 48 1.1 mrg } while (0) 49 1.1 mrg 50 1.1.1.2 mrg typedef mp_limb_t (*mpn_aors_1_t) (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); 51 1.1.1.2 mrg mpn_aors_1_t fudge (mpn_aors_1_t); 52 1.1 mrg 53 1.1 mrg 54 1.1 mrg void 55 1.1 mrg verify (const char *name, int i, 56 1.1 mrg mp_srcptr src, mp_limb_t n, 57 1.1 mrg mp_limb_t got_c, mp_limb_t want_c, 58 1.1 mrg mp_srcptr got, mp_srcptr want, mp_size_t size) 59 1.1 mrg { 60 1.1 mrg if (got[size] != MAGIC) 61 1.1 mrg { 62 1.1 mrg printf ("Overwrite at %s i=%d\n", name, i); 63 1.1 mrg abort (); 64 1.1 mrg } 65 1.1 mrg 66 1.1 mrg if (got_c != want_c || ! refmpn_equal_anynail (got, want, size)) 67 1.1 mrg { 68 1.1 mrg printf ("Wrong at %s i=%d size=%ld\n", name, i, size); 69 1.1 mrg mpn_trace (" src", src, size); 70 1.1 mrg mpn_trace (" n", &n, (mp_size_t) 1); 71 1.1 mrg mpn_trace (" got", got, size); 72 1.1 mrg mpn_trace (" want", want, size); 73 1.1 mrg mpn_trace (" got c", &got_c, (mp_size_t) 1); 74 1.1 mrg mpn_trace ("want c", &want_c, (mp_size_t) 1); 75 1.1 mrg abort (); 76 1.1 mrg } 77 1.1 mrg } 78 1.1 mrg 79 1.1 mrg 80 1.1 mrg void 81 1.1 mrg check_add_1 (void) 82 1.1 mrg { 83 1.1 mrg static const struct { 84 1.1 mrg mp_size_t size; 85 1.1 mrg mp_limb_t n; 86 1.1 mrg const mp_limb_t src[ASIZE]; 87 1.1 mrg mp_limb_t want_c; 88 1.1 mrg const mp_limb_t want[ASIZE]; 89 1.1 mrg } data[] = { 90 1.1 mrg { 1, 0, { 0 }, 0, { 0 } }, 91 1.1 mrg { 1, 0, { 1 }, 0, { 1 } }, 92 1.1 mrg { 1, 1, { 0 }, 0, { 1 } }, 93 1.1 mrg { 1, 0, { M }, 0, { M } }, 94 1.1 mrg { 1, M, { 0 }, 0, { M } }, 95 1.1 mrg { 1, 1, { 123 }, 0, { 124 } }, 96 1.1 mrg 97 1.1 mrg { 1, 1, { M }, 1, { 0 } }, 98 1.1 mrg { 1, M, { 1 }, 1, { 0 } }, 99 1.1 mrg { 1, M, { M }, 1, { M-1 } }, 100 1.1 mrg 101 1.1 mrg { 2, 0, { 0, 0 }, 0, { 0, 0 } }, 102 1.1 mrg { 2, 0, { 1, 0 }, 0, { 1, 0 } }, 103 1.1 mrg { 2, 1, { 0, 0 }, 0, { 1, 0 } }, 104 1.1 mrg { 2, 0, { M, 0 }, 0, { M, 0 } }, 105 1.1 mrg { 2, M, { 0, 0 }, 0, { M, 0 } }, 106 1.1 mrg { 2, 1, { M, 0 }, 0, { 0, 1 } }, 107 1.1 mrg { 2, M, { 1, 0 }, 0, { 0, 1 } }, 108 1.1 mrg { 2, M, { M, 0 }, 0, { M-1, 1 } }, 109 1.1 mrg { 2, M, { M, 0 }, 0, { M-1, 1 } }, 110 1.1 mrg 111 1.1 mrg { 2, 1, { M, M }, 1, { 0, 0 } }, 112 1.1 mrg { 2, M, { 1, M }, 1, { 0, 0 } }, 113 1.1 mrg { 2, M, { M, M }, 1, { M-1, 0 } }, 114 1.1 mrg { 2, M, { M, M }, 1, { M-1, 0 } }, 115 1.1 mrg 116 1.1 mrg { 3, 1, { M, M, M }, 1, { 0, 0, 0 } }, 117 1.1 mrg { 3, M, { 1, M, M }, 1, { 0, 0, 0 } }, 118 1.1 mrg { 3, M, { M, M, M }, 1, { M-1, 0, 0 } }, 119 1.1 mrg { 3, M, { M, M, M }, 1, { M-1, 0, 0 } }, 120 1.1 mrg 121 1.1 mrg { 4, 1, { M, M, M, M }, 1, { 0, 0, 0, 0 } }, 122 1.1 mrg { 4, M, { 1, M, M, M }, 1, { 0, 0, 0, 0 } }, 123 1.1 mrg { 4, M, { M, M, M, M }, 1, { M-1, 0, 0, 0 } }, 124 1.1 mrg { 4, M, { M, M, M, M }, 1, { M-1, 0, 0, 0 } }, 125 1.1 mrg 126 1.1 mrg { 4, M, { M, 0, M, M }, 0, { M-1, 1, M, M } }, 127 1.1 mrg { 4, M, { M, M-1, M, M }, 0, { M-1, M, M, M } }, 128 1.1 mrg 129 1.1 mrg { 4, M, { M, M, 0, M }, 0, { M-1, 0, 1, M } }, 130 1.1 mrg { 4, M, { M, M, M-1, M }, 0, { M-1, 0, M, M } }, 131 1.1 mrg }; 132 1.1 mrg 133 1.1 mrg mp_limb_t got[ASIZE]; 134 1.1 mrg mp_limb_t got_c; 135 1.1.1.3 mrg /* mpn_sec_add_a_itch(n) <= n */ 136 1.1.1.3 mrg mp_limb_t scratch[ASIZE]; 137 1.1 mrg int i; 138 1.1 mrg 139 1.1 mrg for (i = 0; i < numberof (data); i++) 140 1.1 mrg { 141 1.1 mrg SETUP (); 142 1.1 mrg got_c = mpn_add_1 (got, data[i].src, data[i].size, data[i].n); 143 1.1 mrg VERIFY ("check_add_1 (separate)"); 144 1.1 mrg 145 1.1 mrg SETUP_INPLACE (); 146 1.1 mrg got_c = mpn_add_1 (got, got, data[i].size, data[i].n); 147 1.1 mrg VERIFY ("check_add_1 (in-place)"); 148 1.1 mrg 149 1.1.1.3 mrg SETUP (); 150 1.1.1.3 mrg scratch [mpn_sec_add_1_itch(data[i].size)] = MAGIC; 151 1.1.1.3 mrg got_c = mpn_sec_add_1 (got, data[i].src, data[i].size, data[i].n, scratch); 152 1.1.1.3 mrg got_c ^= scratch [mpn_sec_add_1_itch(data[i].size)] ^ MAGIC; 153 1.1.1.3 mrg VERIFY ("check_sec_add_1 (separate)"); 154 1.1.1.3 mrg 155 1.1.1.3 mrg SETUP_INPLACE (); 156 1.1.1.3 mrg got_c = mpn_sec_add_1 (got, got, data[i].size, data[i].n, scratch); 157 1.1.1.3 mrg VERIFY ("check_sec_add_1 (in-place)"); 158 1.1.1.3 mrg 159 1.1 mrg if (data[i].n == 1) 160 1.1 mrg { 161 1.1 mrg SETUP (); 162 1.1 mrg got_c = mpn_add_1 (got, data[i].src, data[i].size, CNST_LIMB(1)); 163 1.1 mrg VERIFY ("check_add_1 (separate, const 1)"); 164 1.1 mrg 165 1.1 mrg SETUP_INPLACE (); 166 1.1 mrg got_c = mpn_add_1 (got, got, data[i].size, CNST_LIMB(1)); 167 1.1 mrg VERIFY ("check_add_1 (in-place, const 1)"); 168 1.1.1.3 mrg 169 1.1.1.3 mrg SETUP (); 170 1.1.1.3 mrg got_c = mpn_sec_add_1 (got, data[i].src, data[i].size, 171 1.1.1.3 mrg CNST_LIMB(1), scratch); 172 1.1.1.3 mrg VERIFY ("check_sec_add_1 (separate, const 1)"); 173 1.1.1.3 mrg 174 1.1.1.3 mrg SETUP_INPLACE (); 175 1.1.1.3 mrg got_c = mpn_sec_add_1 (got, got, data[i].size, 176 1.1.1.3 mrg CNST_LIMB(1), scratch); 177 1.1.1.3 mrg VERIFY ("check_sec_add_1 (in-place, const 1)"); 178 1.1 mrg } 179 1.1 mrg 180 1.1 mrg /* Same again on functions, not inlines. */ 181 1.1 mrg SETUP (); 182 1.1 mrg got_c = (*fudge(mpn_add_1)) (got, data[i].src, data[i].size, data[i].n); 183 1.1 mrg VERIFY ("check_add_1 (function, separate)"); 184 1.1 mrg 185 1.1 mrg SETUP_INPLACE (); 186 1.1 mrg got_c = (*fudge(mpn_add_1)) (got, got, data[i].size, data[i].n); 187 1.1 mrg VERIFY ("check_add_1 (function, in-place)"); 188 1.1 mrg } 189 1.1 mrg } 190 1.1 mrg 191 1.1 mrg void 192 1.1 mrg check_sub_1 (void) 193 1.1 mrg { 194 1.1 mrg static const struct { 195 1.1 mrg mp_size_t size; 196 1.1 mrg mp_limb_t n; 197 1.1 mrg const mp_limb_t src[ASIZE]; 198 1.1 mrg mp_limb_t want_c; 199 1.1 mrg const mp_limb_t want[ASIZE]; 200 1.1 mrg } data[] = { 201 1.1 mrg { 1, 0, { 0 }, 0, { 0 } }, 202 1.1 mrg { 1, 0, { 1 }, 0, { 1 } }, 203 1.1 mrg { 1, 1, { 1 }, 0, { 0 } }, 204 1.1 mrg { 1, 0, { M }, 0, { M } }, 205 1.1 mrg { 1, 1, { M }, 0, { M-1 } }, 206 1.1 mrg { 1, 1, { 123 }, 0, { 122 } }, 207 1.1 mrg 208 1.1 mrg { 1, 1, { 0 }, 1, { M } }, 209 1.1 mrg { 1, M, { 0 }, 1, { 1 } }, 210 1.1 mrg 211 1.1 mrg { 2, 0, { 0, 0 }, 0, { 0, 0 } }, 212 1.1 mrg { 2, 0, { 1, 0 }, 0, { 1, 0 } }, 213 1.1 mrg { 2, 1, { 1, 0 }, 0, { 0, 0 } }, 214 1.1 mrg { 2, 0, { M, 0 }, 0, { M, 0 } }, 215 1.1 mrg { 2, 1, { M, 0 }, 0, { M-1, 0 } }, 216 1.1 mrg { 2, 1, { 123, 0 }, 0, { 122, 0 } }, 217 1.1 mrg 218 1.1 mrg { 2, 1, { 0, 0 }, 1, { M, M } }, 219 1.1 mrg { 2, M, { 0, 0 }, 1, { 1, M } }, 220 1.1 mrg 221 1.1 mrg { 3, 0, { 0, 0, 0 }, 0, { 0, 0, 0 } }, 222 1.1 mrg { 3, 0, { 123, 0, 0 }, 0, { 123, 0, 0 } }, 223 1.1 mrg 224 1.1 mrg { 3, 1, { 0, 0, 0 }, 1, { M, M, M } }, 225 1.1 mrg { 3, M, { 0, 0, 0 }, 1, { 1, M, M } }, 226 1.1 mrg 227 1.1 mrg { 4, 1, { 0, 0, 0, 0 }, 1, { M, M, M, M } }, 228 1.1 mrg { 4, M, { 0, 0, 0, 0 }, 1, { 1, M, M, M } }, 229 1.1 mrg 230 1.1 mrg { 4, 1, { 0, 0, 1, 42 }, 0, { M, M, 0, 42 } }, 231 1.1 mrg { 4, M, { 0, 0, 123, 24 }, 0, { 1, M, 122, 24 } }, 232 1.1 mrg }; 233 1.1 mrg 234 1.1 mrg mp_limb_t got[ASIZE]; 235 1.1 mrg mp_limb_t got_c; 236 1.1.1.3 mrg /* mpn_sec_sub_1_itch(n) <= n */ 237 1.1.1.3 mrg mp_limb_t scratch[ASIZE]; 238 1.1 mrg int i; 239 1.1 mrg 240 1.1 mrg for (i = 0; i < numberof (data); i++) 241 1.1 mrg { 242 1.1 mrg SETUP (); 243 1.1 mrg got_c = mpn_sub_1 (got, data[i].src, data[i].size, data[i].n); 244 1.1 mrg VERIFY ("check_sub_1 (separate)"); 245 1.1 mrg 246 1.1 mrg SETUP_INPLACE (); 247 1.1 mrg got_c = mpn_sub_1 (got, got, data[i].size, data[i].n); 248 1.1 mrg VERIFY ("check_sub_1 (in-place)"); 249 1.1 mrg 250 1.1.1.3 mrg SETUP (); 251 1.1.1.3 mrg scratch [mpn_sec_sub_1_itch(data[i].size)] = MAGIC; 252 1.1.1.3 mrg got_c = mpn_sec_sub_1 (got, data[i].src, data[i].size, data[i].n, scratch); 253 1.1.1.3 mrg got_c ^= scratch [mpn_sec_sub_1_itch(data[i].size)] ^ MAGIC; 254 1.1.1.3 mrg VERIFY ("check_sec_sub_1 (separate)"); 255 1.1.1.3 mrg 256 1.1.1.3 mrg SETUP_INPLACE (); 257 1.1.1.3 mrg got_c = mpn_sec_sub_1 (got, got, data[i].size, data[i].n, scratch); 258 1.1.1.3 mrg VERIFY ("check_sec_sub_1 (in-place)"); 259 1.1.1.3 mrg 260 1.1 mrg if (data[i].n == 1) 261 1.1 mrg { 262 1.1 mrg SETUP (); 263 1.1 mrg got_c = mpn_sub_1 (got, data[i].src, data[i].size, CNST_LIMB(1)); 264 1.1 mrg VERIFY ("check_sub_1 (separate, const 1)"); 265 1.1 mrg 266 1.1 mrg SETUP_INPLACE (); 267 1.1 mrg got_c = mpn_sub_1 (got, got, data[i].size, CNST_LIMB(1)); 268 1.1 mrg VERIFY ("check_sub_1 (in-place, const 1)"); 269 1.1.1.3 mrg 270 1.1.1.3 mrg SETUP (); 271 1.1.1.3 mrg got_c = mpn_sec_sub_1 (got, data[i].src, data[i].size, 272 1.1.1.3 mrg CNST_LIMB(1), scratch); 273 1.1.1.3 mrg VERIFY ("check_sec_sub_1 (separate, const 1)"); 274 1.1.1.3 mrg 275 1.1.1.3 mrg SETUP_INPLACE (); 276 1.1.1.3 mrg got_c = mpn_sec_sub_1 (got, got, data[i].size, 277 1.1.1.3 mrg CNST_LIMB(1), scratch); 278 1.1.1.3 mrg VERIFY ("check_sec_sub_1 (in-place, const 1)"); 279 1.1 mrg } 280 1.1 mrg 281 1.1 mrg /* Same again on functions, not inlines. */ 282 1.1 mrg SETUP (); 283 1.1 mrg got_c = (*fudge(mpn_sub_1)) (got, data[i].src, data[i].size, data[i].n); 284 1.1 mrg VERIFY ("check_sub_1 (function, separate)"); 285 1.1 mrg 286 1.1 mrg SETUP_INPLACE (); 287 1.1 mrg got_c = (*fudge(mpn_sub_1)) (got, got, data[i].size, data[i].n); 288 1.1 mrg VERIFY ("check_sub_1 (function, in-place)"); 289 1.1 mrg } 290 1.1 mrg } 291 1.1 mrg 292 1.1 mrg /* Try to prevent the optimizer inlining. */ 293 1.1 mrg mpn_aors_1_t 294 1.1 mrg fudge (mpn_aors_1_t f) 295 1.1 mrg { 296 1.1 mrg return f; 297 1.1 mrg } 298 1.1 mrg 299 1.1 mrg int 300 1.1 mrg main (void) 301 1.1 mrg { 302 1.1 mrg tests_start (); 303 1.1 mrg mp_trace_base = -16; 304 1.1 mrg 305 1.1 mrg check_add_1 (); 306 1.1 mrg check_sub_1 (); 307 1.1 mrg 308 1.1 mrg tests_end (); 309 1.1 mrg exit (0); 310 1.1 mrg } 311