source: git/ntl/src/gen_lip_gmp_aux.c @ 33a041

spielwiese
Last change on this file since 33a041 was 09da99, checked in by Hans Schönemann <hannes@…>, 21 years ago
*hannes: NTL- 5.3.1 git-svn-id: file:///usr/local/Singular/svn/trunk@6910 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 9.8 KB
Line 
1
2
3#include <stdlib.h>
4#include <math.h>
5#include <stdio.h>
6
7#include <NTL/config.h>
8
9#ifdef NTL_GMP_HACK
10
11#include <gmp.h>
12#include <NTL/mach_desc.h>
13
14
15int gcd(int a, int b)
16{
17   int u, v, t, x;
18
19   if (b==0)
20      x = a;
21   else {
22      u = a;
23      v = b;
24      do {
25         t = u % v;
26         u = v; 
27         v = t;
28      } while (v != 0);
29
30      x = u;
31   }
32
33   return x;
34}
35
36int pow2(int a)
37{
38   int m;
39   int k;
40
41   m = 1;
42   k = 0;
43
44   while (m < a) {
45      m = 2*m;
46      k++;
47   }
48
49   if (m == a) 
50      return k;
51   else
52      return -1;
53}
54 
55   
56
57const char *accum[2] = { "", "yy | " };
58
59void lip_to_gmp(int A, int B)
60{
61   int d, na, nb;
62   int i, j, r;
63   int xx, yy;
64   int shamt;
65
66   int iter, na2, nb2;
67
68   d = gcd(A, B);
69   na = B/d;
70   nb = A/d;
71
72   na2 = pow2(na);
73   nb2 = pow2(nb);
74
75   printf("static\n");
76   printf("void lip_to_gmp(const long *x, mp_limb_t *y, long n)\n");
77   printf("{\n");
78   printf("   long r, q, xx;\n");
79   printf("   mp_limb_t yy;\n\n");
80
81   if (na2 != -1) {
82      printf("   r = n & %d;\n", na-1);
83      printf("   q = n >> %d;\n", na2);
84   }
85   else {
86      printf("   r = n % %d;\n", na);
87      printf("   q = n / %d;\n", na);
88   }
89
90   printf("\n");
91
92   printf("   if (q > 0) {\n");
93
94   if (na2 != -1) 
95      printf("      x += (q << %d);\n", na2);
96   else 
97      printf("      x += (q * %d);\n", na);
98
99   if (nb2 != -1) 
100      printf("      y += (q << %d);\n", nb2);
101   else if (pow2(nb+1) != -1)
102      printf("      y += (q << %d) - q;\n", pow2(nb+1));
103   else
104      printf("      y += (q * %d);\n", nb);
105
106   printf("   }\n");
107
108   printf("\n");
109   printf("   if (r > 0) {\n");
110   printf("      yy = 0;\n");
111   printf("\n");
112
113   printf("      switch (r-1) {\n");
114     
115
116   xx = 0;
117   yy = 0;
118
119   for (i = 1; ; i++) {
120      j = (i*A)/B;
121      r = (i*A)%B;
122
123
124      if (xx) {
125         printf("         ");
126         printf("yy = %s (((mp_limb_t)(xx)) << %d);\n", accum[yy], B-r);
127         yy = 1;
128      }
129
130      printf("      ");
131      printf("case %d:\n", na-1-i);
132
133      shamt = A-B+r;
134
135      printf("         ");
136
137      if (shamt >= 0) {
138         printf("y[%d] = ", nb-1-j);
139      }
140      else {
141         printf("yy = ");
142      }
143
144      printf("%s", accum[yy]);
145
146      if (shamt == 0) {
147         printf("x[0];\n");
148         break;
149      }
150      else if (shamt < 0) {
151         printf("(((mp_limb_t)(x[%d])) << %d);\n", na-1-i, -shamt);
152         xx = 0;
153         yy = 1;
154      }
155      else {
156         printf("((xx=x[%d]) >> %d);\n", na-1-i, shamt);
157         xx = 1;
158         yy = 0;
159      }
160   }
161
162   printf("      }\n\n");
163   printf("      n -= r;\n");
164   printf("   }\n\n");
165   printf("   while (n > 0) {\n");
166   printf("      x -= %d;\n", na);
167   printf("      n -= %d;\n", na);
168   printf("      y -= %d;\n", nb);
169   printf("\n");
170
171
172   xx = 0;
173   yy = 0;
174
175   for (i = 0; ; i++) {
176      j = (i*A)/B;
177      r = (i*A)%B;
178
179     
180      if (xx) {
181         printf("      ");
182         printf("yy = %s (((mp_limb_t)(xx)) << %d);\n", accum[yy], B-r);
183         yy = 1;
184      }
185
186      shamt = A-B+r;
187
188      printf("      ");
189
190      if (shamt >= 0) {
191         printf("y[%d] = ", nb-1-j);
192      }
193      else {
194         printf("yy = ");
195      }
196
197      printf("%s", accum[yy]);
198
199      if (shamt == 0) {
200         printf("x[0];\n");
201         break;
202      }
203      else if (shamt < 0) {
204         printf("(((mp_limb_t)(x[%d])) << %d);\n", na-1-i, -shamt);
205         xx = 0;
206         yy = 1;
207      }
208      else {
209         printf("((xx=x[%d]) >> %d);\n", na-1-i, shamt);
210         xx = 1;
211         yy = 0;
212      }
213   }
214
215   printf("   }\n");
216   printf("}\n");
217}
218
219
220void gmp_to_lip(int A, int B, int alt)
221{
222   int d, na, nb;
223   int i, j, r;
224   int shamt;
225
226   int na2, nb2;
227
228   d = gcd(A, B);
229   na = B/d;
230   nb = A/d;
231
232   na2 = pow2(na);
233   nb2 = pow2(nb);
234
235   printf("static\n");
236   if (!alt)
237      printf("void gmp_to_lip(long *x, const mp_limb_t *y, long n)\n");
238   else
239      printf("void gmp_to_lip1(long *x, const mp_limb_t *y, long n)\n");
240   printf("{\n");
241   printf("   long r, q; unsigned long xx;\n");
242   printf("   mp_limb_t yy;\n\n");
243
244   if (na2 != -1) {
245      printf("   r = n & %d;\n", na-1);
246      printf("   q = n >> %d;\n", na2);
247   }
248   else {
249      printf("   r = n % %d;\n", na);
250      printf("   q = n / %d;\n", na);
251   }
252
253   printf("\n");
254
255   printf("   if (q > 0) {\n");
256
257   if (na2 != -1)
258      printf("      x += (q << %d);\n", na2);
259   else
260      printf("      x += (q * %d);\n", na);
261
262   if (nb2 != -1)
263      printf("      y += (q << %d);\n", nb2);
264   else if (pow2(nb+1) != -1)
265      printf("      y += (q << %d) - q;\n", pow2(nb+1));
266   else
267      printf("      y += (q * %d);\n", nb);
268
269   printf("   }\n");
270
271   printf("\n");
272
273
274   printf("   if (r > 0) {\n");
275
276   if (!alt) {
277      if (na - nb == 1)
278         printf("      yy = y[r-1];\n");
279      else if (na2 != -1) 
280         printf("      yy = y[((r*%d + %d) >> %d) - 1];\n", nb, na-1, na2);
281      else
282         printf("      yy = y[((r*%d + %d) / %d) - 1];\n", nb, na-1, na);
283   
284   }
285   else
286      printf("      yy = 0;\n");
287
288   printf("\n");
289
290   printf("      switch (r-1) {\n");
291     
292
293
294   for (i = 1; ; i++) {
295      j = (i*A)/B;
296      r = (i*A)%B;
297
298
299      printf("      ");
300      printf("case %d:\n", na-1-i);
301
302      shamt = A-B+r;
303
304
305      if (shamt > 0) {
306         printf("         ");
307         printf("xx = ((unsigned long)(yy)) << %d;\n", shamt);
308         printf("         ");
309         printf("x[%d] = (xx | ((unsigned long)((yy = y[%d]) >> %d))) & NTL_RADIXM;\n", 
310                na-1-i, nb-2-j, 2*B-r-A);
311      }
312      else if (shamt == 0) {
313         printf("         ");
314         printf("x[0] = ((unsigned long)(yy)) & NTL_RADIXM;\n");
315         break;
316      }
317      else {
318         printf("         ");
319         printf("x[%d] = ((unsigned long)(yy >> %d)) & NTL_RADIXM;\n", na-1-i, -shamt);
320      }
321   }
322
323   printf("      }\n\n");
324   printf("      n -= r;\n");
325   printf("   }\n\n");
326   printf("   while (n > 0) {\n");
327   printf("      x -= %d;\n", na);
328   printf("      n -= %d;\n", na);
329   printf("      y -= %d;\n", nb);
330   printf("\n");
331
332   printf("      yy = y[%d];\n", nb-1);
333
334   for (i = 0; ; i++) {
335      j = (i*A)/B;
336      r = (i*A)%B;
337
338
339      shamt = A-B+r;
340
341      if (shamt > 0) {
342         printf("      ");
343         printf("xx = ((unsigned long)(yy)) << %d;\n", shamt);
344         printf("      ");
345         printf("x[%d] = (xx | ((unsigned long)((yy = y[%d]) >> %d))) & NTL_RADIXM;\n", 
346                na-1-i, nb-2-j, 2*B-r-A);
347      }
348      else if (shamt == 0) {
349         printf("      ");
350         printf("x[0] = ((unsigned long)(yy)) & NTL_RADIXM;\n");
351         break;
352      }
353      else {
354         printf("      ");
355         printf("x[%d] = ((unsigned long)(yy >> %d)) & NTL_RADIXM;\n", na-1-i, -shamt);
356      }
357   }
358
359
360   printf("   }\n");
361   printf("}\n");
362
363}
364
365void rdup(int a, int b)
366{
367   printf("((");
368   if (pow2(a) != -1) {
369      printf("(x << %d)", pow2(a)); 
370   }
371   else if (pow2(a+1) != -1) {
372      printf("((x << %d) - x)", pow2(a+1));
373   }
374   else {
375      printf("(x*%d)", a);
376   }
377   
378   printf(" + %d)", b-1);
379
380   if (pow2(b) != -1) {
381      printf(" >> %d)", pow2(b));
382   }
383   else {
384      printf(" / %d)", b);
385   }
386}
387
388
389void G_TO_L(int A, int B)
390{
391   int d, na, nb;
392
393   d = gcd(A, B);
394   na = B/d;
395   nb = A/d;
396
397   printf("#define G_TO_L(x) ");
398   
399   rdup(na, nb);
400
401   printf("\n");
402}
403
404void L_TO_G(int A, int B)
405{
406   int d, na, nb;
407
408   d = gcd(A, B);
409   na = B/d;
410   nb = A/d;
411
412   printf("#define L_TO_G(x) ");
413   
414   rdup(nb, na);
415
416   printf("\n");
417}
418
419
420void L_TO_G_CHECK(int BPL, int BPI)
421{
422   if (BPL != BPI) {
423      printf("#define L_TO_G_CHECK_LEN\n");
424   }
425     
426}
427
428
429void Error(const char *s)
430{
431   fprintf(stderr, "%s\n", s);
432   abort();
433}
434
435
436int main()
437{
438   mpz_t tt;
439   int A, B, BPL, BPI;
440
441   A = NTL_NBITS_MAX;
442
443   /*
444    * We compute B as the number of bits of a gmp limb.
445    * We require that this quantity correspond to the number of bits
446    * of a long, or possibly a "long long" that is twice as
447    * wide as a long.  These restrictions may not be entirely
448    * necessary, but they are satisfied on all platforms that I know of.
449    */
450
451   if (sizeof(mp_limb_t)==sizeof(long) &&
452            mp_bits_per_limb == NTL_BITS_PER_LONG)
453
454      B = NTL_BITS_PER_LONG;
455
456   else if (sizeof(mp_limb_t) == 2*sizeof(long) &&
457            mp_bits_per_limb == 2*NTL_BITS_PER_LONG)
458
459      B = 2*NTL_BITS_PER_LONG;
460
461   else
462      Error("sorry...this is a funny gmp");
463
464   /*
465    * The following test is a bit redundant, but it doesn't hurt.
466    */
467
468   if (A >= B) Error("sorry...this is a funny gmp");
469
470
471
472   /*
473    * Next, we check if either the _mp_size field of an mpz struct
474    * or the type mp_size_t is narrower than type "long".
475    * This is done to enable some overflow checks.
476    * For simplicity, we require that the sizeof
477    * these types is that of an int or a long, and we also make
478    * the somewhat DIRTY assumption that this sizeof value implies
479    * a corresponding bit count.  Since this assumption is true
480    * on all platforms that I know of, and since this assumption
481    * only affects some overflow tests, it seems reasonable.
482    */
483
484   if (sizeof(tt->_mp_size) == sizeof(int))
485      BPI = NTL_BITS_PER_INT;
486   else if (sizeof(tt->_mp_size) == sizeof(long))
487      BPI = NTL_BITS_PER_LONG;
488   else
489      Error("sorry...this is a funny gmp");
490
491   if (sizeof(mp_size_t) != sizeof(int) && sizeof(mp_size_t) != sizeof(long))
492      Error("sorry...this is a funny gmp");
493
494   if (sizeof(mp_size_t) < sizeof(tt->_mp_size))
495      BPI = NTL_BITS_PER_INT;
496
497
498   BPL = NTL_BITS_PER_LONG;
499
500   fprintf(stderr, "\ngmp looks OK...%d, %d, %d, %d.\n", A, B, BPI, BPL);
501   fprintf(stderr, "generating file lip_gmp_aux.c.\n");
502
503
504   lip_to_gmp(A, B);
505   printf("\n");
506
507   gmp_to_lip(A, B, 0);
508   printf("\n");
509   gmp_to_lip(A, B, 1);
510   printf("\n");
511
512   G_TO_L(A, B);
513   L_TO_G(A, B);
514   L_TO_G_CHECK(BPL, BPI);
515
516   printf("#define HAVE_LIP_GMP_AUX\n");
517
518   return 0;
519}
520
521#else
522
523int main()
524{
525   fprintf(stderr, "NTL_GMP_HACK flag not set.\n");
526   return 0;
527}
528
529#endif
Note: See TracBrowser for help on using the repository browser.