|
18 | 18 | #include "expr_util.h" |
19 | 19 | #include "fixedbv.h" |
20 | 20 | #include "ieee_float.h" |
| 21 | +#include "invariant.h" |
21 | 22 | #include "namespace.h" |
| 23 | +#include "pointer_offset_size.h" |
22 | 24 | #include "rational.h" |
23 | 25 | #include "rational_tools.h" |
24 | 26 | #include "std_expr.h" |
@@ -1101,45 +1103,47 @@ bool simplify_exprt::simplify_power(exprt &expr) |
1101 | 1103 | } |
1102 | 1104 |
|
1103 | 1105 | /// Simplifies extracting of bits from a constant. |
1104 | | -bool simplify_exprt::simplify_extractbits(exprt &expr) |
| 1106 | +bool simplify_exprt::simplify_extractbits(extractbits_exprt &expr) |
1105 | 1107 | { |
1106 | | - assert(expr.operands().size()==3); |
1107 | | - |
1108 | | - const typet &op0_type=expr.op0().type(); |
| 1108 | + const typet &op0_type = expr.src().type(); |
1109 | 1109 |
|
1110 | 1110 | if(!is_bitvector_type(op0_type) && |
1111 | 1111 | !is_bitvector_type(expr.type())) |
1112 | 1112 | return true; |
1113 | 1113 |
|
1114 | | - if(expr.op0().is_constant()) |
1115 | | - { |
1116 | | - std::size_t width=to_bitvector_type(op0_type).get_width(); |
1117 | | - mp_integer start, end; |
| 1114 | + mp_integer start, end; |
1118 | 1115 |
|
1119 | | - if(to_integer(expr.op1(), start)) |
1120 | | - return true; |
| 1116 | + if(to_integer(expr.upper(), start)) |
| 1117 | + return true; |
1121 | 1118 |
|
1122 | | - if(to_integer(expr.op2(), end)) |
1123 | | - return true; |
| 1119 | + if(to_integer(expr.lower(), end)) |
| 1120 | + return true; |
1124 | 1121 |
|
1125 | | - if(start<0 || start>=width || |
1126 | | - end<0 || end>=width) |
1127 | | - return true; |
| 1122 | + const mp_integer width = pointer_offset_bits(op0_type, ns); |
1128 | 1123 |
|
1129 | | - assert(start>=end); // is this always the case?? |
| 1124 | + if(start < 0 || start >= width || end < 0 || end >= width) |
| 1125 | + return true; |
1130 | 1126 |
|
1131 | | - const irep_idt &value=expr.op0().get(ID_value); |
| 1127 | + DATA_INVARIANT( |
| 1128 | + start >= end, |
| 1129 | + "extractbits must have upper() >= lower()"); |
| 1130 | + |
| 1131 | + if(expr.src().is_constant()) |
| 1132 | + { |
| 1133 | + const irep_idt &value = to_constant_expr(expr.src()).get_value(); |
1132 | 1134 |
|
1133 | 1135 | if(value.size()!=width) |
1134 | 1136 | return true; |
1135 | 1137 |
|
1136 | 1138 | std::string svalue=id2string(value); |
1137 | 1139 |
|
1138 | | - std::string extracted_value= |
1139 | | - svalue.substr(width-integer2size_t(start)-1, |
1140 | | - integer2size_t(start-end+1)); |
| 1140 | + std::string extracted_value = |
| 1141 | + svalue.substr( |
| 1142 | + integer2size_t(width - start - 1), |
| 1143 | + integer2size_t(start - end + 1)); |
1141 | 1144 |
|
1142 | | - expr = constant_exprt(extracted_value, expr.type()); |
| 1145 | + constant_exprt result(extracted_value, expr.type()); |
| 1146 | + expr.swap(result); |
1143 | 1147 |
|
1144 | 1148 | return false; |
1145 | 1149 | } |
|
0 commit comments