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>
73
/*+***************************************************************************
75
*****************************************************************************/
79
* osl_int_is_precision_supported function:
80
* this function returns 1 if the precision provided as parameter is supported
81
* by the library and 0 otherwise. Possible values for the precision
82
* parameter are OSL_PRECISION_SP for 32 bits (single) precision,
83
* OSL_PRECISION_DP for 64 bits (double) precision and OSL_PRECISION_MP for
85
* \param[in] precision The precision to check for.
86
* \return 1 if the precision is supported, 0 otherwise.
88
int osl_int_is_precision_supported(int precision) {
90
case OSL_PRECISION_SP:
92
case OSL_PRECISION_DP:
94
#ifdef OSL_GMP_IS_HERE
95
case OSL_PRECISION_MP:
105
* osl_int_dump_precision function:
106
* this function prints in a human readable fashion the precision
107
* corresponding to the "precision" parameter.
108
* \param[in] file The file where to print the precision.
109
* \param[in] precision The precision to print.
111
void osl_int_dump_precision(FILE * file, int precision) {
113
case OSL_PRECISION_SP:
114
fprintf(file, "32 bits");
116
case OSL_PRECISION_DP:
117
fprintf(file, "64 bits");
119
#ifdef OSL_GMP_IS_HERE
120
case OSL_PRECISION_MP:
121
fprintf(file, "GMP");
125
fprintf(file, "unknown precision %d", precision);
130
void osl_int_init(int precision, osl_int_p variable) {
132
case OSL_PRECISION_SP:
136
case OSL_PRECISION_DP:
140
#ifdef OSL_GMP_IS_HERE
141
case OSL_PRECISION_MP:
142
OSL_malloc(variable->mp, void*, sizeof(mpz_t));
143
mpz_init(*((mpz_t*)variable->mp));
148
OSL_error("unknown precision");
153
osl_int_p osl_int_malloc(int precision) {
156
OSL_malloc(variable, osl_int_p, sizeof(osl_int_t));
157
osl_int_init(precision, variable);
165
void osl_int_assign(int precision, osl_int_p variable, osl_int_t value) {
167
case OSL_PRECISION_SP:
168
variable->sp = value.sp;
171
case OSL_PRECISION_DP:
172
variable->dp = value.dp;
175
#ifdef OSL_GMP_IS_HERE
176
case OSL_PRECISION_MP:
177
mpz_set(*((mpz_t*)variable->mp), *((mpz_t*)value.mp));
182
OSL_error("unknown precision");
190
void osl_int_set_si(int precision, osl_int_p variable, int i) {
192
case OSL_PRECISION_SP:
193
variable->sp = (long int)i;
196
case OSL_PRECISION_DP:
197
variable->dp = (long long int)i;
200
#ifdef OSL_GMP_IS_HERE
201
case OSL_PRECISION_MP:
202
mpz_set_si(*((mpz_t*)variable->mp), i);
207
OSL_error("unknown precision");
215
int osl_int_get_si(int precision, osl_int_t value) {
217
case OSL_PRECISION_SP:
220
case OSL_PRECISION_DP:
221
return (int)value.dp;
223
#ifdef OSL_GMP_IS_HERE
224
case OSL_PRECISION_MP:
225
return mpz_get_si(*((mpz_t*)value.mp));
229
OSL_error("unknown precision");
235
* variable = i; // including initialization for GMP
237
void osl_int_init_set_si(int precision, osl_int_p variable, int i) {
239
case OSL_PRECISION_SP:
240
variable->sp = (long int)i;
243
case OSL_PRECISION_DP:
244
variable->dp = (long long int)i;
247
#ifdef OSL_GMP_IS_HERE
248
case OSL_PRECISION_MP:
249
OSL_malloc(variable->mp, void*, sizeof(mpz_t));
250
mpz_init_set_si(*((mpz_t*)variable->mp), i);
255
OSL_error("unknown precision");
263
void osl_int_swap(int precision, osl_int_p var1, osl_int_p var2) {
265
case OSL_PRECISION_SP: {
266
long int temp = var1->sp;
272
case OSL_PRECISION_DP: {
273
long long int temp = var1->dp;
279
#ifdef OSL_GMP_IS_HERE
280
case OSL_PRECISION_MP: {
283
mpz_set(temp, *((mpz_t*)var1->mp));
284
mpz_set(*((mpz_t*)var1->mp), *((mpz_t*)var2->mp));
285
mpz_set(*((mpz_t*)var2->mp), temp);
292
OSL_error("unknown precision");
298
* variable = 0; // Including cleaning for GMP
300
void osl_int_clear(int precision, osl_int_p variable) {
302
case OSL_PRECISION_SP:
306
case OSL_PRECISION_DP:
310
#ifdef OSL_GMP_IS_HERE
311
case OSL_PRECISION_MP:
312
mpz_clear(*((mpz_t*)variable->mp));
318
OSL_error("unknown precision");
323
void osl_int_free(int precision, osl_int_p variable) {
324
osl_int_clear(precision, variable);
330
* osl_int_print function:
331
* this function displays an integer value into a file (file, possibly stdout).
332
* \param file The file where the integer has to be printed.
333
* \param precision The precision of the integer.
334
* \param value The integer element to print.
336
void osl_int_print(FILE * file, int precision, osl_int_t value) {
337
char string[OSL_MAX_STRING];
339
osl_int_sprint(string, precision, value);
340
fprintf(file, "%s", string);
345
* osl_int_sprint function:
346
* this function prints an integer value into a string, it uses the
347
* OpenScop Library formats OSL_FMT_* to format the printing.
348
* \param string The string where the integer has to be printed.
349
* \param precision The precision of the integer.
350
* \param value The integer element to print.
352
void osl_int_sprint(char * string, int precision, osl_int_t value) {
354
case OSL_PRECISION_SP:
355
sprintf(string, OSL_FMT_SP, value.sp);
358
case OSL_PRECISION_DP:
359
sprintf(string, OSL_FMT_DP, value.dp);
362
#ifdef OSL_GMP_IS_HERE
363
case OSL_PRECISION_MP: {
365
str = mpz_get_str(0, 10, *((mpz_t*)value.mp)); //TODO: 10 -> #define
366
sprintf(string, OSL_FMT_MP, str);
373
OSL_error("unknown precision");
379
* osl_int_sprint_txt function:
380
* this function is similar to osl_int_sprintf but it prints the value
381
* using OSL_TMT_TXT_* formats.
382
* \see osl_int_sprintf
384
void osl_int_sprint_txt(char * string, int precision, osl_int_t value) {
386
case OSL_PRECISION_SP:
387
sprintf(string, OSL_FMT_TXT_SP, value.sp);
390
case OSL_PRECISION_DP:
391
sprintf(string, OSL_FMT_TXT_DP, value.dp);
394
#ifdef OSL_GMP_IS_HERE
395
case OSL_PRECISION_MP: {
397
str = mpz_get_str(0, 10, *((mpz_t*)value.mp)); //TODO: 10 -> #define
398
sprintf(string, OSL_FMT_TXT_MP, str);
405
OSL_error("unknown precision");
410
void osl_int_sread(char ** string, int precision, osl_int_p variable) {
414
case OSL_PRECISION_SP:
415
nb_read = sscanf(*string, OSL_FMT_TXT_SP, &(variable->sp));
417
OSL_error("failed to read an integer");
420
case OSL_PRECISION_DP:
421
nb_read = sscanf(*string, OSL_FMT_TXT_DP, &(variable->dp));
423
OSL_error("failed to read an integer");
426
#ifdef OSL_GMP_IS_HERE
427
case OSL_PRECISION_MP: {
429
nb_read = sscanf(*string, OSL_FMT_TXT_DP, &tmp);
431
OSL_error("failed to read an integer");
432
mpz_set_si(*((mpz_t*)variable->mp), tmp);
438
OSL_error("unknown precision");
441
// Update the position in the input string.
442
*string = *string + nb_read;
446
/*+***************************************************************************
447
* Arithmetic Operations *
448
*****************************************************************************/
452
* variable <- value + 1;
454
void osl_int_increment(int precision, osl_int_p variable, osl_int_t value) {
456
case OSL_PRECISION_SP:
457
variable->sp = value.sp + 1;
460
case OSL_PRECISION_DP:
461
variable->dp = value.dp + (long long int)1;
464
#ifdef OSL_GMP_IS_HERE
465
case OSL_PRECISION_MP:
466
mpz_add_ui(*((mpz_t*)variable->mp), *((mpz_t*)value.mp), 1);
471
OSL_error("unknown precision");
477
* variable <- value - 1;
479
void osl_int_decrement(int precision, osl_int_p variable, osl_int_t value) {
481
case OSL_PRECISION_SP:
482
variable->sp = value.sp - 1;
485
case OSL_PRECISION_DP:
486
variable->dp = value.dp - (long long int)1;
489
#ifdef OSL_GMP_IS_HERE
490
case OSL_PRECISION_MP: {
492
mpz_init_set_si(one, 1);
493
mpz_sub(*((mpz_t*)variable->mp), *((mpz_t*)value.mp), one);
500
OSL_error("unknown precision");
506
* variable <- val1 + val2;
508
void osl_int_add(int precision,
509
osl_int_p variable, osl_int_t val1, osl_int_t val2) {
511
case OSL_PRECISION_SP:
512
variable->sp = val1.sp + val2.sp;
515
case OSL_PRECISION_DP:
516
variable->dp = val1.dp + val2.dp;
519
#ifdef OSL_GMP_IS_HERE
520
case OSL_PRECISION_MP:
521
mpz_add(*((mpz_t*)variable->mp), *((mpz_t*)val1.mp), *((mpz_t*)val2.mp));
526
OSL_error("unknown precision");
532
* variable <- value + i;
534
void osl_int_add_si(int precision,
535
osl_int_p variable, osl_int_t value, int i) {
537
case OSL_PRECISION_SP:
538
variable->sp = value.sp + (long int)i;
541
case OSL_PRECISION_DP:
542
variable->dp = value.dp + (long long int)i;
545
#ifdef OSL_GMP_IS_HERE
546
case OSL_PRECISION_MP: {
548
mpz_init_set_si(si, i);
549
mpz_add(*((mpz_t*)variable->mp), *((mpz_t*)value.mp), si);
556
OSL_error("unknown precision");
562
* variable <- val1 * val2;
564
void osl_int_mul(int precision,
565
osl_int_p variable, osl_int_t val1, osl_int_t val2) {
567
case OSL_PRECISION_SP:
568
variable->sp = val1.sp * val2.sp;
571
case OSL_PRECISION_DP:
572
variable->dp = val1.dp * val2.dp;
575
#ifdef OSL_GMP_IS_HERE
576
case OSL_PRECISION_MP:
577
mpz_mul(*((mpz_t*)variable->mp), *((mpz_t*)val1.mp), *((mpz_t*)val2.mp));
582
OSL_error("unknown precision");
588
* variable <- value * i;
590
void osl_int_mul_si(int precision,
591
osl_int_p variable, osl_int_t value, int i) {
593
case OSL_PRECISION_SP:
594
variable->sp = value.sp * (long int)i;
597
case OSL_PRECISION_DP:
598
variable->dp = value.dp * (long long int)i;
601
#ifdef OSL_GMP_IS_HERE
602
case OSL_PRECISION_MP:
603
mpz_mul_si(*((mpz_t*)variable->mp), *((mpz_t*)value.mp), i);
608
OSL_error("unknown precision");
614
* variable <- val1 - val2;
616
void osl_int_sub(int precision,
617
osl_int_p variable, osl_int_t val1, osl_int_t val2) {
619
case OSL_PRECISION_SP:
620
variable->sp = val1.sp - val2.sp;
623
case OSL_PRECISION_DP:
624
variable->dp = val1.dp - val2.dp;
627
#ifdef OSL_GMP_IS_HERE
628
case OSL_PRECISION_MP:
629
mpz_sub(*((mpz_t*)variable->mp), *((mpz_t*)val1.mp), *((mpz_t*)val2.mp));
634
OSL_error("unknown precision");
640
* variable <- -value;
642
void osl_int_oppose(int precision, osl_int_p variable, osl_int_t value) {
644
case OSL_PRECISION_SP:
645
variable->sp = -value.sp;
648
case OSL_PRECISION_DP:
649
variable->dp = -value.dp;
652
#ifdef OSL_GMP_IS_HERE
653
case OSL_PRECISION_MP:
654
mpz_neg(*((mpz_t*)variable->mp), *((mpz_t*)value.mp));
659
OSL_error("unknown precision");
665
* variable <- | value |;
667
void osl_int_abs(int precision, osl_int_p variable, osl_int_t value) {
669
case OSL_PRECISION_SP:
670
variable->sp = (value.sp > 0) ? value.sp : -value.sp;
673
case OSL_PRECISION_DP:
674
variable->dp = (value.dp > 0) ? value.dp : -value.dp;
677
#ifdef OSL_GMP_IS_HERE
678
case OSL_PRECISION_MP:
679
mpz_abs(*((mpz_t*)variable->mp), *((mpz_t*)value.mp));
684
OSL_error("unknown precision");
689
/*+***************************************************************************
690
* Conditional Operations *
691
*****************************************************************************/
697
int osl_int_eq(int precision, osl_int_t val1, osl_int_t val2) {
699
case OSL_PRECISION_SP:
700
return (val1.sp == val2.sp);
702
case OSL_PRECISION_DP:
703
return (val1.dp == val2.dp);
705
#ifdef OSL_GMP_IS_HERE
706
case OSL_PRECISION_MP:
707
return (mpz_cmp(*((mpz_t*)val1.mp), *((mpz_t*)val2.mp)) == 0);
711
OSL_error("unknown precision");
719
int osl_int_ne(int precision, osl_int_t val1, osl_int_t val2) {
720
return !osl_int_eq(precision, val1, val2);
727
int osl_int_pos(int precision, osl_int_t value) {
729
case OSL_PRECISION_SP:
730
return (value.sp > 0);
732
case OSL_PRECISION_DP:
733
return (value.dp > 0);
735
#ifdef OSL_GMP_IS_HERE
736
case OSL_PRECISION_MP:
737
return (mpz_sgn(*((mpz_t*)value.mp)) > 0);
741
OSL_error("unknown precision");
749
int osl_int_neg(int precision, osl_int_t value) {
751
case OSL_PRECISION_SP:
752
return (value.sp < 0);
754
case OSL_PRECISION_DP:
755
return (value.dp < 0);
757
#ifdef OSL_GMP_IS_HERE
758
case OSL_PRECISION_MP:
759
return (mpz_sgn(*((mpz_t*)value.mp)) < 0);
763
OSL_error("unknown precision");
771
int osl_int_zero(int precision, osl_int_t value) {
773
case OSL_PRECISION_SP:
774
return (value.sp == 0);
776
case OSL_PRECISION_DP:
777
return (value.dp == 0);
779
#ifdef OSL_GMP_IS_HERE
780
case OSL_PRECISION_MP:
781
return (mpz_sgn(*((mpz_t*)value.mp)) == 0);
785
OSL_error("unknown precision");
793
int osl_int_one(int precision, osl_int_t value) {
795
case OSL_PRECISION_SP:
796
return (value.sp == (long int)1);
798
case OSL_PRECISION_DP:
799
return (value.dp == (long long int)1);
801
#ifdef OSL_GMP_IS_HERE
802
case OSL_PRECISION_MP:
803
return (mpz_cmp_si(*((mpz_t*)value.mp), 1) == 0);
807
OSL_error("unknown precision");
815
int osl_int_mone(int precision, osl_int_t value) {
817
case OSL_PRECISION_SP:
818
return (value.sp == (long int)-1);
820
case OSL_PRECISION_DP:
821
return (value.dp == (long long int)-1);
823
#ifdef OSL_GMP_IS_HERE
824
case OSL_PRECISION_MP:
825
return (mpz_cmp_si(*((mpz_t*)value.mp), -1) == 0);
829
OSL_error("unknown precision");
835
* ((val1 % val2) == 0)
837
int osl_int_divisible(int precision, osl_int_t val1, osl_int_t val2) {
839
case OSL_PRECISION_SP:
840
return ((val1.sp % val2.sp) == 0);
842
case OSL_PRECISION_DP:
843
return ((val1.dp % val2.dp) == 0);
845
#ifdef OSL_GMP_IS_HERE
846
case OSL_PRECISION_MP:
847
return mpz_divisible_p(*((mpz_t*)val1.mp), *((mpz_t*)val2.mp));
851
OSL_error("unknown precision");