author | Manuele conti <conti.ma@alice.it> |
Tue, 12 Jun 2012 09:45:31 +0200 | |
changeset 582 | 8495119e7271 |
parent 579 | 983a3b743085 |
child 587 | 1ecf916cc397 |
permissions | -rw-r--r-- |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
1 |
/* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
2 |
* matiec - a compiler for the programming languages defined in IEC 61131-3 |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
3 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
4 |
* Copyright (C) 2003-2011 Mario de Sousa (msousa@fe.up.pt) |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
5 |
* Copyright (C) 2012 Manuele Conti (conti.ma@alice.it) |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
6 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
7 |
* This program is free software: you can redistribute it and/or modify |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
8 |
* it under the terms of the GNU General Public License as published by |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
9 |
* the Free Software Foundation, either version 3 of the License, or |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
10 |
* (at your option) any later version. |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
11 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
12 |
* This program is distributed in the hope that it will be useful, |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
13 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
14 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
15 |
* GNU General Public License for more details. |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
16 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
17 |
* You should have received a copy of the GNU General Public License |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
18 |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
19 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
20 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
21 |
* This code is made available on the understanding that it will not be |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
22 |
* used in safety-critical situations without a full and competent review. |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
23 |
*/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
24 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
25 |
/* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
26 |
* An IEC 61131-3 compiler. |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
27 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
28 |
* Based on the |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
29 |
* FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
30 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
31 |
*/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
32 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
33 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
34 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
35 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
36 |
|
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
37 |
/* Do constant folding... |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
38 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
39 |
* I.e., Determine the value of all expressions in which only constant values (i.e. literals) are used. |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
40 |
* The (constant) result of each operation is stored (annotated) in the respective operation symbol |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
41 |
* (e.g.: add_expression_c) in the abstract syntax tree, |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
42 |
* |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
43 |
* For example: |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
44 |
* 2 + 3 -> the constant value '5' is stored in the add_expression_c symbol. |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
45 |
* 22.2 - 5.0 -> the constant value '17.2' is stored in the add_expression_c symbol. |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
46 |
* etc... |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
47 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
48 |
* |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
49 |
* NOTE 1 |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
50 |
* Some operations and constants can have multiple data types. For example, |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
51 |
* 1 AND 0 |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
52 |
* may be either a BOOL, BYTE, WORD or LWORD. |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
53 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
54 |
* The same happens with |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
55 |
* 1 + 2 |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
56 |
* which may be signed (e.g. INT) or unsigned (UINT) |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
57 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
58 |
* For the above reason, instead of storing a single constant value, we actually store 4: |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
59 |
* - bool |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
60 |
* - uint64 |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
61 |
* - int64 |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
62 |
* - real64 |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
63 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
64 |
* Additionally, since the result of an operation may result in an overflow, we actually |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
65 |
* store the result inside a struct (defined in absyntax.hh) |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
66 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
67 |
* ** During stage 3 (semantic analysis/checking) we will be doing constant folding. |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
68 |
* * That algorithm will anotate the abstract syntax tree with the result of operations |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
69 |
* * on literals (i.e. 44 + 55 will store the result 99). |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
70 |
* * Since the same source code (e.g. 1 + 0) may actually be a BOOL or an ANY_INT, |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
71 |
* * or an ANY_BIT, we need to handle all possibilities, and determine the result of the |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
72 |
* * operation assuming each type. |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
73 |
* * For this reason, we have one entry for each possible type, with some expressions |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
74 |
* * having more than one entry filled in! |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
75 |
* ** |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
76 |
* typedef enum { cs_undefined, // not defined --> const_value is not valid! |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
77 |
* cs_const_value, // const value is valid |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
78 |
* cs_overflow // result produced overflow or underflow --> const_value is not valid! |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
79 |
* } const_status_t; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
80 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
81 |
* typedef struct { |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
82 |
* const_status_t status; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
83 |
* real64_t value; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
84 |
* } const_value_real64_t; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
85 |
* const_value_real64_t *const_value_real64; // when NULL --> UNDEFINED |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
86 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
87 |
* typedef struct { |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
88 |
* const_status_t status; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
89 |
* int64_t value; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
90 |
* } const_value_int64_t; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
91 |
* const_value_int64_t *const_value_int64; // when NULL --> UNDEFINED |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
92 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
93 |
* typedef struct { |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
94 |
* const_status_t status; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
95 |
* uint64_t value; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
96 |
* } const_value_uint64_t; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
97 |
* const_value_uint64_t *const_value_uint64; // when NULL --> UNDEFINED |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
98 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
99 |
* typedef struct { |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
100 |
* const_status_t status; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
101 |
* bool value; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
102 |
* } const_value_bool_t; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
103 |
* const_value_bool_t *const_value_bool; // when NULL --> UNDEFINED |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
104 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
105 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
106 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
107 |
* NOTE 2 |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
108 |
* This file does not print out any error messages! |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
109 |
* We cannot really print out error messages when we find an overflow. Since each operation |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
110 |
* (symbol in the absract syntax tree for that operation) will have up to 4 constant results, |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
111 |
* it may happen that some of them overflow, while other do not. |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
112 |
* We must wait for data type checking to determine the exact data type of each expression |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
113 |
* before we can decide whether or not we should print out an overflow error message. |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
114 |
* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
115 |
* For this reason, this visitor merely annotates the abstract syntax tree, and leaves the |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
116 |
* actuall printing of errors for the print_datatype_errors_c class! |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
117 |
*/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
118 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
119 |
#include "constant_folding.hh" |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
120 |
#include <limits> |
579
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
121 |
#include <math.h> /* required for pow function, and HUGE_VAL, HUGE_VALF, HUGE_VALL */ |
565
8acbddf75333
Fix a few bugs of previous commit.
Mario de Sousa <msousa@fe.up.pt>
parents:
564
diff
changeset
|
122 |
#include <stdlib.h> /* required for malloc() */ |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
123 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
124 |
#define __STDC_LIMIT_MACROS /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
125 |
#include <stdint.h> /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */ |
579
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
126 |
|
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
127 |
|
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
128 |
|
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
129 |
#ifndef UINT64_MAX |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
130 |
#define UINT64_MAX (std::numeric_limits< uint64_t >::max()) |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
131 |
#endif |
579
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
132 |
#ifndef INT64_MAX |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
133 |
#define INT64_MAX (std::numeric_limits< int64_t >::max()) |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
134 |
#endif |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
135 |
#ifndef INT64_MIN |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
136 |
#define INT64_MIN (std::numeric_limits< int64_t >::min()) |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
137 |
#endif |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
138 |
|
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
139 |
#if (real64_t == float) |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
140 |
#define HUGE_VAL64 HUGE_VALF |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
141 |
#elif (real64_t == double) |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
142 |
#define HUGE_VAL64 HUGE_VAL |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
143 |
#elif (real64_t == long_double) |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
144 |
#define HUGE_VAL64 HUGE_VALL |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
145 |
#else |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
146 |
#error Could not determine which data type is being used for real64_t (defined in absyntax.hh). Aborting! |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
147 |
#endif |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
148 |
|
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
149 |
|
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
150 |
|
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
151 |
|
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
152 |
|
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
153 |
|
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
154 |
|
568
5f79478142d7
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents:
567
diff
changeset
|
155 |
|
5f79478142d7
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents:
567
diff
changeset
|
156 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
157 |
#define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order) ? (symbol1) : (symbol2)) |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
158 |
#define LAST_(symbol1, symbol2) (((symbol1)->last_order > (symbol2)->last_order) ? (symbol1) : (symbol2)) |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
159 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
160 |
#define STAGE3_ERROR(error_level, symbol1, symbol2, ...) { \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
161 |
if (current_display_error_level >= error_level) { \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
162 |
fprintf(stderr, "%s:%d-%d..%d-%d: error: ", \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
163 |
FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
164 |
LAST_(symbol1,symbol2) ->last_line, LAST_(symbol1,symbol2) ->last_column);\ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
165 |
fprintf(stderr, __VA_ARGS__); \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
166 |
fprintf(stderr, "\n"); \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
167 |
error_count++; \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
168 |
} \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
169 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
170 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
171 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
172 |
#define STAGE3_WARNING(symbol1, symbol2, ...) { \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
173 |
fprintf(stderr, "%s:%d-%d..%d-%d: warning: ", \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
174 |
FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
175 |
LAST_(symbol1,symbol2) ->last_line, LAST_(symbol1,symbol2) ->last_column);\ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
176 |
fprintf(stderr, __VA_ARGS__); \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
177 |
fprintf(stderr, "\n"); \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
178 |
warning_found = true; \ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
179 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
180 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
181 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
182 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
183 |
|
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
184 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
185 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
186 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
187 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
188 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
189 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
190 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
191 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
192 |
#define NEW_CVALUE(dtype, symbol) \ |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
193 |
(symbol->const_value_##dtype) = new(symbol_c::const_value_##dtype##_t); \ |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
194 |
if ((symbol->const_value_##dtype) == NULL) ERROR; \ |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
195 |
(symbol->const_value_##dtype)->status = symbol_c::cs_undefined; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
196 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
197 |
#define SET_CVALUE(dtype, symbol, new_value) ((symbol)->const_value_##dtype->value) = new_value; ((symbol)->const_value_##dtype->status) = symbol_c::cs_const_value; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
198 |
#define GET_CVALUE(dtype, symbol) ((symbol)->const_value_##dtype->value) |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
199 |
#define SET_OVFLOW(dtype, symbol) ((symbol)->const_value_##dtype->status) = symbol_c::cs_overflow |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
200 |
/* The following test is correct in the presence of a NULL pointer, as the logical evaluation will be suspended as soon as the first condition is false! */ |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
201 |
#define VALID_CVALUE(dtype, symbol) ((NULL != (symbol)->const_value_##dtype) && (symbol_c::cs_const_value == (symbol)->const_value_##dtype->status)) |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
202 |
#define ISZERO_CVALUE(dtype, symbol) ((VALID_CVALUE(dtype, symbol)) && (GET_CVALUE(dtype, symbol) == 0)) |
575 | 203 |
|
577
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
204 |
#define DO_BINARY_OPER(dtype, oper, otype)\ |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
205 |
if (VALID_CVALUE(dtype, symbol->r_exp) && VALID_CVALUE(dtype, symbol->l_exp)) { \ |
578 | 206 |
NEW_CVALUE(otype, symbol); \ |
577
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
207 |
SET_CVALUE(otype, symbol, GET_CVALUE(dtype, symbol->l_exp) oper GET_CVALUE(dtype, symbol->r_exp)); \ |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
208 |
} |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
209 |
|
575 | 210 |
#define DO_UNARY_OPER(dtype, oper, arg)\ |
211 |
if (VALID_CVALUE(dtype, arg)) { \ |
|
212 |
NEW_CVALUE(dtype, symbol); \ |
|
213 |
SET_CVALUE(dtype, symbol, oper GET_CVALUE(dtype, arg)); \ |
|
214 |
} |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
215 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
216 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
217 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
218 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
219 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
220 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
221 |
|
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
222 |
/* NOTE: |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
223 |
* Most of the conditions to detect overflows on signed and unsigned integer operations were adapted from |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
224 |
* https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow?showComments=false |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
225 |
* https://www.securecoding.cert.org/confluence/display/seccode/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
226 |
*/ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
227 |
|
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
228 |
/* NOTE: If at all possible, all overflow tests are done by pre-condition tests, i.e. tests that |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
229 |
* can be run _before_ the operation is executed, and therefore without accessing the result! |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
230 |
* |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
231 |
* The exception is for real/floating point values, that simply test if the result is NaN (not a number). |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
232 |
*/ |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
233 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
234 |
/* res = a + b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
235 |
static void CHECK_OVERFLOW_uint64_SUM(symbol_c *res, symbol_c *a, symbol_c *b) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
236 |
if (!VALID_CVALUE(uint64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
237 |
return; |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
238 |
/* Test by post-condition: If sum is smaller than either operand => overflow! */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
239 |
// if (GET_CVALUE(uint64, res) < GET_CVALUE(uint64, a)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
240 |
/* Test by pre-condition: If (UINT64_MAX - a) < b => overflow! */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
241 |
if ((UINT64_MAX - GET_CVALUE(uint64, a)) < GET_CVALUE(uint64, b)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
242 |
SET_OVFLOW(uint64, res); |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
243 |
} |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
244 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
245 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
246 |
/* res = a - b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
247 |
static void CHECK_OVERFLOW_uint64_SUB(symbol_c *res, symbol_c *a, symbol_c *b) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
248 |
if (!VALID_CVALUE(uint64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
249 |
return; |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
250 |
/* Test by post-condition: If diference is larger than a => overflow! */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
251 |
// if (GET_CVALUE(uint64, res) > GET_CVALUE(uint64, a)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
252 |
/* Test by pre-condition: if b > a => overflow! */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
253 |
if (GET_CVALUE(uint64, b) > GET_CVALUE(uint64, a)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
254 |
SET_OVFLOW(uint64, res); |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
255 |
} |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
256 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
257 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
258 |
/* res = a * b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
259 |
static void CHECK_OVERFLOW_uint64_MUL(symbol_c *res, symbol_c *a, symbol_c *b) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
260 |
if (!VALID_CVALUE(uint64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
261 |
return; |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
262 |
/* Test by pre-condition: If (UINT64_MAX / a) < b => overflow! */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
263 |
if ((UINT64_MAX / GET_CVALUE(uint64, a)) < GET_CVALUE(uint64, b)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
264 |
SET_OVFLOW(uint64, res); |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
265 |
} |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
266 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
267 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
268 |
/* res = a / b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
269 |
static void CHECK_OVERFLOW_uint64_DIV(symbol_c *res, symbol_c *a, symbol_c *b) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
270 |
if (!VALID_CVALUE(uint64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
271 |
return; |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
272 |
if (GET_CVALUE(uint64, b) == 0) /* division by zero! */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
273 |
SET_OVFLOW(uint64, res); |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
274 |
} |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
275 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
276 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
277 |
/* res = a MOD b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
278 |
static void CHECK_OVERFLOW_uint64_MOD(symbol_c *res, symbol_c *a, symbol_c *b) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
279 |
if (!VALID_CVALUE(uint64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
280 |
return; |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
281 |
/* no overflow condition exists, including division by zero, which IEC 61131-3 considers legal for MOD operation! */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
282 |
if (false) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
283 |
SET_OVFLOW(uint64, res); |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
284 |
} |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
285 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
286 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
287 |
/* res = a + b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
288 |
static void CHECK_OVERFLOW_int64_SUM(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
289 |
if (!VALID_CVALUE(int64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
290 |
return; |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
291 |
int64_t a = GET_CVALUE(int64, a_ptr); |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
292 |
int64_t b = GET_CVALUE(int64, b_ptr); |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
293 |
/* The following test is valid no matter what representation is being used (e.g. two's complement, etc...) */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
294 |
if (((b > 0) && (a > (INT64_MAX - b))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
295 |
|| ((b < 0) && (a < (INT64_MIN - b)))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
296 |
SET_OVFLOW(int64, res); |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
297 |
} |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
298 |
|
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
299 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
300 |
/* res = a - b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
301 |
static void CHECK_OVERFLOW_int64_SUB(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
302 |
if (!VALID_CVALUE(int64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
303 |
return; |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
304 |
int64_t a = GET_CVALUE(int64, a_ptr); |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
305 |
int64_t b = GET_CVALUE(int64, b_ptr); |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
306 |
/* The following test is valid no matter what representation is being used (e.g. two's complement, etc...) */ |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
307 |
if (((b > 0) && (a < (INT64_MIN + b))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
308 |
|| ((b < 0) && (a > (INT64_MAX + b)))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
309 |
SET_OVFLOW(int64, res); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
310 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
311 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
312 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
313 |
/* res = a * b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
314 |
static void CHECK_OVERFLOW_int64_MUL(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
315 |
if (!VALID_CVALUE(int64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
316 |
return; |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
317 |
int64_t a = GET_CVALUE(int64, a_ptr); |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
318 |
int64_t b = GET_CVALUE(int64, b_ptr); |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
319 |
if ( ( (a > 0) && (b > 0) && (a > (INT64_MAX / b))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
320 |
|| ( (a > 0) && !(b > 0) && (b < (INT64_MIN / a))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
321 |
|| (!(a > 0) && (b > 0) && (a < (INT64_MIN / b))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
322 |
|| (!(a > 0) && !(b > 0) && (a != 0) && (b < (INT64_MAX / a)))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
323 |
SET_OVFLOW(int64, res); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
324 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
325 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
326 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
327 |
/* res = a / b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
328 |
static void CHECK_OVERFLOW_int64_DIV(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
329 |
if (!VALID_CVALUE(int64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
330 |
return; |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
331 |
int64_t a = GET_CVALUE(int64, a_ptr); |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
332 |
int64_t b = GET_CVALUE(int64, b_ptr); |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
333 |
if ((b == 0) || ((a == INT64_MIN) && (b == -1))) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
334 |
SET_OVFLOW(int64, res); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
335 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
336 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
337 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
338 |
/* res = a MOD b */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
339 |
static void CHECK_OVERFLOW_int64_MOD(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
340 |
if (!VALID_CVALUE(int64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
341 |
return; |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
342 |
int64_t a = GET_CVALUE(int64, a_ptr); |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
343 |
int64_t b = GET_CVALUE(int64, b_ptr); |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
344 |
/* IEC 61131-3 standard says IN1 MOD IN2 must be equivalent to |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
345 |
* IF (IN2 = 0) THEN OUT:=0 ; ELSE OUT:=IN1 - (IN1/IN2)*IN2 ; END_IF |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
346 |
* |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
347 |
* Note that, when IN1 = INT64_MIN, and IN2 = -1, an overflow occurs in the division, |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
348 |
* so although the MOD operation should be OK, acording to the above definition, we actually have an overflow!! |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
349 |
* |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
350 |
* On the other hand, division by 0 is OK!! |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
351 |
*/ |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
352 |
if ((a == INT64_MIN) && (b == -1)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
353 |
SET_OVFLOW(int64, res); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
354 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
355 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
356 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
357 |
/* res = - a */ |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
358 |
static void CHECK_OVERFLOW_int64_NEG(symbol_c *res, symbol_c *a_ptr) { |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
359 |
if (!VALID_CVALUE(int64, res)) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
360 |
return; |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
361 |
int64_t a = GET_CVALUE(int64, a_ptr); |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
362 |
if (a == INT64_MIN) |
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
363 |
SET_OVFLOW(int64, res); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
364 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
365 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
366 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
367 |
|
579
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
368 |
static void CHECK_OVERFLOW_real64(symbol_c *res_ptr) { |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
369 |
if (!VALID_CVALUE(real64, res_ptr)) |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
370 |
return; |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
371 |
real64_t res = GET_CVALUE(real64, res_ptr); |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
372 |
/* NaN => underflow, overflow, number is a higher precision format, is a complex number (IEEE standard) */ |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
373 |
/* The IEC 61131-3 clearly states in section '2.5.1.5.2 Numerical functions': |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
374 |
* "It is an error if the result of evaluation of one of these [numerical] functions exceeds the range of values |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
375 |
* specified for the data type of the function output, or if division by zero is attempted." |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
376 |
* For this reason, any operation that has as a result a positive or negative inifinity, is also an error! |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
377 |
*/ |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
378 |
if ((isnan(res)) || (res == HUGE_VAL64) || (res == -HUGE_VAL64)) |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
379 |
SET_OVFLOW(real64, res_ptr); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
380 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
381 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
382 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
383 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
384 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
385 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
386 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
387 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
388 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
389 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
390 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
391 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
392 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
393 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
394 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
395 |
constant_folding_c::constant_folding_c(symbol_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
396 |
error_count = 0; |
568
5f79478142d7
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents:
567
diff
changeset
|
397 |
warning_found = false; |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
398 |
current_display_error_level = 0; |
568
5f79478142d7
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents:
567
diff
changeset
|
399 |
|
5f79478142d7
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents:
567
diff
changeset
|
400 |
/* check whether the platform on which the compiler is being run implements IEC 559 floating point data types. */ |
5f79478142d7
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents:
567
diff
changeset
|
401 |
symbol_c null_symbol; |
5f79478142d7
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents:
567
diff
changeset
|
402 |
if (! (std::numeric_limits<real64_t>::is_iec559) ) |
579
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
403 |
STAGE3_WARNING(&null_symbol, &null_symbol, "The platform running the compiler does not implement IEC 60559 floating point numbers. " |
568
5f79478142d7
make the compiler platform independent (i.e. no longer assume sizeof(double)==8).
Mario de Sousa <msousa@fe.up.pt>
parents:
567
diff
changeset
|
404 |
"Any error and/or warning messages related to overflow/underflow of the result of operations on REAL/LREAL literals " |
579
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
405 |
"(i.e. constant folding) may themselves be erroneous, although are most probably correct." |
983a3b743085
Fix 'overflow' detection for real64.
Mario de Sousa <msousa@fe.up.pt>
parents:
578
diff
changeset
|
406 |
"However, more likely is the possible existance of overflow/underflow errors that are not detected."); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
407 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
408 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
409 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
410 |
constant_folding_c::~constant_folding_c(void) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
411 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
412 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
413 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
414 |
int constant_folding_c::get_error_count() { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
415 |
return error_count; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
416 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
417 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
418 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
419 |
/*********************/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
420 |
/* B 1.2 - Constants */ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
421 |
/*********************/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
422 |
/******************************/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
423 |
/* B 1.2.1 - Numeric Literals */ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
424 |
/******************************/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
425 |
void *constant_folding_c::visit(real_c *symbol) { |
576
8368ec909825
Fix extract_real (thanks Manuele), and add check for overflow.
Mario de Sousa <msousa@fe.up.pt>
parents:
575
diff
changeset
|
426 |
bool overflow; |
8368ec909825
Fix extract_real (thanks Manuele), and add check for overflow.
Mario de Sousa <msousa@fe.up.pt>
parents:
575
diff
changeset
|
427 |
NEW_CVALUE(real64, symbol); SET_CVALUE(real64, symbol, extract_real_value(symbol, &overflow)); |
8368ec909825
Fix extract_real (thanks Manuele), and add check for overflow.
Mario de Sousa <msousa@fe.up.pt>
parents:
575
diff
changeset
|
428 |
if (overflow) SET_OVFLOW(real64, symbol); |
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
429 |
return NULL; |
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
430 |
} |
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
431 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
432 |
|
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
433 |
void *constant_folding_c::visit(integer_c *symbol) { |
575 | 434 |
NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_integer_value(symbol)); |
435 |
NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_integer_value(symbol)); |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
436 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
437 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
438 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
439 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
440 |
void *constant_folding_c::visit(neg_real_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
441 |
symbol->exp->accept(*this); |
575 | 442 |
DO_UNARY_OPER(real64, -, symbol->exp); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
443 |
CHECK_OVERFLOW_real64(symbol); |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
444 |
return NULL; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
445 |
} |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
446 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
447 |
/* | '-' integer {$$ = new neg_integer_c($2, locloc(@$));} */ |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
448 |
void *constant_folding_c::visit(neg_integer_c *symbol) { |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
449 |
symbol->exp->accept(*this); |
575 | 450 |
DO_UNARY_OPER(int64, -, symbol->exp); |
574
d291a942899b
Fix remaining overflow checks.
Mario de Sousa <msousa@fe.up.pt>
parents:
573
diff
changeset
|
451 |
CHECK_OVERFLOW_int64_NEG(symbol, symbol->exp); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
452 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
453 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
454 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
455 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
456 |
void *constant_folding_c::visit(binary_integer_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
457 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
458 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
459 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
460 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
461 |
void *constant_folding_c::visit(octal_integer_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
462 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
463 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
464 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
465 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
466 |
void *constant_folding_c::visit(hex_integer_c *symbol) { |
575 | 467 |
NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, extract_hex_value(symbol)); |
468 |
NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, extract_hex_value(symbol)); |
|
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
469 |
return NULL; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
470 |
} |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
471 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
472 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
473 |
/* |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
474 |
integer_literal: |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
475 |
integer_type_name '#' signed_integer {$$ = new integer_literal_c($1, $3, locloc(@$));} |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
476 |
| integer_type_name '#' binary_integer {$$ = new integer_literal_c($1, $3, locloc(@$));} |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
477 |
| integer_type_name '#' octal_integer {$$ = new integer_literal_c($1, $3, locloc(@$));} |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
478 |
| integer_type_name '#' hex_integer {$$ = new integer_literal_c($1, $3, locloc(@$));} |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
479 |
*/ |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
480 |
// SYM_REF2(integer_literal_c, type, value) |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
481 |
void *constant_folding_c::visit(integer_literal_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
482 |
symbol->value->accept(*this); |
575 | 483 |
DO_UNARY_OPER( int64, /* none */, symbol->value); |
484 |
DO_UNARY_OPER(uint64, /* none */, symbol->value); |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
485 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
486 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
487 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
488 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
489 |
void *constant_folding_c::visit(real_literal_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
490 |
symbol->value->accept(*this); |
575 | 491 |
DO_UNARY_OPER(real64, /* none */, symbol->value); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
492 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
493 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
494 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
495 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
496 |
void *constant_folding_c::visit(bit_string_literal_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
497 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
498 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
499 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
500 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
501 |
void *constant_folding_c::visit(boolean_literal_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
502 |
symbol->value->accept(*this); |
575 | 503 |
DO_UNARY_OPER(bool, /* none */, symbol->value); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
504 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
505 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
506 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
507 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
508 |
void *constant_folding_c::visit(boolean_true_c *symbol) { |
575 | 509 |
NEW_CVALUE(bool, symbol); SET_CVALUE(bool, symbol, true); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
510 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
511 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
512 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
513 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
514 |
void *constant_folding_c::visit(boolean_false_c *symbol) { |
575 | 515 |
NEW_CVALUE(bool, symbol); SET_CVALUE(bool, symbol, false); |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
516 |
return NULL; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
517 |
} |
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
518 |
|
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
519 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
520 |
/***************************************/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
521 |
/* B.3 - Language ST (Structured Text) */ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
522 |
/***************************************/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
523 |
/***********************/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
524 |
/* B 3.1 - Expressions */ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
525 |
/***********************/ |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
526 |
void *constant_folding_c::visit(or_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
527 |
symbol->l_exp->accept(*this); |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
528 |
symbol->r_exp->accept(*this); |
577
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
529 |
DO_BINARY_OPER( bool, ||, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
530 |
DO_BINARY_OPER(uint64, | , bool); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
531 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
532 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
533 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
534 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
535 |
void *constant_folding_c::visit(xor_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
536 |
symbol->l_exp->accept(*this); |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
537 |
symbol->r_exp->accept(*this); |
577
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
538 |
DO_BINARY_OPER( bool, ^, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
539 |
DO_BINARY_OPER(uint64, ^, uint64); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
540 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
541 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
542 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
543 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
544 |
void *constant_folding_c::visit(and_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
545 |
symbol->l_exp->accept(*this); |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
546 |
symbol->r_exp->accept(*this); |
577
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
547 |
DO_BINARY_OPER( bool, &&, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
548 |
DO_BINARY_OPER(uint64, & , uint64); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
549 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
550 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
551 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
552 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
553 |
void *constant_folding_c::visit(equ_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
554 |
symbol->l_exp->accept(*this); |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
555 |
symbol->r_exp->accept(*this); |
577
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
556 |
DO_BINARY_OPER( bool, ==, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
557 |
DO_BINARY_OPER(uint64, ==, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
558 |
DO_BINARY_OPER( int64, ==, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
559 |
DO_BINARY_OPER(real64, ==, bool); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
560 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
561 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
562 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
563 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
564 |
void *constant_folding_c::visit(notequ_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
565 |
symbol->l_exp->accept(*this); |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
566 |
symbol->r_exp->accept(*this); |
577
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
567 |
DO_BINARY_OPER( bool, !=, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
568 |
DO_BINARY_OPER(uint64, !=, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
569 |
DO_BINARY_OPER( int64, !=, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
570 |
DO_BINARY_OPER(real64, !=, bool); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
571 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
572 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
573 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
574 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
575 |
void *constant_folding_c::visit(lt_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
576 |
symbol->l_exp->accept(*this); |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
577 |
symbol->r_exp->accept(*this); |
577
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
578 |
DO_BINARY_OPER( bool, <, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
579 |
DO_BINARY_OPER(uint64, <, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
580 |
DO_BINARY_OPER( int64, <, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
581 |
DO_BINARY_OPER(real64, <, bool); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
582 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
583 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
584 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
585 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
586 |
void *constant_folding_c::visit(gt_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
587 |
symbol->l_exp->accept(*this); |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
588 |
symbol->r_exp->accept(*this); |
577
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
589 |
DO_BINARY_OPER( bool, >, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
590 |
DO_BINARY_OPER(uint64, >, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
591 |
DO_BINARY_OPER( int64, >, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
592 |
DO_BINARY_OPER(real64, >, bool); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
593 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
594 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
595 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
596 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
597 |
void *constant_folding_c::visit(le_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
598 |
symbol->l_exp->accept(*this); |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
599 |
symbol->r_exp->accept(*this); |
577
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
600 |
DO_BINARY_OPER( bool, <=, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
601 |
DO_BINARY_OPER(uint64, <=, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
602 |
DO_BINARY_OPER( int64, <=, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
603 |
DO_BINARY_OPER(real64, <=, bool); |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
604 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
605 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
606 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
607 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
608 |
void *constant_folding_c::visit(ge_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
609 |
symbol->l_exp->accept(*this); |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
610 |
symbol->r_exp->accept(*this); |
577
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
611 |
DO_BINARY_OPER( bool, >=, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
612 |
DO_BINARY_OPER(uint64, >=, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
613 |
DO_BINARY_OPER( int64, >=, bool); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
614 |
DO_BINARY_OPER(real64, >=, bool); |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
615 |
return NULL; |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
616 |
} |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
617 |
|
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
618 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
619 |
void *constant_folding_c::visit(add_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
620 |
symbol->l_exp->accept(*this); |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
621 |
symbol->r_exp->accept(*this); |
577
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
622 |
DO_BINARY_OPER(uint64, +, uint64); CHECK_OVERFLOW_uint64_SUM(symbol, symbol->l_exp, symbol->r_exp); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
623 |
DO_BINARY_OPER( int64, +, int64); CHECK_OVERFLOW_int64_SUM (symbol, symbol->l_exp, symbol->r_exp); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
624 |
DO_BINARY_OPER(real64, +, real64); CHECK_OVERFLOW_real64 (symbol); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
625 |
return NULL; |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
626 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
627 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
628 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
629 |
void *constant_folding_c::visit(sub_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
630 |
symbol->l_exp->accept(*this); |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
631 |
symbol->r_exp->accept(*this); |
577
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
632 |
DO_BINARY_OPER(uint64, -, uint64); CHECK_OVERFLOW_uint64_SUB(symbol, symbol->l_exp, symbol->r_exp); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
633 |
DO_BINARY_OPER( int64, -, int64); CHECK_OVERFLOW_int64_SUB (symbol, symbol->l_exp, symbol->r_exp); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
634 |
DO_BINARY_OPER(real64, -, real64); CHECK_OVERFLOW_real64 (symbol); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
635 |
return NULL; |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
636 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
637 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
638 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
639 |
void *constant_folding_c::visit(mul_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
640 |
symbol->l_exp->accept(*this); |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
641 |
symbol->r_exp->accept(*this); |
577
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
642 |
DO_BINARY_OPER(uint64, *, uint64); CHECK_OVERFLOW_uint64_MUL(symbol, symbol->l_exp, symbol->r_exp); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
643 |
DO_BINARY_OPER( int64, *, int64); CHECK_OVERFLOW_int64_MUL (symbol, symbol->l_exp, symbol->r_exp); |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
644 |
DO_BINARY_OPER(real64, *, real64); CHECK_OVERFLOW_real64 (symbol); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
645 |
return NULL; |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
646 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
647 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
648 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
649 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
650 |
void *constant_folding_c::visit(div_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
651 |
symbol->l_exp->accept(*this); |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
652 |
symbol->r_exp->accept(*this); |
577
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
653 |
if (ISZERO_CVALUE(uint64, symbol->r_exp)) {NEW_CVALUE(uint64, symbol); SET_OVFLOW(uint64, symbol);} else {DO_BINARY_OPER(uint64, /, uint64); CHECK_OVERFLOW_uint64_DIV(symbol, symbol->l_exp, symbol->r_exp);}; |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
654 |
if (ISZERO_CVALUE( int64, symbol->r_exp)) {NEW_CVALUE( int64, symbol); SET_OVFLOW( int64, symbol);} else {DO_BINARY_OPER( int64, /, int64); CHECK_OVERFLOW_int64_DIV(symbol, symbol->l_exp, symbol->r_exp);}; |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
655 |
if (ISZERO_CVALUE(real64, symbol->r_exp)) {NEW_CVALUE(real64, symbol); SET_OVFLOW(real64, symbol);} else {DO_BINARY_OPER(real64, /, real64); CHECK_OVERFLOW_real64(symbol);}; |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
656 |
return NULL; |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
657 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
658 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
659 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
660 |
void *constant_folding_c::visit(mod_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
661 |
symbol->l_exp->accept(*this); |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
662 |
symbol->r_exp->accept(*this); |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
663 |
/* IEC 61131-3 standard says IN1 MOD IN2 must be equivalent to |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
664 |
* IF (IN2 = 0) THEN OUT:=0 ; ELSE OUT:=IN1 - (IN1/IN2)*IN2 ; END_IF |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
665 |
* |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
666 |
* Note that, when IN1 = INT64_MIN, and IN2 = -1, an overflow occurs in the division, |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
667 |
* so although the MOD operation should be OK, acording to the above definition, we actually have an overflow!! |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
668 |
*/ |
577
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
669 |
if (ISZERO_CVALUE(uint64, symbol->r_exp)) {NEW_CVALUE(uint64, symbol); SET_CVALUE(uint64, symbol, 0);} else {DO_BINARY_OPER(uint64, %, uint64); CHECK_OVERFLOW_uint64_MOD(symbol, symbol->l_exp, symbol->r_exp);}; |
f578f14cb97f
Fix compare expression in constat folding class.
Manuele Conti <conti.ma@alice.it>
parents:
576
diff
changeset
|
670 |
if (ISZERO_CVALUE( int64, symbol->r_exp)) {NEW_CVALUE( int64, symbol); SET_CVALUE( int64, symbol, 0);} else {DO_BINARY_OPER( int64, %, int64); CHECK_OVERFLOW_int64_MOD(symbol, symbol->l_exp, symbol->r_exp);}; |
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
671 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
672 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
673 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
674 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
675 |
void *constant_folding_c::visit(power_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
676 |
symbol->l_exp->accept(*this); |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
677 |
symbol->r_exp->accept(*this); |
569
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
678 |
/* NOTE: If the const_value in symbol->r_exp is within the limits of both int64 and uint64, then we do both operations. |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
679 |
* That is OK, as the result should be identicial (we do create an unnecessary CVALUE variable, but who cares?). |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
680 |
* If only one is valid, then that is the oper we will do! |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
681 |
*/ |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
682 |
if (VALID_CVALUE(real64, symbol->l_exp) && VALID_CVALUE( int64, symbol->r_exp)) { |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
683 |
NEW_CVALUE(real64, symbol); |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
684 |
SET_CVALUE(real64, symbol, pow(GET_CVALUE(real64, symbol->l_exp), GET_CVALUE( int64, symbol->r_exp))); |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
685 |
} |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
686 |
if (VALID_CVALUE(real64, symbol->l_exp) && VALID_CVALUE(uint64, symbol->r_exp)) { |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
687 |
NEW_CVALUE(real64, symbol); |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
688 |
SET_CVALUE(real64, symbol, pow(GET_CVALUE(real64, symbol->l_exp), GET_CVALUE(uint64, symbol->r_exp))); |
0d1ab9e78574
Add data structure for storing overflow of constant values.
Mario de Sousa <msousa@fe.up.pt>
parents:
568
diff
changeset
|
689 |
} |
572
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
690 |
CHECK_OVERFLOW_real64(symbol); |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
691 |
return NULL; |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
692 |
} |
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
693 |
|
c353bc67bf91
Correctly implement MOD operation and overflow checks (still missing uint * / MOD).
Mario de Sousa <msousa@fe.up.pt>
parents:
570
diff
changeset
|
694 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
695 |
void *constant_folding_c::visit(neg_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
696 |
symbol->exp->accept(*this); |
575 | 697 |
DO_UNARY_OPER( int64, -, symbol->exp); CHECK_OVERFLOW_int64_NEG(symbol, symbol->exp); |
698 |
DO_UNARY_OPER(real64, -, symbol->exp); CHECK_OVERFLOW_real64(symbol); |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
699 |
return NULL; |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
700 |
} |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
701 |
|
567
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
702 |
|
e5deeb6d4d2f
create extract_real_value() in absyntax_utils. NOTE: overflows not yet handled!
Mario de Sousa <msousa@fe.up.pt>
parents:
566
diff
changeset
|
703 |
|
564
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
704 |
void *constant_folding_c::visit(not_expression_c *symbol) { |
dabffc3086dc
Start constant_folding class.
Manuele Conti <conti.ma@alice.it>
parents:
diff
changeset
|
705 |
symbol->exp->accept(*this); |
575 | 706 |
DO_UNARY_OPER( bool, !, symbol->exp); |
707 |
DO_UNARY_OPER(uint64, ~, symbol->exp); |
|
708 |
return NULL; |
|
709 |
} |
|
710 |
||
711 |