1 /* Test mpn_add_1 and mpn_sub_1. 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 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 #define M GMP_NUMB_MAX 29 #define ASIZE 10 30 #define MAGIC 0x1234 31 32 #define SETUP() \ 33 do { \ 34 refmpn_random (got, data[i].size); \ 35 got[data[i].size] = MAGIC; \ 36 } while (0) 37 38 #define SETUP_INPLACE() \ 39 do { \ 40 refmpn_copyi (got, data[i].src, data[i].size); \ 41 got[data[i].size] = MAGIC; \ 42 } while (0) 43 44 #define VERIFY(name) \ 45 do { \ 46 verify (name, i, data[i].src, data[i].n, \ 47 got_c, data[i].want_c, \ 48 got, data[i].want, data[i].size); \ 49 } while (0) 50 51 typedef mp_limb_t (*mpn_aors_1_t) (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); 52 mpn_aors_1_t fudge (mpn_aors_1_t); 53 54 55 void 56 verify (const char *name, int i, 57 mp_srcptr src, mp_limb_t n, 58 mp_limb_t got_c, mp_limb_t want_c, 59 mp_srcptr got, mp_srcptr want, mp_size_t size) 60 { 61 if (got[size] != MAGIC) 62 { 63 printf ("Overwrite at %s i=%d\n", name, i); 64 abort (); 65 } 66 67 if (got_c != want_c || ! refmpn_equal_anynail (got, want, size)) 68 { 69 printf ("Wrong at %s i=%d size=%ld\n", name, i, size); 70 mpn_trace (" src", src, size); 71 mpn_trace (" n", &n, (mp_size_t) 1); 72 mpn_trace (" got", got, size); 73 mpn_trace (" want", want, size); 74 mpn_trace (" got c", &got_c, (mp_size_t) 1); 75 mpn_trace ("want c", &want_c, (mp_size_t) 1); 76 abort (); 77 } 78 } 79 80 81 void 82 check_add_1 (void) 83 { 84 static const struct { 85 mp_size_t size; 86 mp_limb_t n; 87 const mp_limb_t src[ASIZE]; 88 mp_limb_t want_c; 89 const mp_limb_t want[ASIZE]; 90 } data[] = { 91 { 1, 0, { 0 }, 0, { 0 } }, 92 { 1, 0, { 1 }, 0, { 1 } }, 93 { 1, 1, { 0 }, 0, { 1 } }, 94 { 1, 0, { M }, 0, { M } }, 95 { 1, M, { 0 }, 0, { M } }, 96 { 1, 1, { 123 }, 0, { 124 } }, 97 98 { 1, 1, { M }, 1, { 0 } }, 99 { 1, M, { 1 }, 1, { 0 } }, 100 { 1, M, { M }, 1, { M-1 } }, 101 102 { 2, 0, { 0, 0 }, 0, { 0, 0 } }, 103 { 2, 0, { 1, 0 }, 0, { 1, 0 } }, 104 { 2, 1, { 0, 0 }, 0, { 1, 0 } }, 105 { 2, 0, { M, 0 }, 0, { M, 0 } }, 106 { 2, M, { 0, 0 }, 0, { M, 0 } }, 107 { 2, 1, { M, 0 }, 0, { 0, 1 } }, 108 { 2, M, { 1, 0 }, 0, { 0, 1 } }, 109 { 2, M, { M, 0 }, 0, { M-1, 1 } }, 110 { 2, M, { M, 0 }, 0, { M-1, 1 } }, 111 112 { 2, 1, { M, M }, 1, { 0, 0 } }, 113 { 2, M, { 1, M }, 1, { 0, 0 } }, 114 { 2, M, { M, M }, 1, { M-1, 0 } }, 115 { 2, M, { M, M }, 1, { M-1, 0 } }, 116 117 { 3, 1, { M, M, M }, 1, { 0, 0, 0 } }, 118 { 3, M, { 1, M, M }, 1, { 0, 0, 0 } }, 119 { 3, M, { M, M, M }, 1, { M-1, 0, 0 } }, 120 { 3, M, { M, M, M }, 1, { M-1, 0, 0 } }, 121 122 { 4, 1, { M, M, M, M }, 1, { 0, 0, 0, 0 } }, 123 { 4, M, { 1, M, M, M }, 1, { 0, 0, 0, 0 } }, 124 { 4, M, { M, M, M, M }, 1, { M-1, 0, 0, 0 } }, 125 { 4, M, { M, M, M, M }, 1, { M-1, 0, 0, 0 } }, 126 127 { 4, M, { M, 0, M, M }, 0, { M-1, 1, M, M } }, 128 { 4, M, { M, M-1, M, M }, 0, { M-1, M, M, M } }, 129 130 { 4, M, { M, M, 0, M }, 0, { M-1, 0, 1, M } }, 131 { 4, M, { M, M, M-1, M }, 0, { M-1, 0, M, M } }, 132 }; 133 134 mp_limb_t got[ASIZE]; 135 mp_limb_t got_c; 136 int i; 137 138 for (i = 0; i < numberof (data); i++) 139 { 140 SETUP (); 141 got_c = mpn_add_1 (got, data[i].src, data[i].size, data[i].n); 142 VERIFY ("check_add_1 (separate)"); 143 144 SETUP_INPLACE (); 145 got_c = mpn_add_1 (got, got, data[i].size, data[i].n); 146 VERIFY ("check_add_1 (in-place)"); 147 148 if (data[i].n == 1) 149 { 150 SETUP (); 151 got_c = mpn_add_1 (got, data[i].src, data[i].size, CNST_LIMB(1)); 152 VERIFY ("check_add_1 (separate, const 1)"); 153 154 SETUP_INPLACE (); 155 got_c = mpn_add_1 (got, got, data[i].size, CNST_LIMB(1)); 156 VERIFY ("check_add_1 (in-place, const 1)"); 157 } 158 159 /* Same again on functions, not inlines. */ 160 SETUP (); 161 got_c = (*fudge(mpn_add_1)) (got, data[i].src, data[i].size, data[i].n); 162 VERIFY ("check_add_1 (function, separate)"); 163 164 SETUP_INPLACE (); 165 got_c = (*fudge(mpn_add_1)) (got, got, data[i].size, data[i].n); 166 VERIFY ("check_add_1 (function, in-place)"); 167 } 168 } 169 170 void 171 check_sub_1 (void) 172 { 173 static const struct { 174 mp_size_t size; 175 mp_limb_t n; 176 const mp_limb_t src[ASIZE]; 177 mp_limb_t want_c; 178 const mp_limb_t want[ASIZE]; 179 } data[] = { 180 { 1, 0, { 0 }, 0, { 0 } }, 181 { 1, 0, { 1 }, 0, { 1 } }, 182 { 1, 1, { 1 }, 0, { 0 } }, 183 { 1, 0, { M }, 0, { M } }, 184 { 1, 1, { M }, 0, { M-1 } }, 185 { 1, 1, { 123 }, 0, { 122 } }, 186 187 { 1, 1, { 0 }, 1, { M } }, 188 { 1, M, { 0 }, 1, { 1 } }, 189 190 { 2, 0, { 0, 0 }, 0, { 0, 0 } }, 191 { 2, 0, { 1, 0 }, 0, { 1, 0 } }, 192 { 2, 1, { 1, 0 }, 0, { 0, 0 } }, 193 { 2, 0, { M, 0 }, 0, { M, 0 } }, 194 { 2, 1, { M, 0 }, 0, { M-1, 0 } }, 195 { 2, 1, { 123, 0 }, 0, { 122, 0 } }, 196 197 { 2, 1, { 0, 0 }, 1, { M, M } }, 198 { 2, M, { 0, 0 }, 1, { 1, M } }, 199 200 { 3, 0, { 0, 0, 0 }, 0, { 0, 0, 0 } }, 201 { 3, 0, { 123, 0, 0 }, 0, { 123, 0, 0 } }, 202 203 { 3, 1, { 0, 0, 0 }, 1, { M, M, M } }, 204 { 3, M, { 0, 0, 0 }, 1, { 1, M, M } }, 205 206 { 4, 1, { 0, 0, 0, 0 }, 1, { M, M, M, M } }, 207 { 4, M, { 0, 0, 0, 0 }, 1, { 1, M, M, M } }, 208 209 { 4, 1, { 0, 0, 1, 42 }, 0, { M, M, 0, 42 } }, 210 { 4, M, { 0, 0, 123, 24 }, 0, { 1, M, 122, 24 } }, 211 }; 212 213 mp_limb_t got[ASIZE]; 214 mp_limb_t got_c; 215 int i; 216 217 for (i = 0; i < numberof (data); i++) 218 { 219 SETUP (); 220 got_c = mpn_sub_1 (got, data[i].src, data[i].size, data[i].n); 221 VERIFY ("check_sub_1 (separate)"); 222 223 SETUP_INPLACE (); 224 got_c = mpn_sub_1 (got, got, data[i].size, data[i].n); 225 VERIFY ("check_sub_1 (in-place)"); 226 227 if (data[i].n == 1) 228 { 229 SETUP (); 230 got_c = mpn_sub_1 (got, data[i].src, data[i].size, CNST_LIMB(1)); 231 VERIFY ("check_sub_1 (separate, const 1)"); 232 233 SETUP_INPLACE (); 234 got_c = mpn_sub_1 (got, got, data[i].size, CNST_LIMB(1)); 235 VERIFY ("check_sub_1 (in-place, const 1)"); 236 } 237 238 /* Same again on functions, not inlines. */ 239 SETUP (); 240 got_c = (*fudge(mpn_sub_1)) (got, data[i].src, data[i].size, data[i].n); 241 VERIFY ("check_sub_1 (function, separate)"); 242 243 SETUP_INPLACE (); 244 got_c = (*fudge(mpn_sub_1)) (got, got, data[i].size, data[i].n); 245 VERIFY ("check_sub_1 (function, in-place)"); 246 } 247 } 248 249 /* Try to prevent the optimizer inlining. */ 250 mpn_aors_1_t 251 fudge (mpn_aors_1_t f) 252 { 253 return f; 254 } 255 256 int 257 main (void) 258 { 259 tests_start (); 260 mp_trace_base = -16; 261 262 check_add_1 (); 263 check_sub_1 (); 264 265 tests_end (); 266 exit (0); 267 } 268