~ubuntu-branches/ubuntu/trusty/cloog/trusty

« back to all changes in this revision

Viewing changes to osl/source/int.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2011-12-15 18:39:17 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20111215183917-uqggmujou8wna9js
Tags: 0.17.0-1
New upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
    /*+-----------------------------------------------------------------**
 
3
     **                       OpenScop Library                          **
 
4
     **-----------------------------------------------------------------**
 
5
     **                             int.c                               **
 
6
     **-----------------------------------------------------------------**
 
7
     **                   First version: 18/07/2011                     **
 
8
     **-----------------------------------------------------------------**
 
9
 
 
10
 
 
11
 *****************************************************************************
 
12
 * OpenScop: Structures and formats for polyhedral tools to talk together    *
 
13
 *****************************************************************************
 
14
 *    ,___,,_,__,,__,,__,,__,,_,__,,_,__,,__,,___,_,__,,_,__,                *
 
15
 *    /   / /  //  //  //  // /   / /  //  //   / /  // /  /|,_,             *
 
16
 *   /   / /  //  //  //  // /   / /  //  //   / /  // /  / / /\             *
 
17
 *  |~~~|~|~~~|~~~|~~~|~~~|~|~~~|~|~~~|~~~|~~~|~|~~~|~|~~~|/_/  \            *
 
18
 *  | G |C| P | = | L | P |=| = |C| = | = | = |=| = |=| C |\  \ /\           *
 
19
 *  | R |l| o | = | e | l |=| = |a| = | = | = |=| = |=| L | \# \ /\          *
 
20
 *  | A |a| l | = | t | u |=| = |n| = | = | = |=| = |=| o | |\# \  \         *
 
21
 *  | P |n| l | = | s | t |=| = |d| = | = | = | |   |=| o | | \# \  \        *
 
22
 *  | H | | y |   | e | o | | = |l|   |   | = | |   | | G | |  \  \  \       *
 
23
 *  | I | |   |   | e |   | |   | |   |   |   | |   | |   | |   \  \  \      *
 
24
 *  | T | |   |   |   |   | |   | |   |   |   | |   | |   | |    \  \  \     *
 
25
 *  | E | |   |   |   |   | |   | |   |   |   | |   | |   | |     \  \  \    *
 
26
 *  | * |*| * | * | * | * |*| * |*| * | * | * |*| * |*| * | /      \* \  \   *
 
27
 *  | O |p| e | n | S | c |o| p |-| L | i | b |r| a |r| y |/        \  \ /   *
 
28
 *  '---'-'---'---'---'---'-'---'-'---'---'---'-'---'-'---'          '--'    *
 
29
 *                                                                           *
 
30
 * Copyright (C) 2008 University Paris-Sud 11 and INRIA                      *
 
31
 *                                                                           *
 
32
 * (3-clause BSD license)                                                    *
 
33
 * Redistribution and use in source  and binary forms, with or without       *
 
34
 * modification, are permitted provided that the following conditions        *
 
35
 * are met:                                                                  *
 
36
 *                                                                           *
 
37
 * 1. Redistributions of source code must retain the above copyright notice, *
 
38
 *    this list of conditions and the following disclaimer.                  *
 
39
 * 2. Redistributions in binary form must reproduce the above copyright      *
 
40
 *    notice, this list of conditions and the following disclaimer in the    *
 
41
 *    documentation and/or other materials provided with the distribution.   *
 
42
 * 3. The name of the author may not be used to endorse or promote products  *
 
43
 *    derived from this software without specific prior written permission.  *
 
44
 *                                                                           *
 
45
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR      *
 
46
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *
 
47
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.   *
 
48
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,          *
 
49
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT  *
 
50
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
 
51
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     *
 
52
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       *
 
53
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF  *
 
54
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.         *
 
55
 *                                                                           *
 
56
 * OpenScop Library, a library to manipulate OpenScop formats and data       *
 
57
 * structures. Written by:                                                   *
 
58
 * Cedric Bastoul     <Cedric.Bastoul@u-psud.fr> and                         *
 
59
 * Louis-Noel Pouchet <Louis-Noel.pouchet@inria.fr>                          *
 
60
 *                                                                           *
 
61
 *****************************************************************************/
 
62
 
 
63
#include <stdlib.h>
 
64
#include <stdio.h>
 
65
#ifdef OSL_GMP_IS_HERE
 
66
# include <gmp.h>
 
67
#endif
 
68
 
 
69
#include <osl/macros.h>
 
70
#include <osl/int.h>
 
71
 
 
72
 
 
73
 
 
74
/*+***************************************************************************
 
75
 *                                Basic Functions                            *
 
76
 *****************************************************************************/
 
77
 
 
78
 
 
79
/**
 
80
 * osl_int_dump_precision function:
 
81
 * this function prints in a human readable fashion the precision
 
82
 * corresponding to the "precision" parameter.
 
83
 * \param[in] file      The file where to print the precision.
 
84
 * \param[in] precision The precision to print.
 
85
 */
 
86
void osl_int_dump_precision(FILE * file, int precision) {
 
87
 
 
88
  switch (precision) {
 
89
    case OSL_PRECISION_SP:
 
90
      fprintf(file, "32 bits");
 
91
      break;
 
92
    case OSL_PRECISION_DP:
 
93
      fprintf(file, "64 bits");
 
94
      break;
 
95
#ifdef OSL_GMP_IS_HERE
 
96
    case OSL_PRECISION_MP:
 
97
      fprintf(file, "GMP");
 
98
      break;
 
99
#endif
 
100
    default:
 
101
      fprintf(file, "unknown precision %d", precision);
 
102
  }
 
103
}
 
104
 
 
105
 
 
106
int osl_int_sizeof(int precision) {
 
107
  switch (precision) {
 
108
    case OSL_PRECISION_SP:
 
109
      return sizeof(long int);
 
110
 
 
111
    case OSL_PRECISION_DP:
 
112
      return sizeof(long long int);
 
113
 
 
114
#ifdef OSL_GMP_IS_HERE
 
115
    case OSL_PRECISION_MP:
 
116
      return sizeof(mpz_t);
 
117
#endif
 
118
 
 
119
    default:
 
120
      OSL_error("unknown precision");
 
121
  }
 
122
}
 
123
 
 
124
 
 
125
void * osl_int_address(int precision, void * base, int offset) {
 
126
  switch (precision) {
 
127
    case OSL_PRECISION_SP:
 
128
      return (long int *)base + offset;
 
129
 
 
130
    case OSL_PRECISION_DP:
 
131
      return (long long int *)base + offset;
 
132
 
 
133
#ifdef OSL_GMP_IS_HERE
 
134
    case OSL_PRECISION_MP:
 
135
      return (mpz_t *)base + offset;
 
136
#endif
 
137
 
 
138
    default:
 
139
      OSL_error("unknown precision");
 
140
  }
 
141
}
 
142
 
 
143
 
 
144
void osl_int_init(int precision, void * value_base, int value_offset) {
 
145
  void * value = osl_int_address(precision, value_base, value_offset);
 
146
 
 
147
  switch (precision) {
 
148
    case OSL_PRECISION_SP:
 
149
      *(long int *)value = 0;
 
150
      break;
 
151
 
 
152
    case OSL_PRECISION_DP:
 
153
      *(long long int *)value = 0;
 
154
      break;
 
155
 
 
156
#ifdef OSL_GMP_IS_HERE
 
157
    case OSL_PRECISION_MP:
 
158
      mpz_init(*(mpz_t *)value);
 
159
      break;
 
160
#endif
 
161
 
 
162
    default:
 
163
      OSL_error("unknown precision");
 
164
  }
 
165
}
 
166
 
 
167
 
 
168
void * osl_int_malloc(int precision) {
 
169
  void * value;
 
170
 
 
171
  switch (precision) {
 
172
    case OSL_PRECISION_SP:
 
173
      value = malloc(sizeof(long int));
 
174
      break;
 
175
 
 
176
    case OSL_PRECISION_DP:
 
177
      value = malloc(sizeof(long long int));
 
178
      *(long long int *)value = 0;
 
179
      break;
 
180
 
 
181
#ifdef OSL_GMP_IS_HERE
 
182
    case OSL_PRECISION_MP:
 
183
      value = malloc(sizeof(mpz_t));
 
184
      break;
 
185
#endif
 
186
 
 
187
    default:
 
188
      OSL_error("unknown precision");
 
189
  }
 
190
 
 
191
  osl_int_init(precision, value, 0);
 
192
  return value;
 
193
}
 
194
 
 
195
 
 
196
/**
 
197
 * val1_base[val1_offset] = val2_base[val2_offset];
 
198
 */
 
199
void osl_int_assign(int precision,
 
200
                    void * val1_base, int val1_offset,
 
201
                    void * val2_base, int val2_offset) {
 
202
  void * val1 = osl_int_address(precision, val1_base, val1_offset);
 
203
  void * val2 = osl_int_address(precision, val2_base, val2_offset);
 
204
 
 
205
  switch (precision) {
 
206
    case OSL_PRECISION_SP:
 
207
      *(long int *)val1 = *(long int *)val2;
 
208
      break;
 
209
 
 
210
    case OSL_PRECISION_DP:
 
211
      *(long long int *)val1 = *(long long int *)val2;
 
212
      break;
 
213
 
 
214
#ifdef OSL_GMP_IS_HERE
 
215
    case OSL_PRECISION_MP:
 
216
      mpz_set(*(mpz_t *)val1, *(mpz_t *)val2);
 
217
      break;
 
218
#endif
 
219
 
 
220
    default:
 
221
      OSL_error("unknown precision");
 
222
  }
 
223
}
 
224
 
 
225
 
 
226
/**
 
227
 * value_base[value_offset] = i;
 
228
 */
 
229
void osl_int_set_si(int precision, void * value_base, int value_offset,
 
230
                    int i) {
 
231
  void * value = osl_int_address(precision, value_base, value_offset);
 
232
 
 
233
  switch (precision) {
 
234
    case OSL_PRECISION_SP:
 
235
      *(long int *)value = (long int)i;
 
236
      break;
 
237
 
 
238
    case OSL_PRECISION_DP:
 
239
      *(long long int *)value = (long long int)i;
 
240
      break;
 
241
 
 
242
#ifdef OSL_GMP_IS_HERE
 
243
    case OSL_PRECISION_MP:
 
244
      mpz_set_si(*(mpz_t *)value, i);
 
245
      break;
 
246
#endif
 
247
 
 
248
    default:
 
249
      OSL_error("unknown precision");
 
250
  }
 
251
}
 
252
 
 
253
 
 
254
/**
 
255
 * return value_base[value_offset];
 
256
 */
 
257
int osl_int_get_si(int precision, void * value_base, int value_offset) {
 
258
  void * value = osl_int_address(precision, value_base, value_offset);
 
259
 
 
260
  switch (precision) {
 
261
    case OSL_PRECISION_SP:
 
262
      return *(int *)value;
 
263
 
 
264
    case OSL_PRECISION_DP:
 
265
      return *(int *)value;
 
266
 
 
267
#ifdef OSL_GMP_IS_HERE
 
268
    case OSL_PRECISION_MP:
 
269
      return mpz_get_si(*(mpz_t *)value);
 
270
#endif
 
271
 
 
272
    default:
 
273
      OSL_error("unknown precision");
 
274
  }
 
275
}
 
276
 
 
277
 
 
278
/**
 
279
 * value_base[value_offset] = i; // including initialization for GMP
 
280
 */
 
281
void osl_int_init_set_si(int precision,
 
282
                         void * value_base, int value_offset, int i) {
 
283
  void * value = osl_int_address(precision, value_base, value_offset);
 
284
 
 
285
  switch (precision) {
 
286
    case OSL_PRECISION_SP:
 
287
      *(long int *)value = (long int)i;
 
288
      break;
 
289
 
 
290
    case OSL_PRECISION_DP:
 
291
      *(long long int *)value = (long long int)i;
 
292
      break;
 
293
 
 
294
#ifdef OSL_GMP_IS_HERE
 
295
    case OSL_PRECISION_MP:
 
296
      mpz_init_set_si(*(mpz_t *)value, i);
 
297
      break;
 
298
#endif
 
299
 
 
300
    default:
 
301
      OSL_error("unknown precision");
 
302
  }
 
303
}
 
304
 
 
305
 
 
306
/**
 
307
 * value_base[value_offset] = 0; // Including cleaning for GMP
 
308
 */
 
309
void osl_int_clear(int precision, void * value_base, int value_offset) {
 
310
  void * value = osl_int_address(precision, value_base, value_offset);
 
311
  
 
312
  switch (precision) {
 
313
    case OSL_PRECISION_SP:
 
314
      *(long int *)value = 0;
 
315
      break;
 
316
 
 
317
    case OSL_PRECISION_DP:
 
318
      *(long long int *)value = 0;
 
319
      break;
 
320
 
 
321
#ifdef OSL_GMP_IS_HERE
 
322
    case OSL_PRECISION_MP:
 
323
      mpz_clear(*(mpz_t *)value);
 
324
      break;
 
325
#endif
 
326
 
 
327
    default:
 
328
      OSL_error("unknown precision");
 
329
  }
 
330
}
 
331
 
 
332
 
 
333
void osl_int_free(int precision, void * value_base, int value_offset) {
 
334
  void * value = osl_int_address(precision, value_base, value_offset);
 
335
 
 
336
  osl_int_clear(precision, value_base, value_offset);
 
337
  free(value);
 
338
}
 
339
 
 
340
 
 
341
/**
 
342
 * osl_int_print function:
 
343
 * this function displays an integer value into a file (file, possibly stdout).
 
344
 * \param file         The file where the integer has to be printed.
 
345
 * \param precision    The precision of the integer.
 
346
 * \param value_base   Address of the base integer value.
 
347
 * \param value_offset Offset in number of values from the base integer value.
 
348
 */
 
349
void osl_int_print(FILE * file, int precision,
 
350
                   void * value_base, int value_offset) {
 
351
  char string[OSL_MAX_STRING];
 
352
  
 
353
  osl_int_sprint(string, precision, value_base, value_offset);
 
354
  fprintf(file, "%s", string);
 
355
}
 
356
 
 
357
 
 
358
/**
 
359
 * osl_int_sprint function:
 
360
 * this function prints an integer value into a string, it uses the
 
361
 * OpenScop Library formats OSL_FMT_* to format the printing.
 
362
 * \param string       The string where the integer has to be printed.
 
363
 * \param precision    The precision of the integer.
 
364
 * \param value_base   Address of the base integer value.
 
365
 * \param value_offset Offset in number of values from the base integer value.
 
366
 */
 
367
void osl_int_sprint(char * string, int precision,
 
368
                    void * value_base, int value_offset) {
 
369
  void * value = osl_int_address(precision, value_base, value_offset);
 
370
            
 
371
  switch (precision) {
 
372
    case OSL_PRECISION_SP:
 
373
      sprintf(string, OSL_FMT_SP, *(long int *)value);
 
374
      break;
 
375
 
 
376
    case OSL_PRECISION_DP:
 
377
      sprintf(string, OSL_FMT_DP, *(long long int *)value);
 
378
      break;
 
379
 
 
380
#ifdef OSL_GMP_IS_HERE
 
381
    case OSL_PRECISION_MP: {
 
382
      char * str;
 
383
      str = mpz_get_str(0, 10, *(mpz_t *)value); //TODO: 10 -> #define
 
384
      sprintf(string, OSL_FMT_MP, str);
 
385
      free(str);
 
386
      break;
 
387
    }
 
388
#endif
 
389
 
 
390
    default:
 
391
      OSL_error("unknown precision");
 
392
  }
 
393
}
 
394
 
 
395
 
 
396
/**
 
397
 * osl_int_sprint_txt function:
 
398
 * this function is similar to osl_int_sprintf but it prints the value
 
399
 * using OSL_TMT_TXT_* formats.
 
400
 * \see osl_int_sprintf
 
401
 */
 
402
void osl_int_sprint_txt(char * string, int precision,
 
403
                        void * value_base, int value_offset) {
 
404
  void * value = osl_int_address(precision, value_base, value_offset);
 
405
            
 
406
  switch (precision) {
 
407
    case OSL_PRECISION_SP:
 
408
      sprintf(string, OSL_FMT_TXT_SP, *(long int *)value);
 
409
      break;
 
410
 
 
411
    case OSL_PRECISION_DP:
 
412
      sprintf(string, OSL_FMT_TXT_DP, *(long long int *)value);
 
413
      break;
 
414
 
 
415
#ifdef OSL_GMP_IS_HERE
 
416
    case OSL_PRECISION_MP: {
 
417
      char * str;
 
418
      str = mpz_get_str(0, 10, *(mpz_t *)value); //TODO: 10 -> #define
 
419
      sprintf(string, OSL_FMT_TXT_MP, str);
 
420
      free(str);
 
421
      break;
 
422
    }
 
423
#endif
 
424
 
 
425
    default:
 
426
      OSL_error("unknown precision");
 
427
  }
 
428
}
 
429
 
 
430
 
 
431
void osl_int_sread(char ** string, int precision,
 
432
                   void * value_base, int value_offset) {
 
433
  void * value = osl_int_address(precision, value_base, value_offset);
 
434
  int nb_read = 0;
 
435
 
 
436
  switch (precision) {
 
437
    case OSL_PRECISION_SP:
 
438
      nb_read = sscanf(*string, OSL_FMT_TXT_SP, (long int *)value);
 
439
      if (nb_read == 0)
 
440
        OSL_error("failed to read an integer");
 
441
      break;
 
442
 
 
443
    case OSL_PRECISION_DP:
 
444
      nb_read = sscanf(*string, OSL_FMT_TXT_DP, (long long int *)value);
 
445
      if (nb_read == 0)
 
446
        OSL_error("failed to read an integer");
 
447
      break;
 
448
 
 
449
#ifdef OSL_GMP_IS_HERE
 
450
    case OSL_PRECISION_MP: {
 
451
      long long int tmp;
 
452
      nb_read = sscanf(*string, OSL_FMT_TXT_DP, &tmp);
 
453
      if (nb_read == 0)
 
454
        OSL_error("failed to read an integer");
 
455
      mpz_set_si(*(mpz_t *)value, tmp);
 
456
      break;
 
457
    }
 
458
#endif
 
459
 
 
460
    default:
 
461
      OSL_error("unknown precision");
 
462
  }
 
463
 
 
464
  // Update the position in the input string.
 
465
  *string = *string + nb_read;
 
466
}
 
467
 
 
468
 
 
469
/*+***************************************************************************
 
470
 *                            Arithmetic Operations                          *
 
471
 *****************************************************************************/
 
472
 
 
473
 
 
474
/**
 
475
 * result_base[result_offset] = value_base[value_offset] + 1;
 
476
 */
 
477
void osl_int_increment(int precision,
 
478
                       void * result_base, int result_offset,
 
479
                       void * value_base,  int value_offset) {
 
480
  void * result = osl_int_address(precision, result_base, result_offset);
 
481
  void * value  = osl_int_address(precision, value_base, value_offset);
 
482
 
 
483
  switch (precision) {
 
484
    case OSL_PRECISION_SP:
 
485
      *(long int *)result = *(long int *)value + (long int)1;
 
486
      break;
 
487
 
 
488
    case OSL_PRECISION_DP:
 
489
      *(long long int *)result = *(long long int *)value + (long long int)1;
 
490
      break;
 
491
 
 
492
#ifdef OSL_GMP_IS_HERE
 
493
    case OSL_PRECISION_MP:
 
494
      mpz_add_ui(*(mpz_t *)result, *(mpz_t *)value, 1);
 
495
      break;
 
496
#endif
 
497
 
 
498
    default:
 
499
      OSL_error("unknown precision");
 
500
  }
 
501
}
 
502
 
 
503
 
 
504
/**
 
505
 * result_base[result_offset] = value_base[value_offset] - 1;
 
506
 */
 
507
void osl_int_decrement(int precision,
 
508
                       void * result_base, int result_offset,
 
509
                       void * value_base,  int value_offset) {
 
510
  void * result = osl_int_address(precision, result_base, result_offset);
 
511
  void * value  = osl_int_address(precision, value_base, value_offset);
 
512
 
 
513
  switch (precision) {
 
514
    case OSL_PRECISION_SP:
 
515
      *(long int *)result = *(long int *)value - (long int)1;
 
516
      break;
 
517
 
 
518
    case OSL_PRECISION_DP:
 
519
      *(long long int *)result = *(long long int *)value - (long long int)1;
 
520
      break;
 
521
 
 
522
#ifdef OSL_GMP_IS_HERE
 
523
    case OSL_PRECISION_MP: {
 
524
      mpz_t one;
 
525
      mpz_init_set_si(one, 1);
 
526
      mpz_sub(*(mpz_t *)result, *(mpz_t *)value, one);
 
527
      mpz_clear(one);
 
528
      break;
 
529
    }
 
530
#endif
 
531
 
 
532
    default:
 
533
      OSL_error("unknown precision");
 
534
  }
 
535
}
 
536
 
 
537
 
 
538
/**
 
539
 * result_base[result_offset] = val1_base[val1_offset]+val2_base[val2_offset];
 
540
 */
 
541
void osl_int_add(int precision,
 
542
                 void * result_base, int result_offset,
 
543
                 void * val1_base,   int val1_offset,
 
544
                 void * val2_base,   int val2_offset) {
 
545
  void * result = osl_int_address(precision, result_base, result_offset);
 
546
  void * val1   = osl_int_address(precision, val1_base, val1_offset);
 
547
  void * val2   = osl_int_address(precision, val2_base, val2_offset);
 
548
 
 
549
  switch (precision) {
 
550
    case OSL_PRECISION_SP:
 
551
      *(long int *)result = *(long int *)val1 + *(long int *)val2;
 
552
      break;
 
553
 
 
554
    case OSL_PRECISION_DP:
 
555
      *(long long int *)result = *(long long int *)val1 +
 
556
                                 *(long long int *)val2;
 
557
      break;
 
558
 
 
559
#ifdef OSL_GMP_IS_HERE
 
560
    case OSL_PRECISION_MP:
 
561
      mpz_add(*(mpz_t *)result, *(mpz_t *)val1, *(mpz_t *)val2);
 
562
      break;
 
563
#endif
 
564
 
 
565
    default:
 
566
      OSL_error("unknown precision");
 
567
  }
 
568
}
 
569
 
 
570
 
 
571
/**
 
572
 * result_base[result_offset] = value_base[value_offset] + i;
 
573
 */
 
574
void osl_int_add_si(int precision,
 
575
                    void * result_base, int result_offset,
 
576
                    void * value_base,  int value_offset, int i) {
 
577
  void * result = osl_int_address(precision, result_base, result_offset);
 
578
  void * value  = osl_int_address(precision, value_base, value_offset);
 
579
 
 
580
  switch (precision) {
 
581
    case OSL_PRECISION_SP:
 
582
      *(long int *)result = *(long int *)value + (long int)i;
 
583
      break;
 
584
 
 
585
    case OSL_PRECISION_DP:
 
586
      *(long long int *)result = *(long long int *)value + (long long int)i;
 
587
      break;
 
588
 
 
589
#ifdef OSL_GMP_IS_HERE
 
590
    case OSL_PRECISION_MP: {
 
591
      mpz_t si;
 
592
      mpz_init_set_si(si, i);
 
593
      mpz_add(*(mpz_t *)result, *(mpz_t *)value, si);
 
594
      mpz_clear(si);
 
595
      break;
 
596
    }
 
597
#endif
 
598
 
 
599
    default:
 
600
      OSL_error("unknown precision");
 
601
  }
 
602
}
 
603
 
 
604
 
 
605
/**
 
606
 * result_base[result_offset] = val1_base[val1_offset]*val2_base[val2_offset];
 
607
 */
 
608
void osl_int_mul(int precision,
 
609
                 void * result_base, int result_offset,
 
610
                 void * val1_base,   int val1_offset,
 
611
                 void * val2_base,   int val2_offset) {
 
612
  void * result = osl_int_address(precision, result_base, result_offset);
 
613
  void * val1   = osl_int_address(precision, val1_base, val1_offset);
 
614
  void * val2   = osl_int_address(precision, val2_base, val2_offset);
 
615
 
 
616
  switch (precision) {
 
617
    case OSL_PRECISION_SP:
 
618
      *(long int *)result = *(long int *)val1 * *(long int *)val2;
 
619
      break;
 
620
 
 
621
    case OSL_PRECISION_DP:
 
622
      *(long long int *)result = *(long long int *)val1 *
 
623
                                 *(long long int *)val2;
 
624
      break;
 
625
 
 
626
#ifdef OSL_GMP_IS_HERE
 
627
    case OSL_PRECISION_MP:
 
628
      mpz_mul(*(mpz_t *)result, *(mpz_t *)val1, *(mpz_t *)val2);
 
629
      break;
 
630
#endif
 
631
 
 
632
    default:
 
633
      OSL_error("unknown precision");
 
634
  }
 
635
}
 
636
 
 
637
 
 
638
/**
 
639
 * result_base[result_offset] = value_base[value_offset] * i;
 
640
 */
 
641
void osl_int_mul_si(int precision,
 
642
                    void * result_base, int result_offset,
 
643
                    void * value_base,  int value_offset, int i) {
 
644
  void * result = osl_int_address(precision, result_base, result_offset);
 
645
  void * value  = osl_int_address(precision, value_base, value_offset);
 
646
 
 
647
  switch (precision) {
 
648
    case OSL_PRECISION_SP:
 
649
      *(long int *)result = *(long int *)value * (long int)i;
 
650
      break;
 
651
 
 
652
    case OSL_PRECISION_DP:
 
653
      *(long long int *)result = *(long long int *)value * (long long int)i;
 
654
      break;
 
655
 
 
656
#ifdef OSL_GMP_IS_HERE
 
657
    case OSL_PRECISION_MP:
 
658
      mpz_mul_si(*(mpz_t *)result, *(mpz_t *)value, i);
 
659
      break;
 
660
#endif
 
661
 
 
662
    default:
 
663
      OSL_error("unknown precision");
 
664
  }
 
665
}
 
666
 
 
667
 
 
668
/**
 
669
 * result_base[result_offset] = val1_base[val1_offset]-val2_base[val2_offset];
 
670
 */
 
671
void osl_int_sub(int precision,
 
672
                 void * result_base, int result_offset,
 
673
                 void * val1_base,   int val1_offset,
 
674
                 void * val2_base,   int val2_offset) {
 
675
  void * result = osl_int_address(precision, result_base, result_offset);
 
676
  void * val1   = osl_int_address(precision, val1_base, val1_offset);
 
677
  void * val2   = osl_int_address(precision, val2_base, val2_offset);
 
678
 
 
679
  switch (precision) {
 
680
    case OSL_PRECISION_SP:
 
681
      *(long int *)result = *(long int *)val1 - *(long int *)val2;
 
682
      break;
 
683
 
 
684
    case OSL_PRECISION_DP:
 
685
      *(long long int *)result = *(long long int *)val1 -
 
686
                                 *(long long int *)val2;
 
687
      break;
 
688
 
 
689
#ifdef OSL_GMP_IS_HERE
 
690
    case OSL_PRECISION_MP:
 
691
      mpz_sub(*(mpz_t *)result, *(mpz_t *)val1, *(mpz_t *)val2);
 
692
      break;
 
693
#endif
 
694
 
 
695
    default:
 
696
      OSL_error("unknown precision");
 
697
  }
 
698
}
 
699
 
 
700
 
 
701
/**
 
702
 * result_base[result_offset] = -value_base[value_offset];
 
703
 */
 
704
void osl_int_oppose(int precision,
 
705
                    void * result_base, int result_offset,
 
706
                    void * value_base,  int value_offset) {
 
707
  void * result = osl_int_address(precision, result_base, result_offset);
 
708
  void * value  = osl_int_address(precision, value_base, value_offset);
 
709
 
 
710
  switch (precision) {
 
711
    case OSL_PRECISION_SP:
 
712
      *(long int *)result = -*(long int *)value;
 
713
      break;
 
714
 
 
715
    case OSL_PRECISION_DP:
 
716
      *(long long int *)result = -*(long long int *)value;
 
717
      break;
 
718
 
 
719
#ifdef OSL_GMP_IS_HERE
 
720
    case OSL_PRECISION_MP:
 
721
      mpz_neg(*(mpz_t *)result, *(mpz_t *)value);
 
722
      break;
 
723
#endif
 
724
 
 
725
    default:
 
726
      OSL_error("unknown precision");
 
727
  }
 
728
}
 
729
 
 
730
 
 
731
/*+***************************************************************************
 
732
 *                            Conditional Operations                         *
 
733
 *****************************************************************************/
 
734
 
 
735
 
 
736
/**
 
737
 * (val1_base[val1_offset] == val2_base[val2_offset])
 
738
 */
 
739
int osl_int_eq(int precision,
 
740
               void * val1_base, int val1_offset,
 
741
               void * val2_base, int val2_offset) {
 
742
  void * val1 = osl_int_address(precision, val1_base, val1_offset);
 
743
  void * val2 = osl_int_address(precision, val2_base, val2_offset);
 
744
 
 
745
  switch (precision) {
 
746
    case OSL_PRECISION_SP:
 
747
      return (*(long int *)val1 == *(long int *)val2);
 
748
 
 
749
    case OSL_PRECISION_DP:
 
750
      return (*(long long int *)val1 == *(long long int *)val2);
 
751
 
 
752
#ifdef OSL_GMP_IS_HERE
 
753
    case OSL_PRECISION_MP:
 
754
      return (mpz_cmp(*(mpz_t *)val1, *(mpz_t *)val2) == 0);
 
755
#endif
 
756
 
 
757
    default:
 
758
      OSL_error("unknown precision");
 
759
  }
 
760
}
 
761
 
 
762
 
 
763
/**
 
764
 * (val1_base[val1_offset] != val2_base[val2_offset])
 
765
 */
 
766
int osl_int_ne(int precision,
 
767
               void * val1_base, int val1_offset,
 
768
               void * val2_base, int val2_offset) {
 
769
  return !osl_int_eq(precision,
 
770
                          val1_base, val1_offset,
 
771
                          val2_base, val2_offset);
 
772
}
 
773
 
 
774
 
 
775
/**
 
776
 * (value_base[value_offset] > 0)
 
777
 */
 
778
int osl_int_pos(int precision, void * value_base, int value_offset) {
 
779
  void * value = osl_int_address(precision, value_base, value_offset);
 
780
 
 
781
  switch (precision) {
 
782
    case OSL_PRECISION_SP:
 
783
      return (*(long int *)value > 0);
 
784
 
 
785
    case OSL_PRECISION_DP:
 
786
      return (*(long long int *)value > 0);
 
787
 
 
788
#ifdef OSL_GMP_IS_HERE
 
789
    case OSL_PRECISION_MP:
 
790
      return (mpz_sgn(*(mpz_t *)value) > 0);
 
791
#endif
 
792
 
 
793
    default:
 
794
      OSL_error("unknown precision");
 
795
  }
 
796
}
 
797
 
 
798
 
 
799
/**
 
800
 * (value_base[value_offset] < 0)
 
801
 */
 
802
int osl_int_neg(int precision, void * value_base, int value_offset) {
 
803
  void * value = osl_int_address(precision, value_base, value_offset);
 
804
 
 
805
  switch (precision) {
 
806
    case OSL_PRECISION_SP:
 
807
      return (*(long int *)value < 0);
 
808
 
 
809
    case OSL_PRECISION_DP:
 
810
      return (*(long long int *)value < 0);
 
811
 
 
812
#ifdef OSL_GMP_IS_HERE
 
813
    case OSL_PRECISION_MP:
 
814
      return (mpz_sgn(*(mpz_t *)value) < 0);
 
815
#endif
 
816
 
 
817
    default:
 
818
      OSL_error("unknown precision");
 
819
  }
 
820
}
 
821
 
 
822
 
 
823
/**
 
824
 * (value_base[value_offset] == 0)
 
825
 */
 
826
int osl_int_zero(int precision, void * value_base, int value_offset) {
 
827
  void * value = osl_int_address(precision, value_base, value_offset);
 
828
 
 
829
  switch (precision) {
 
830
    case OSL_PRECISION_SP:
 
831
      return (*(long int *)value == 0);
 
832
 
 
833
    case OSL_PRECISION_DP:
 
834
      return (*(long long int *)value == 0);
 
835
 
 
836
#ifdef OSL_GMP_IS_HERE
 
837
    case OSL_PRECISION_MP:
 
838
      return (mpz_sgn(*(mpz_t *)value) == 0);
 
839
#endif
 
840
 
 
841
    default:
 
842
      OSL_error("unknown precision");
 
843
  }
 
844
}
 
845
 
 
846
 
 
847
/**
 
848
 * (value_base[value_offset] == 1)
 
849
 */
 
850
int osl_int_one(int precision, void * value_base, int value_offset) {
 
851
  void * value = osl_int_address(precision, value_base, value_offset);
 
852
 
 
853
  switch (precision) {
 
854
    case OSL_PRECISION_SP:
 
855
      return (*(long int *)value == (long int)1);
 
856
 
 
857
    case OSL_PRECISION_DP:
 
858
      return (*(long long int *)value == (long long int)1);
 
859
 
 
860
#ifdef OSL_GMP_IS_HERE
 
861
    case OSL_PRECISION_MP:
 
862
      return (mpz_cmp_si(*(mpz_t *)value, 1) == 0);
 
863
#endif
 
864
 
 
865
    default:
 
866
      OSL_error("unknown precision");
 
867
  }
 
868
}
 
869
 
 
870
 
 
871
/**
 
872
 * (value_base[value_offset] == -1)
 
873
 */
 
874
int osl_int_mone(int precision, void * value_base, int value_offset) {
 
875
  void * value = osl_int_address(precision, value_base, value_offset);
 
876
 
 
877
  switch (precision) {
 
878
    case OSL_PRECISION_SP:
 
879
      return (*(long int *)value == (long int)-1);
 
880
 
 
881
    case OSL_PRECISION_DP:
 
882
      return (*(long long int *)value == (long long int)-1);
 
883
 
 
884
#ifdef OSL_GMP_IS_HERE
 
885
    case OSL_PRECISION_MP:
 
886
      return (mpz_cmp_si(*(mpz_t *)value, -1) == 0);
 
887
#endif
 
888
 
 
889
    default:
 
890
      OSL_error("unknown precision");
 
891
  }
 
892
}
 
893
 
 
894
 
 
895
/**
 
896
 * ((val1_base[val1_offset] % val2_base[val2_offset]) == 0)
 
897
 */
 
898
int osl_int_divisible(int precision,
 
899
                      void * val1_base, int val1_offset,
 
900
                      void * val2_base, int val2_offset) {
 
901
  void * val1 = osl_int_address(precision, val1_base, val1_offset);
 
902
  void * val2 = osl_int_address(precision, val2_base, val2_offset);
 
903
 
 
904
  switch (precision) {
 
905
    case OSL_PRECISION_SP:
 
906
      return ((*(long int *)val1 % *(long int *)val2) == 0);
 
907
 
 
908
    case OSL_PRECISION_DP:
 
909
      return ((*(long long int *)val1 % *(long long int *)val2) == 0);
 
910
 
 
911
#ifdef OSL_GMP_IS_HERE
 
912
    case OSL_PRECISION_MP:
 
913
      return mpz_divisible_p(*(mpz_t *)val1, *(mpz_t *)val2);
 
914
#endif
 
915
 
 
916
    default:
 
917
      OSL_error("unknown precision");
 
918
  }
 
919
}