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_malloc(int precision
) {
166 case OPENSCOP_PRECISION_SP
:
167 value
= malloc(sizeof(long int));
170 case OPENSCOP_PRECISION_DP
:
171 value
= malloc(sizeof(long long int));
172 *(long long int *)value
= 0;
175 #ifdef OPENSCOP_GMP_IS_HERE
176 case OPENSCOP_PRECISION_MP
:
177 value
= malloc(sizeof(mpz_t
));
182 OPENSCOP_error("unknown precision");
185 openscop_int_init(precision
, value
, 0);
190 void openscop_int_assign(int precision
,
191 void * val1_base
, int val1_offset
,
192 void * val2_base
, int val2_offset
) {
193 void * val1
= openscop_int_address(precision
, val1_base
, val1_offset
);
194 void * val2
= openscop_int_address(precision
, val2_base
, val2_offset
);
197 case OPENSCOP_PRECISION_SP
:
198 *(long int *)val1
= *(long int *)val2
;
201 case OPENSCOP_PRECISION_DP
:
202 *(long long int *)val1
= *(long long int *)val2
;
205 #ifdef OPENSCOP_GMP_IS_HERE
206 case OPENSCOP_PRECISION_MP
:
207 mpz_set(*(mpz_t
*)val1
, *(mpz_t
*)val2
);
212 OPENSCOP_error("unknown precision");
217 void openscop_int_set_si(int precision
, void * value_base
, int value_offset
,
219 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
222 case OPENSCOP_PRECISION_SP
:
223 *(long int *)value
= (long int)i
;
226 case OPENSCOP_PRECISION_DP
:
227 *(long long int *)value
= (long long int)i
;
230 #ifdef OPENSCOP_GMP_IS_HERE
231 case OPENSCOP_PRECISION_MP
:
232 mpz_set_si(*(mpz_t
*)value
, i
);
237 OPENSCOP_error("unknown precision");
242 int openscop_int_get_si(int precision
, void * value_base
, int value_offset
) {
243 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
246 case OPENSCOP_PRECISION_SP
:
247 return *(int *)value
;
249 case OPENSCOP_PRECISION_DP
:
250 return *(int *)value
;
252 #ifdef OPENSCOP_GMP_IS_HERE
253 case OPENSCOP_PRECISION_MP
:
254 return mpz_get_si(*(mpz_t
*)value
);
258 OPENSCOP_error("unknown precision");
263 void openscop_int_init_set_si(int precision
,
264 void * value_base
, int value_offset
, int i
) {
265 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
268 case OPENSCOP_PRECISION_SP
:
269 *(long int *)value
= (long int)i
;
272 case OPENSCOP_PRECISION_DP
:
273 *(long long int *)value
= (long long int)i
;
276 #ifdef OPENSCOP_GMP_IS_HERE
277 case OPENSCOP_PRECISION_MP
:
278 mpz_init_set_si(*(mpz_t
*)value
, i
);
283 OPENSCOP_error("unknown precision");
288 void openscop_int_clear(int precision
, void * value_base
, int value_offset
) {
289 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
292 case OPENSCOP_PRECISION_SP
:
293 *(long int *)value
= 0;
296 case OPENSCOP_PRECISION_DP
:
297 *(long long int *)value
= 0;
300 #ifdef OPENSCOP_GMP_IS_HERE
301 case OPENSCOP_PRECISION_MP
:
302 mpz_clear(*(mpz_t
*)value
);
307 OPENSCOP_error("unknown precision");
312 void openscop_int_free(int precision
, void * value_base
, int value_offset
) {
313 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
315 openscop_int_clear(precision
, value_base
, value_offset
);
321 * openscop_int_print function:
322 * this function displays an integer value into a file (file, possibly stdout).
323 * \param file The file 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_print(FILE * file
, int precision
,
328 void * value_base
, int value_offset
) {
329 char string
[OPENSCOP_MAX_STRING
];
331 openscop_int_sprint(string
, precision
, value_base
, value_offset
);
332 fprintf(file
, "%s", string
);
337 * openscop_int_sprint function:
338 * this function prints an integer value into a string.
339 * \param string The string where the integer has to be printed.
340 * \param precision The precision of the integer.
341 * \param value Address of the integer value.
343 void openscop_int_sprint(char * string
, int precision
,
344 void * value_base
, int value_offset
) {
345 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
348 case OPENSCOP_PRECISION_SP
:
349 sprintf(string
, OPENSCOP_FMT_SP
, *(long int *)value
);
352 case OPENSCOP_PRECISION_DP
:
353 sprintf(string
, OPENSCOP_FMT_DP
, *(long long int *)value
);
356 #ifdef OPENSCOP_GMP_IS_HERE
357 case OPENSCOP_PRECISION_MP
: {
359 str
= mpz_get_str(0, 10, *(mpz_t
*)value
); //TODO: 10 -> #define
360 sprintf(string
, OPENSCOP_FMT_MP
, str
);
367 OPENSCOP_error("unknown precision");
372 void openscop_int_sread(char * string
, int precision
,
373 void * value_base
, int value_offset
) {
374 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
378 case OPENSCOP_PRECISION_SP
:
379 nb_read
= sscanf(string
, OPENSCOP_FMT_TXT_SP
, (long int *)value
);
381 OPENSCOP_error("failed to read an integer");
384 case OPENSCOP_PRECISION_DP
:
385 nb_read
= sscanf(string
, OPENSCOP_FMT_TXT_DP
, (long long int *)value
);
387 OPENSCOP_error("failed to read an integer");
390 #ifdef OPENSCOP_GMP_IS_HERE
391 case OPENSCOP_PRECISION_MP
: {
393 nb_read
= sscanf(string
, OPENSCOP_FMT_TXT_DP
, &tmp
);
395 OPENSCOP_error("failed to read an integer");
396 mpz_set_si(*(mpz_t
*)value
, tmp
);
402 OPENSCOP_error("unknown precision");
407 /*+***************************************************************************
408 * Arithmetic Operations *
409 *****************************************************************************/
412 void openscop_int_increment(int precision
,
413 void * result_base
, int result_offset
,
414 void * value_base
, int value_offset
) {
415 void * result
= openscop_int_address(precision
, result_base
, result_offset
);
416 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
419 case OPENSCOP_PRECISION_SP
:
420 *(long int *)result
= *(long int *)value
+ (long int)1;
423 case OPENSCOP_PRECISION_DP
:
424 *(long long int *)result
= *(long long int *)value
+ (long long int)1;
427 #ifdef OPENSCOP_GMP_IS_HERE
428 case OPENSCOP_PRECISION_MP
:
429 mpz_add_ui(*(mpz_t
*)result
, *(mpz_t
*)value
, 1);
434 OPENSCOP_error("unknown precision");
439 void openscop_int_decrement(int precision
,
440 void * result_base
, int result_offset
,
441 void * value_base
, int value_offset
) {
442 void * result
= openscop_int_address(precision
, result_base
, result_offset
);
443 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
446 case OPENSCOP_PRECISION_SP
:
447 *(long int *)result
= *(long int *)value
- (long int)1;
450 case OPENSCOP_PRECISION_DP
:
451 *(long long int *)result
= *(long long int *)value
- (long long int)1;
454 #ifdef OPENSCOP_GMP_IS_HERE
455 case OPENSCOP_PRECISION_MP
: {
457 mpz_init_set_si(one
, 1);
458 mpz_sub(*(mpz_t
*)result
, *(mpz_t
*)value
, one
);
465 OPENSCOP_error("unknown precision");
470 void openscop_int_add(int precision
,
471 void * result_base
, int result_offset
,
472 void * val1_base
, int val1_offset
,
473 void * val2_base
, int val2_offset
) {
474 void * result
= openscop_int_address(precision
, result_base
, result_offset
);
475 void * val1
= openscop_int_address(precision
, val1_base
, val1_offset
);
476 void * val2
= openscop_int_address(precision
, val2_base
, val2_offset
);
479 case OPENSCOP_PRECISION_SP
:
480 *(long int *)result
= *(long int *)val1
+ *(long int *)val2
;
483 case OPENSCOP_PRECISION_DP
:
484 *(long long int *)result
= *(long long int *)val1
+
485 *(long long int *)val2
;
488 #ifdef OPENSCOP_GMP_IS_HERE
489 case OPENSCOP_PRECISION_MP
:
490 mpz_add(*(mpz_t
*)result
, *(mpz_t
*)val1
, *(mpz_t
*)val2
);
495 OPENSCOP_error("unknown precision");
500 void openscop_int_add_ui(int precision
,
501 void * result_base
, int result_offset
,
502 void * value_base
, int value_offset
, int i
) {
503 void * result
= openscop_int_address(precision
, result_base
, result_offset
);
504 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
507 case OPENSCOP_PRECISION_SP
:
508 *(long int *)result
= *(long int *)value
+ (long int)i
;
511 case OPENSCOP_PRECISION_DP
:
512 *(long long int *)result
= *(long long int *)value
+ (long long int)i
;
515 #ifdef OPENSCOP_GMP_IS_HERE
516 case OPENSCOP_PRECISION_MP
:
517 mpz_add_ui(*(mpz_t
*)result
, *(mpz_t
*)value
, (long int)i
);
522 OPENSCOP_error("unknown precision");
527 void openscop_int_mul(int precision
,
528 void * result_base
, int result_offset
,
529 void * val1_base
, int val1_offset
,
530 void * val2_base
, int val2_offset
) {
531 void * result
= openscop_int_address(precision
, result_base
, result_offset
);
532 void * val1
= openscop_int_address(precision
, val1_base
, val1_offset
);
533 void * val2
= openscop_int_address(precision
, val2_base
, val2_offset
);
536 case OPENSCOP_PRECISION_SP
:
537 *(long int *)result
= *(long int *)val1
* *(long int *)val2
;
540 case OPENSCOP_PRECISION_DP
:
541 *(long long int *)result
= *(long long int *)val1
*
542 *(long long int *)val2
;
545 #ifdef OPENSCOP_GMP_IS_HERE
546 case OPENSCOP_PRECISION_MP
:
547 mpz_mul(*(mpz_t
*)result
, *(mpz_t
*)val1
, *(mpz_t
*)val2
);
552 OPENSCOP_error("unknown precision");
557 void openscop_int_mul_si(int precision
,
558 void * result_base
, int result_offset
,
559 void * value_base
, int value_offset
, int i
) {
560 void * result
= openscop_int_address(precision
, result_base
, result_offset
);
561 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
564 case OPENSCOP_PRECISION_SP
:
565 *(long int *)result
= *(long int *)value
* (long int)i
;
568 case OPENSCOP_PRECISION_DP
:
569 *(long long int *)result
= *(long long int *)value
* (long long int)i
;
572 #ifdef OPENSCOP_GMP_IS_HERE
573 case OPENSCOP_PRECISION_MP
:
574 mpz_mul_si(*(mpz_t
*)result
, *(mpz_t
*)value
, i
);
579 OPENSCOP_error("unknown precision");
584 void openscop_int_sub(int precision
,
585 void * result_base
, int result_offset
,
586 void * val1_base
, int val1_offset
,
587 void * val2_base
, int val2_offset
) {
588 void * result
= openscop_int_address(precision
, result_base
, result_offset
);
589 void * val1
= openscop_int_address(precision
, val1_base
, val1_offset
);
590 void * val2
= openscop_int_address(precision
, val2_base
, val2_offset
);
593 case OPENSCOP_PRECISION_SP
:
594 *(long int *)result
= *(long int *)val1
- *(long int *)val2
;
597 case OPENSCOP_PRECISION_DP
:
598 *(long long int *)result
= *(long long int *)val1
-
599 *(long long int *)val2
;
602 #ifdef OPENSCOP_GMP_IS_HERE
603 case OPENSCOP_PRECISION_MP
:
604 mpz_sub(*(mpz_t
*)result
, *(mpz_t
*)val1
, *(mpz_t
*)val2
);
609 OPENSCOP_error("unknown precision");
614 void openscop_int_oppose(int precision
,
615 void * result_base
, int result_offset
,
616 void * value_base
, int value_offset
) {
617 void * result
= openscop_int_address(precision
, result_base
, result_offset
);
618 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
621 case OPENSCOP_PRECISION_SP
:
622 *(long int *)result
= -*(long int *)value
;
625 case OPENSCOP_PRECISION_DP
:
626 *(long long int *)result
= -*(long long int *)value
;
629 #ifdef OPENSCOP_GMP_IS_HERE
630 case OPENSCOP_PRECISION_MP
:
631 mpz_neg(*(mpz_t
*)result
, *(mpz_t
*)value
);
636 OPENSCOP_error("unknown precision");
641 /*+***************************************************************************
642 * Conditional Operations *
643 *****************************************************************************/
646 int openscop_int_eq(int precision
,
647 void * val1_base
, int val1_offset
,
648 void * val2_base
, int val2_offset
) {
649 void * val1
= openscop_int_address(precision
, val1_base
, val1_offset
);
650 void * val2
= openscop_int_address(precision
, val2_base
, val2_offset
);
653 case OPENSCOP_PRECISION_SP
:
654 return (*(long int *)val1
== *(long int *)val2
);
656 case OPENSCOP_PRECISION_DP
:
657 return (*(long long int *)val1
== *(long long int *)val2
);
659 #ifdef OPENSCOP_GMP_IS_HERE
660 case OPENSCOP_PRECISION_MP
:
661 return (mpz_cmp(*(mpz_t
*)val1
, *(mpz_t
*)val2
) == 0);
665 OPENSCOP_error("unknown precision");
670 int openscop_int_ne(int precision
,
671 void * val1_base
, int val1_offset
,
672 void * val2_base
, int val2_offset
) {
673 return !openscop_int_eq(precision
,
674 val1_base
, val1_offset
,
675 val2_base
, val2_offset
);
679 int openscop_int_pos(int precision
, void * value_base
, int value_offset
) {
680 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
683 case OPENSCOP_PRECISION_SP
:
684 return (*(long int *)value
> 0);
686 case OPENSCOP_PRECISION_DP
:
687 return (*(long long int *)value
> 0);
689 #ifdef OPENSCOP_GMP_IS_HERE
690 case OPENSCOP_PRECISION_MP
:
691 return (mpz_sgn(*(mpz_t
*)value
) > 0);
695 OPENSCOP_error("unknown precision");
700 int openscop_int_neg(int precision
, void * value_base
, int value_offset
) {
701 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
704 case OPENSCOP_PRECISION_SP
:
705 return (*(long int *)value
< 0);
707 case OPENSCOP_PRECISION_DP
:
708 return (*(long long int *)value
< 0);
710 #ifdef OPENSCOP_GMP_IS_HERE
711 case OPENSCOP_PRECISION_MP
:
712 return (mpz_sgn(*(mpz_t
*)value
) < 0);
716 OPENSCOP_error("unknown precision");
721 int openscop_int_zero(int precision
, void * value_base
, int value_offset
) {
722 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
725 case OPENSCOP_PRECISION_SP
:
726 return (*(long int *)value
== 0);
728 case OPENSCOP_PRECISION_DP
:
729 return (*(long long int *)value
== 0);
731 #ifdef OPENSCOP_GMP_IS_HERE
732 case OPENSCOP_PRECISION_MP
:
733 return (mpz_sgn(*(mpz_t
*)value
) == 0);
737 OPENSCOP_error("unknown precision");
742 int openscop_int_notzero(int precision
, void * value_base
, int value_offset
) {
744 return !openscop_int_zero(precision
, value_base
, value_offset
);
748 int openscop_int_one(int precision
, void * value_base
, int value_offset
) {
749 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
752 case OPENSCOP_PRECISION_SP
:
753 return (*(long int *)value
== (long int)1);
755 case OPENSCOP_PRECISION_DP
:
756 return (*(long long int *)value
== (long long int)1);
758 #ifdef OPENSCOP_GMP_IS_HERE
759 case OPENSCOP_PRECISION_MP
:
760 return (mpz_cmp_si(*(mpz_t
*)value
, 1) == 0);
764 OPENSCOP_error("unknown precision");
769 int openscop_int_mone(int precision
, void * value_base
, int value_offset
) {
770 void * value
= openscop_int_address(precision
, value_base
, value_offset
);
773 case OPENSCOP_PRECISION_SP
:
774 return (*(long int *)value
== (long int)-1);
776 case OPENSCOP_PRECISION_DP
:
777 return (*(long long int *)value
== (long long int)-1);
779 #ifdef OPENSCOP_GMP_IS_HERE
780 case OPENSCOP_PRECISION_MP
:
781 return (mpz_cmp_si(*(mpz_t
*)value
, -1) == 0);
785 OPENSCOP_error("unknown precision");
790 int openscop_int_divisible(int precision
,
791 void * val1_base
, int val1_offset
,
792 void * val2_base
, int val2_offset
) {
793 void * val1
= openscop_int_address(precision
, val1_base
, val1_offset
);
794 void * val2
= openscop_int_address(precision
, val2_base
, val2_offset
);
797 case OPENSCOP_PRECISION_SP
:
798 return ((*(long int *)val1
% *(long int *)val2
) == 0);
800 case OPENSCOP_PRECISION_DP
:
801 return ((*(long long int *)val1
% *(long long int *)val2
) == 0);
803 #ifdef OPENSCOP_GMP_IS_HERE
804 case OPENSCOP_PRECISION_MP
:
805 return mpz_divisible_p(*(mpz_t
*)val1
, *(mpz_t
*)val2
);
809 OPENSCOP_error("unknown precision");