|
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