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 # include <openscop/int.h>
68 /*+***************************************************************************
70 *****************************************************************************/
74 * openscop_int_dump_precision function:
75 * this function prints in a human readable fashion the precision
76 * corresponding to the "precision" parameter.
77 * \param[in] file The file where to print the precision.
78 * \param[in] precision The precision to print.
80 void openscop_int_dump_precision(FILE * file
, int precision
) {
83 case OPENSCOP_PRECISION_SP
:
84 fprintf(file
, "32 bits");
86 case OPENSCOP_PRECISION_DP
:
87 fprintf(file
, "64 bits");
89 #ifdef OPENSCOP_GMP_IS_HERE
90 case OPENSCOP_PRECISION_MP
:
95 fprintf(file
, "unknown precision %d", precision
);
100 int openscop_int_sizeof(int precision
) {
102 case OPENSCOP_PRECISION_SP
:
103 return sizeof(long int);
105 case OPENSCOP_PRECISION_DP
:
106 return sizeof(long long int);
108 #ifdef OPENSCOP_GMP_IS_HERE
109 case OPENSCOP_PRECISION_MP
:
110 return sizeof(mpz_t
);
114 OPENSCOP_error("unknown precision");
119 void * openscop_int_address(int precision
, void * base
, int offset
) {
121 case OPENSCOP_PRECISION_SP
:
122 return (long int *)base
+ offset
;
124 case OPENSCOP_PRECISION_DP
:
125 return (long long int *)base
+ offset
;
127 #ifdef OPENSCOP_GMP_IS_HERE
128 case OPENSCOP_PRECISION_MP
:
129 return (mpz_t
*)base
+ offset
;
133 OPENSCOP_error("unknown precision");
138 void openscop_int_init(int precision
, void * value_base
, int value_offset
) {
139 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
142 case OPENSCOP_PRECISION_SP
:
143 *(long int *)value
= 0;
146 case OPENSCOP_PRECISION_DP
:
147 *(long long int *)value
= 0;
150 #ifdef OPENSCOP_GMP_IS_HERE
151 case OPENSCOP_PRECISION_MP
:
152 mpz_init(*(mpz_t
*)value
);
157 OPENSCOP_error("unknown precision");
162 void openscop_int_assign(int precision
,
163 void * val1_base
, int val1_offset
,
164 void * val2_base
, int val2_offset
) {
165 void * val1
= openscop_int_address(precision
, val1_base
, val1_offset
);
166 void * val2
= openscop_int_address(precision
, val2_base
, val2_offset
);
169 case OPENSCOP_PRECISION_SP
:
170 *(long int *)val1
= *(long int *)val2
;
173 case OPENSCOP_PRECISION_DP
:
174 *(long long int *)val1
= *(long long int *)val2
;
177 #ifdef OPENSCOP_GMP_IS_HERE
178 case OPENSCOP_PRECISION_MP
:
179 mpz_set(*(mpz_t
*)val1
, *(mpz_t
*)val2
);
184 OPENSCOP_error("unknown precision");
189 void openscop_int_set_si(int precision
, void * value_base
, int value_offset
,
191 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
194 case OPENSCOP_PRECISION_SP
:
195 *(long int *)value
= (long int)i
;
198 case OPENSCOP_PRECISION_DP
:
199 *(long long int *)value
= (long long int)i
;
202 #ifdef OPENSCOP_GMP_IS_HERE
203 case OPENSCOP_PRECISION_MP
:
204 mpz_set_si(*(mpz_t
*)value
, i
);
209 OPENSCOP_error("unknown precision");
214 int openscop_int_get_si(int precision
, void * value_base
, int value_offset
) {
215 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
218 case OPENSCOP_PRECISION_SP
:
219 return *(int *)value
;
221 case OPENSCOP_PRECISION_DP
:
222 return *(int *)value
;
224 #ifdef OPENSCOP_GMP_IS_HERE
225 case OPENSCOP_PRECISION_MP
:
226 return mpz_get_si(*(mpz_t
*)value
);
230 OPENSCOP_error("unknown precision");
235 void openscop_int_init_set_si(int precision
,
236 void * value_base
, int value_offset
, int i
) {
237 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
240 case OPENSCOP_PRECISION_SP
:
241 *(long int *)value
= (long int)i
;
244 case OPENSCOP_PRECISION_DP
:
245 *(long long int *)value
= (long long int)i
;
248 #ifdef OPENSCOP_GMP_IS_HERE
249 case OPENSCOP_PRECISION_MP
:
250 mpz_init_set_si(*(mpz_t
*)value
, i
);
255 OPENSCOP_error("unknown precision");
260 void openscop_int_clear(int precision
, void * value_base
, int value_offset
) {
261 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
264 case OPENSCOP_PRECISION_SP
:
265 *(long int *)value
= 0;
268 case OPENSCOP_PRECISION_DP
:
269 *(long long int *)value
= 0;
272 #ifdef OPENSCOP_GMP_IS_HERE
273 case OPENSCOP_PRECISION_MP
:
274 mpz_clear(*(mpz_t
*)value
);
279 OPENSCOP_error("unknown precision");
285 * openscop_int_print function:
286 * this function displays an integer value into a file (file, possibly stdout).
287 * \param file The file where the integer has to be printed.
288 * \param precision The precision of the integer.
289 * \param value Address of the integer value.
291 void openscop_int_print(FILE * file
, int precision
,
292 void * value_base
, int value_offset
) {
293 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
296 case OPENSCOP_PRECISION_SP
:
297 fprintf(file
, OPENSCOP_FMT_SP
, *(long int *)value
);
300 case OPENSCOP_PRECISION_DP
:
301 fprintf(file
, OPENSCOP_FMT_DP
, *(long long int *)value
);
304 #ifdef OPENSCOP_GMP_IS_HERE
305 case OPENSCOP_PRECISION_MP
: {
307 str
= mpz_get_str(0, 10, *(mpz_t
*)value
); //TODO: 10 -> #define
308 fprintf(file
, OPENSCOP_FMT_MP
, str
);
315 OPENSCOP_error("unknown precision");
321 * openscop_int_sprint function:
322 * this function prints an integer value into a string.
323 * \param string The string where the integer has to be printed.
324 * \param precision The precision of the integer.
325 * \param value Address of the integer value.
327 void openscop_int_sprint(char * string
, int precision
,
328 void * value_base
, int value_offset
) {
329 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
332 case OPENSCOP_PRECISION_SP
:
333 sprintf(string
, OPENSCOP_FMT_SP
, *(long int *)value
);
336 case OPENSCOP_PRECISION_DP
:
337 sprintf(string
, OPENSCOP_FMT_DP
, *(long long int *)value
);
340 #ifdef OPENSCOP_GMP_IS_HERE
341 case OPENSCOP_PRECISION_MP
: {
343 str
= mpz_get_str(0, 10, *(mpz_t
*)value
); //TODO: 10 -> #define
344 sprintf(string
, OPENSCOP_FMT_MP
, str
);
351 OPENSCOP_error("unknown precision");
356 void openscop_int_sread(char * string
, int precision
,
357 void * value_base
, int value_offset
) {
358 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
362 case OPENSCOP_PRECISION_SP
:
363 nb_read
= sscanf(string
, OPENSCOP_FMT_TXT_SP
, (long int *)value
);
365 OPENSCOP_error("failed to read an integer");
368 case OPENSCOP_PRECISION_DP
:
369 nb_read
= sscanf(string
, OPENSCOP_FMT_TXT_DP
, (long long int *)value
);
371 OPENSCOP_error("failed to read an integer");
374 #ifdef OPENSCOP_GMP_IS_HERE
375 case OPENSCOP_PRECISION_MP
: {
377 nb_read
= sscanf(string
, OPENSCOP_FMT_TXT_DP
, &tmp
);
379 OPENSCOP_error("failed to read an integer");
380 mpz_set_si(*(mpz_t
*)value
, tmp
);
386 OPENSCOP_error("unknown precision");
391 /*+***************************************************************************
392 * Arithmetic Operations *
393 *****************************************************************************/
396 void openscop_int_increment(int precision
,
397 void * result_base
, int result_offset
,
398 void * value_base
, int value_offset
) {
399 void * result
= openscop_int_address(precision
, result_base
, result_offset
);
400 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
403 case OPENSCOP_PRECISION_SP
:
404 *(long int *)result
= *(long int *)value
+ (long int)1;
407 case OPENSCOP_PRECISION_DP
:
408 *(long long int *)result
= *(long long int *)value
+ (long long int)1;
411 #ifdef OPENSCOP_GMP_IS_HERE
412 case OPENSCOP_PRECISION_MP
:
413 mpz_add_ui(*(mpz_t
*)result
, *(mpz_t
*)value
, 1);
418 OPENSCOP_error("unknown precision");
423 void openscop_int_add(int precision
,
424 void * result_base
, int result_offset
,
425 void * val1_base
, int val1_offset
,
426 void * val2_base
, int val2_offset
) {
427 void * result
= openscop_int_address(precision
, result_base
, result_offset
);
428 void * val1
= openscop_int_address(precision
, val1_base
, val1_offset
);
429 void * val2
= openscop_int_address(precision
, val2_base
, val2_offset
);
432 case OPENSCOP_PRECISION_SP
:
433 *(long int *)result
= *(long int *)val1
+ *(long int *)val2
;
436 case OPENSCOP_PRECISION_DP
:
437 *(long long int *)result
= *(long long int *)val1
+
438 *(long long int *)val2
;
441 #ifdef OPENSCOP_GMP_IS_HERE
442 case OPENSCOP_PRECISION_MP
:
443 mpz_add(*(mpz_t
*)result
, *(mpz_t
*)val1
, *(mpz_t
*)val2
);
448 OPENSCOP_error("unknown precision");
453 void openscop_int_add_ui(int precision
,
454 void * result_base
, int result_offset
,
455 void * value_base
, int value_offset
, int i
) {
456 void * result
= openscop_int_address(precision
, result_base
, result_offset
);
457 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
460 case OPENSCOP_PRECISION_SP
:
461 *(long int *)result
= *(long int *)value
+ (long int)i
;
464 case OPENSCOP_PRECISION_DP
:
465 *(long long int *)result
= *(long long int *)value
+ (long long int)i
;
468 #ifdef OPENSCOP_GMP_IS_HERE
469 case OPENSCOP_PRECISION_MP
:
470 mpz_add_ui(*(mpz_t
*)result
, *(mpz_t
*)value
, (long int)i
);
475 OPENSCOP_error("unknown precision");
480 void openscop_int_mul(int precision
,
481 void * result_base
, int result_offset
,
482 void * val1_base
, int val1_offset
,
483 void * val2_base
, int val2_offset
) {
484 void * result
= openscop_int_address(precision
, result_base
, result_offset
);
485 void * val1
= openscop_int_address(precision
, val1_base
, val1_offset
);
486 void * val2
= openscop_int_address(precision
, val2_base
, val2_offset
);
489 case OPENSCOP_PRECISION_SP
:
490 *(long int *)result
= *(long int *)val1
* *(long int *)val2
;
493 case OPENSCOP_PRECISION_DP
:
494 *(long long int *)result
= *(long long int *)val1
*
495 *(long long int *)val2
;
498 #ifdef OPENSCOP_GMP_IS_HERE
499 case OPENSCOP_PRECISION_MP
:
500 mpz_mul(*(mpz_t
*)result
, *(mpz_t
*)val1
, *(mpz_t
*)val2
);
505 OPENSCOP_error("unknown precision");
510 void openscop_int_mul_si(int precision
,
511 void * result_base
, int result_offset
,
512 void * value_base
, int value_offset
, int i
) {
513 void * result
= openscop_int_address(precision
, result_base
, result_offset
);
514 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
517 case OPENSCOP_PRECISION_SP
:
518 *(long int *)result
= *(long int *)value
* (long int)i
;
521 case OPENSCOP_PRECISION_DP
:
522 *(long long int *)result
= *(long long int *)value
* (long long int)i
;
525 #ifdef OPENSCOP_GMP_IS_HERE
526 case OPENSCOP_PRECISION_MP
:
527 mpz_mul_si(*(mpz_t
*)result
, *(mpz_t
*)value
, i
);
532 OPENSCOP_error("unknown precision");
537 void openscop_int_sub(int precision
,
538 void * result_base
, int result_offset
,
539 void * val1_base
, int val1_offset
,
540 void * val2_base
, int val2_offset
) {
541 void * result
= openscop_int_address(precision
, result_base
, result_offset
);
542 void * val1
= openscop_int_address(precision
, val1_base
, val1_offset
);
543 void * val2
= openscop_int_address(precision
, val2_base
, val2_offset
);
546 case OPENSCOP_PRECISION_SP
:
547 *(long int *)result
= *(long int *)val1
- *(long int *)val2
;
550 case OPENSCOP_PRECISION_DP
:
551 *(long long int *)result
= *(long long int *)val1
-
552 *(long long int *)val2
;
555 #ifdef OPENSCOP_GMP_IS_HERE
556 case OPENSCOP_PRECISION_MP
:
557 mpz_sub(*(mpz_t
*)result
, *(mpz_t
*)val1
, *(mpz_t
*)val2
);
562 OPENSCOP_error("unknown precision");
567 void openscop_int_oppose(int precision
,
568 void * result_base
, int result_offset
,
569 void * value_base
, int value_offset
) {
570 void * result
= openscop_int_address(precision
, result_base
, result_offset
);
571 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
574 case OPENSCOP_PRECISION_SP
:
575 *(long int *)result
= -*(long int *)value
;
578 case OPENSCOP_PRECISION_DP
:
579 *(long long int *)result
= -*(long long int *)value
;
582 #ifdef OPENSCOP_GMP_IS_HERE
583 case OPENSCOP_PRECISION_MP
:
584 mpz_neg(*(mpz_t
*)result
, *(mpz_t
*)value
);
589 OPENSCOP_error("unknown precision");
594 /*+***************************************************************************
595 * Conditional Operations *
596 *****************************************************************************/
599 int openscop_int_eq(int precision
,
600 void * val1_base
, int val1_offset
,
601 void * val2_base
, int val2_offset
) {
602 void * val1
= openscop_int_address(precision
, val1_base
, val1_offset
);
603 void * val2
= openscop_int_address(precision
, val2_base
, val2_offset
);
606 case OPENSCOP_PRECISION_SP
:
607 return (*(long int *)val1
== *(long int *)val2
);
609 case OPENSCOP_PRECISION_DP
:
610 return (*(long long int *)val1
== *(long long int *)val2
);
612 #ifdef OPENSCOP_GMP_IS_HERE
613 case OPENSCOP_PRECISION_MP
:
614 return (mpz_cmp(*(mpz_t
*)val1
, *(mpz_t
*)val2
) == 0);
618 OPENSCOP_error("unknown precision");
623 int openscop_int_ne(int precision
,
624 void * val1_base
, int val1_offset
,
625 void * val2_base
, int val2_offset
) {
626 void * val1
= openscop_int_address(precision
, val1_base
, val1_offset
);
627 void * val2
= openscop_int_address(precision
, val2_base
, val2_offset
);
630 case OPENSCOP_PRECISION_SP
:
631 return (*(long int *)val1
!= *(long int *)val2
);
633 case OPENSCOP_PRECISION_DP
:
634 return (*(long long int *)val1
!= *(long long int *)val2
);
636 #ifdef OPENSCOP_GMP_IS_HERE
637 case OPENSCOP_PRECISION_MP
:
638 return (mpz_cmp(*(mpz_t
*)val1
, *(mpz_t
*)val2
) != 0);
642 OPENSCOP_error("unknown precision");
647 int openscop_int_pos(int precision
, void * value_base
, int value_offset
) {
648 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
651 case OPENSCOP_PRECISION_SP
:
652 return (*(long int *)value
> 0);
654 case OPENSCOP_PRECISION_DP
:
655 return (*(long long int *)value
> 0);
657 #ifdef OPENSCOP_GMP_IS_HERE
658 case OPENSCOP_PRECISION_MP
:
659 return (mpz_sgn(*(mpz_t
*)value
) > 0);
663 OPENSCOP_error("unknown precision");
668 int openscop_int_neg(int precision
, void * value_base
, int value_offset
) {
669 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
672 case OPENSCOP_PRECISION_SP
:
673 return (*(long int *)value
< 0);
675 case OPENSCOP_PRECISION_DP
:
676 return (*(long long int *)value
< 0);
678 #ifdef OPENSCOP_GMP_IS_HERE
679 case OPENSCOP_PRECISION_MP
:
680 return (mpz_sgn(*(mpz_t
*)value
) < 0);
684 OPENSCOP_error("unknown precision");
689 int openscop_int_zero(int precision
, void * value_base
, int value_offset
) {
690 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
693 case OPENSCOP_PRECISION_SP
:
694 return (*(long int *)value
== 0);
696 case OPENSCOP_PRECISION_DP
:
697 return (*(long long int *)value
== 0);
699 #ifdef OPENSCOP_GMP_IS_HERE
700 case OPENSCOP_PRECISION_MP
:
701 return (mpz_sgn(*(mpz_t
*)value
) == 0);
705 OPENSCOP_error("unknown precision");
710 int openscop_int_notzero(int precision
, void * value_base
, int value_offset
) {
711 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
714 case OPENSCOP_PRECISION_SP
:
715 return (*(long int *)value
!= 0);
717 case OPENSCOP_PRECISION_DP
:
718 return (*(long long int *)value
!= 0);
720 #ifdef OPENSCOP_GMP_IS_HERE
721 case OPENSCOP_PRECISION_MP
:
722 return (mpz_sgn(*(mpz_t
*)value
) != 0);
726 OPENSCOP_error("unknown precision");
731 int openscop_int_one(int precision
, void * value_base
, int value_offset
) {
732 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
735 case OPENSCOP_PRECISION_SP
:
736 return (*(long int *)value
== (long int)1);
738 case OPENSCOP_PRECISION_DP
:
739 return (*(long long int *)value
== (long long int)1);
741 #ifdef OPENSCOP_GMP_IS_HERE
742 case OPENSCOP_PRECISION_MP
:
743 return (mpz_cmp_si(*(mpz_t
*)value
, 1) == 0);
747 OPENSCOP_error("unknown precision");
752 int openscop_int_mone(int precision
, void * value_base
, int value_offset
) {
753 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
756 case OPENSCOP_PRECISION_SP
:
757 return (*(long int *)value
== (long int)-1);
759 case OPENSCOP_PRECISION_DP
:
760 return (*(long long int *)value
== (long long int)-1);
762 #ifdef OPENSCOP_GMP_IS_HERE
763 case OPENSCOP_PRECISION_MP
:
764 return (mpz_cmp_si(*(mpz_t
*)value
, -1) == 0);
768 OPENSCOP_error("unknown precision");
773 int openscop_int_divisible(int precision
,
774 void * val1_base
, int val1_offset
,
775 void * val2_base
, int val2_offset
) {
776 void * val1
= openscop_int_address(precision
, val1_base
, val1_offset
);
777 void * val2
= openscop_int_address(precision
, val2_base
, val2_offset
);
780 case OPENSCOP_PRECISION_SP
:
781 return ((*(long int *)val1
% *(long int *)val2
) == 0);
783 case OPENSCOP_PRECISION_DP
:
784 return ((*(long long int *)val1
% *(long long int *)val2
) == 0);
786 #ifdef OPENSCOP_GMP_IS_HERE
787 case OPENSCOP_PRECISION_MP
:
788 return mpz_divisible_p(*(mpz_t
*)val1
, *(mpz_t
*)val2
);
792 OPENSCOP_error("unknown precision");