2
/*+-----------------------------------------------------------------**
4
**-----------------------------------------------------------------**
6
**-----------------------------------------------------------------**
7
** First version: 18/07/2011 **
8
**-----------------------------------------------------------------**
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
* '---'-'---'---'---'---'-'---'-'---'---'---'-'---'-'---' '--' *
30
* Copyright (C) 2008 University Paris-Sud 11 and INRIA *
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 *
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. *
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. *
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> *
61
*****************************************************************************/
65
#ifdef OSL_GMP_IS_HERE
69
#include <osl/macros.h>
74
/*+***************************************************************************
76
*****************************************************************************/
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.
86
void osl_int_dump_precision(FILE * file, int precision) {
89
case OSL_PRECISION_SP:
90
fprintf(file, "32 bits");
92
case OSL_PRECISION_DP:
93
fprintf(file, "64 bits");
95
#ifdef OSL_GMP_IS_HERE
96
case OSL_PRECISION_MP:
101
fprintf(file, "unknown precision %d", precision);
106
int osl_int_sizeof(int precision) {
108
case OSL_PRECISION_SP:
109
return sizeof(long int);
111
case OSL_PRECISION_DP:
112
return sizeof(long long int);
114
#ifdef OSL_GMP_IS_HERE
115
case OSL_PRECISION_MP:
116
return sizeof(mpz_t);
120
OSL_error("unknown precision");
125
void * osl_int_address(int precision, void * base, int offset) {
127
case OSL_PRECISION_SP:
128
return (long int *)base + offset;
130
case OSL_PRECISION_DP:
131
return (long long int *)base + offset;
133
#ifdef OSL_GMP_IS_HERE
134
case OSL_PRECISION_MP:
135
return (mpz_t *)base + offset;
139
OSL_error("unknown precision");
144
void osl_int_init(int precision, void * value_base, int value_offset) {
145
void * value = osl_int_address(precision, value_base, value_offset);
148
case OSL_PRECISION_SP:
149
*(long int *)value = 0;
152
case OSL_PRECISION_DP:
153
*(long long int *)value = 0;
156
#ifdef OSL_GMP_IS_HERE
157
case OSL_PRECISION_MP:
158
mpz_init(*(mpz_t *)value);
163
OSL_error("unknown precision");
168
void * osl_int_malloc(int precision) {
172
case OSL_PRECISION_SP:
173
value = malloc(sizeof(long int));
176
case OSL_PRECISION_DP:
177
value = malloc(sizeof(long long int));
178
*(long long int *)value = 0;
181
#ifdef OSL_GMP_IS_HERE
182
case OSL_PRECISION_MP:
183
value = malloc(sizeof(mpz_t));
188
OSL_error("unknown precision");
191
osl_int_init(precision, value, 0);
197
* val1_base[val1_offset] = val2_base[val2_offset];
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);
206
case OSL_PRECISION_SP:
207
*(long int *)val1 = *(long int *)val2;
210
case OSL_PRECISION_DP:
211
*(long long int *)val1 = *(long long int *)val2;
214
#ifdef OSL_GMP_IS_HERE
215
case OSL_PRECISION_MP:
216
mpz_set(*(mpz_t *)val1, *(mpz_t *)val2);
221
OSL_error("unknown precision");
227
* value_base[value_offset] = i;
229
void osl_int_set_si(int precision, void * value_base, int value_offset,
231
void * value = osl_int_address(precision, value_base, value_offset);
234
case OSL_PRECISION_SP:
235
*(long int *)value = (long int)i;
238
case OSL_PRECISION_DP:
239
*(long long int *)value = (long long int)i;
242
#ifdef OSL_GMP_IS_HERE
243
case OSL_PRECISION_MP:
244
mpz_set_si(*(mpz_t *)value, i);
249
OSL_error("unknown precision");
255
* return value_base[value_offset];
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);
261
case OSL_PRECISION_SP:
262
return *(int *)value;
264
case OSL_PRECISION_DP:
265
return *(int *)value;
267
#ifdef OSL_GMP_IS_HERE
268
case OSL_PRECISION_MP:
269
return mpz_get_si(*(mpz_t *)value);
273
OSL_error("unknown precision");
279
* value_base[value_offset] = i; // including initialization for GMP
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);
286
case OSL_PRECISION_SP:
287
*(long int *)value = (long int)i;
290
case OSL_PRECISION_DP:
291
*(long long int *)value = (long long int)i;
294
#ifdef OSL_GMP_IS_HERE
295
case OSL_PRECISION_MP:
296
mpz_init_set_si(*(mpz_t *)value, i);
301
OSL_error("unknown precision");
307
* value_base[value_offset] = 0; // Including cleaning for GMP
309
void osl_int_clear(int precision, void * value_base, int value_offset) {
310
void * value = osl_int_address(precision, value_base, value_offset);
313
case OSL_PRECISION_SP:
314
*(long int *)value = 0;
317
case OSL_PRECISION_DP:
318
*(long long int *)value = 0;
321
#ifdef OSL_GMP_IS_HERE
322
case OSL_PRECISION_MP:
323
mpz_clear(*(mpz_t *)value);
328
OSL_error("unknown precision");
333
void osl_int_free(int precision, void * value_base, int value_offset) {
334
void * value = osl_int_address(precision, value_base, value_offset);
336
osl_int_clear(precision, value_base, value_offset);
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.
349
void osl_int_print(FILE * file, int precision,
350
void * value_base, int value_offset) {
351
char string[OSL_MAX_STRING];
353
osl_int_sprint(string, precision, value_base, value_offset);
354
fprintf(file, "%s", string);
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.
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);
372
case OSL_PRECISION_SP:
373
sprintf(string, OSL_FMT_SP, *(long int *)value);
376
case OSL_PRECISION_DP:
377
sprintf(string, OSL_FMT_DP, *(long long int *)value);
380
#ifdef OSL_GMP_IS_HERE
381
case OSL_PRECISION_MP: {
383
str = mpz_get_str(0, 10, *(mpz_t *)value); //TODO: 10 -> #define
384
sprintf(string, OSL_FMT_MP, str);
391
OSL_error("unknown precision");
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
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);
407
case OSL_PRECISION_SP:
408
sprintf(string, OSL_FMT_TXT_SP, *(long int *)value);
411
case OSL_PRECISION_DP:
412
sprintf(string, OSL_FMT_TXT_DP, *(long long int *)value);
415
#ifdef OSL_GMP_IS_HERE
416
case OSL_PRECISION_MP: {
418
str = mpz_get_str(0, 10, *(mpz_t *)value); //TODO: 10 -> #define
419
sprintf(string, OSL_FMT_TXT_MP, str);
426
OSL_error("unknown precision");
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);
437
case OSL_PRECISION_SP:
438
nb_read = sscanf(*string, OSL_FMT_TXT_SP, (long int *)value);
440
OSL_error("failed to read an integer");
443
case OSL_PRECISION_DP:
444
nb_read = sscanf(*string, OSL_FMT_TXT_DP, (long long int *)value);
446
OSL_error("failed to read an integer");
449
#ifdef OSL_GMP_IS_HERE
450
case OSL_PRECISION_MP: {
452
nb_read = sscanf(*string, OSL_FMT_TXT_DP, &tmp);
454
OSL_error("failed to read an integer");
455
mpz_set_si(*(mpz_t *)value, tmp);
461
OSL_error("unknown precision");
464
// Update the position in the input string.
465
*string = *string + nb_read;
469
/*+***************************************************************************
470
* Arithmetic Operations *
471
*****************************************************************************/
475
* result_base[result_offset] = value_base[value_offset] + 1;
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);
484
case OSL_PRECISION_SP:
485
*(long int *)result = *(long int *)value + (long int)1;
488
case OSL_PRECISION_DP:
489
*(long long int *)result = *(long long int *)value + (long long int)1;
492
#ifdef OSL_GMP_IS_HERE
493
case OSL_PRECISION_MP:
494
mpz_add_ui(*(mpz_t *)result, *(mpz_t *)value, 1);
499
OSL_error("unknown precision");
505
* result_base[result_offset] = value_base[value_offset] - 1;
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);
514
case OSL_PRECISION_SP:
515
*(long int *)result = *(long int *)value - (long int)1;
518
case OSL_PRECISION_DP:
519
*(long long int *)result = *(long long int *)value - (long long int)1;
522
#ifdef OSL_GMP_IS_HERE
523
case OSL_PRECISION_MP: {
525
mpz_init_set_si(one, 1);
526
mpz_sub(*(mpz_t *)result, *(mpz_t *)value, one);
533
OSL_error("unknown precision");
539
* result_base[result_offset] = val1_base[val1_offset]+val2_base[val2_offset];
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);
550
case OSL_PRECISION_SP:
551
*(long int *)result = *(long int *)val1 + *(long int *)val2;
554
case OSL_PRECISION_DP:
555
*(long long int *)result = *(long long int *)val1 +
556
*(long long int *)val2;
559
#ifdef OSL_GMP_IS_HERE
560
case OSL_PRECISION_MP:
561
mpz_add(*(mpz_t *)result, *(mpz_t *)val1, *(mpz_t *)val2);
566
OSL_error("unknown precision");
572
* result_base[result_offset] = value_base[value_offset] + i;
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);
581
case OSL_PRECISION_SP:
582
*(long int *)result = *(long int *)value + (long int)i;
585
case OSL_PRECISION_DP:
586
*(long long int *)result = *(long long int *)value + (long long int)i;
589
#ifdef OSL_GMP_IS_HERE
590
case OSL_PRECISION_MP: {
592
mpz_init_set_si(si, i);
593
mpz_add(*(mpz_t *)result, *(mpz_t *)value, si);
600
OSL_error("unknown precision");
606
* result_base[result_offset] = val1_base[val1_offset]*val2_base[val2_offset];
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);
617
case OSL_PRECISION_SP:
618
*(long int *)result = *(long int *)val1 * *(long int *)val2;
621
case OSL_PRECISION_DP:
622
*(long long int *)result = *(long long int *)val1 *
623
*(long long int *)val2;
626
#ifdef OSL_GMP_IS_HERE
627
case OSL_PRECISION_MP:
628
mpz_mul(*(mpz_t *)result, *(mpz_t *)val1, *(mpz_t *)val2);
633
OSL_error("unknown precision");
639
* result_base[result_offset] = value_base[value_offset] * i;
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);
648
case OSL_PRECISION_SP:
649
*(long int *)result = *(long int *)value * (long int)i;
652
case OSL_PRECISION_DP:
653
*(long long int *)result = *(long long int *)value * (long long int)i;
656
#ifdef OSL_GMP_IS_HERE
657
case OSL_PRECISION_MP:
658
mpz_mul_si(*(mpz_t *)result, *(mpz_t *)value, i);
663
OSL_error("unknown precision");
669
* result_base[result_offset] = val1_base[val1_offset]-val2_base[val2_offset];
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);
680
case OSL_PRECISION_SP:
681
*(long int *)result = *(long int *)val1 - *(long int *)val2;
684
case OSL_PRECISION_DP:
685
*(long long int *)result = *(long long int *)val1 -
686
*(long long int *)val2;
689
#ifdef OSL_GMP_IS_HERE
690
case OSL_PRECISION_MP:
691
mpz_sub(*(mpz_t *)result, *(mpz_t *)val1, *(mpz_t *)val2);
696
OSL_error("unknown precision");
702
* result_base[result_offset] = -value_base[value_offset];
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);
711
case OSL_PRECISION_SP:
712
*(long int *)result = -*(long int *)value;
715
case OSL_PRECISION_DP:
716
*(long long int *)result = -*(long long int *)value;
719
#ifdef OSL_GMP_IS_HERE
720
case OSL_PRECISION_MP:
721
mpz_neg(*(mpz_t *)result, *(mpz_t *)value);
726
OSL_error("unknown precision");
731
/*+***************************************************************************
732
* Conditional Operations *
733
*****************************************************************************/
737
* (val1_base[val1_offset] == val2_base[val2_offset])
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);
746
case OSL_PRECISION_SP:
747
return (*(long int *)val1 == *(long int *)val2);
749
case OSL_PRECISION_DP:
750
return (*(long long int *)val1 == *(long long int *)val2);
752
#ifdef OSL_GMP_IS_HERE
753
case OSL_PRECISION_MP:
754
return (mpz_cmp(*(mpz_t *)val1, *(mpz_t *)val2) == 0);
758
OSL_error("unknown precision");
764
* (val1_base[val1_offset] != val2_base[val2_offset])
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);
776
* (value_base[value_offset] > 0)
778
int osl_int_pos(int precision, void * value_base, int value_offset) {
779
void * value = osl_int_address(precision, value_base, value_offset);
782
case OSL_PRECISION_SP:
783
return (*(long int *)value > 0);
785
case OSL_PRECISION_DP:
786
return (*(long long int *)value > 0);
788
#ifdef OSL_GMP_IS_HERE
789
case OSL_PRECISION_MP:
790
return (mpz_sgn(*(mpz_t *)value) > 0);
794
OSL_error("unknown precision");
800
* (value_base[value_offset] < 0)
802
int osl_int_neg(int precision, void * value_base, int value_offset) {
803
void * value = osl_int_address(precision, value_base, value_offset);
806
case OSL_PRECISION_SP:
807
return (*(long int *)value < 0);
809
case OSL_PRECISION_DP:
810
return (*(long long int *)value < 0);
812
#ifdef OSL_GMP_IS_HERE
813
case OSL_PRECISION_MP:
814
return (mpz_sgn(*(mpz_t *)value) < 0);
818
OSL_error("unknown precision");
824
* (value_base[value_offset] == 0)
826
int osl_int_zero(int precision, void * value_base, int value_offset) {
827
void * value = osl_int_address(precision, value_base, value_offset);
830
case OSL_PRECISION_SP:
831
return (*(long int *)value == 0);
833
case OSL_PRECISION_DP:
834
return (*(long long int *)value == 0);
836
#ifdef OSL_GMP_IS_HERE
837
case OSL_PRECISION_MP:
838
return (mpz_sgn(*(mpz_t *)value) == 0);
842
OSL_error("unknown precision");
848
* (value_base[value_offset] == 1)
850
int osl_int_one(int precision, void * value_base, int value_offset) {
851
void * value = osl_int_address(precision, value_base, value_offset);
854
case OSL_PRECISION_SP:
855
return (*(long int *)value == (long int)1);
857
case OSL_PRECISION_DP:
858
return (*(long long int *)value == (long long int)1);
860
#ifdef OSL_GMP_IS_HERE
861
case OSL_PRECISION_MP:
862
return (mpz_cmp_si(*(mpz_t *)value, 1) == 0);
866
OSL_error("unknown precision");
872
* (value_base[value_offset] == -1)
874
int osl_int_mone(int precision, void * value_base, int value_offset) {
875
void * value = osl_int_address(precision, value_base, value_offset);
878
case OSL_PRECISION_SP:
879
return (*(long int *)value == (long int)-1);
881
case OSL_PRECISION_DP:
882
return (*(long long int *)value == (long long int)-1);
884
#ifdef OSL_GMP_IS_HERE
885
case OSL_PRECISION_MP:
886
return (mpz_cmp_si(*(mpz_t *)value, -1) == 0);
890
OSL_error("unknown precision");
896
* ((val1_base[val1_offset] % val2_base[val2_offset]) == 0)
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);
905
case OSL_PRECISION_SP:
906
return ((*(long int *)val1 % *(long int *)val2) == 0);
908
case OSL_PRECISION_DP:
909
return ((*(long long int *)val1 % *(long long int *)val2) == 0);
911
#ifdef OSL_GMP_IS_HERE
912
case OSL_PRECISION_MP:
913
return mpz_divisible_p(*(mpz_t *)val1, *(mpz_t *)val2);
917
OSL_error("unknown precision");