@@ -18,7 +18,9 @@ Author: Daniel Kroening, kroening@kroening.com
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,48 +1103,76 @@ 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);
1123
+
1124
+ if (start < 0 || start >= width || end < 0 || end >= width)
1125
+ return true ;
1128
1126
1129
- assert (start>=end); // is this always the case??
1127
+ DATA_INVARIANT (
1128
+ start >= end,
1129
+ " extractbits must have upper() >= lower()" );
1130
1130
1131
- const irep_idt &value=expr.op0 ().get (ID_value);
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
}
1150
+ else if (expr.src ().id () == ID_concatenation)
1151
+ {
1152
+ // the most-significant bit comes first in an concatenation_exprt, hence we
1153
+ // count down
1154
+ mp_integer offset = width;
1155
+
1156
+ forall_operands (it, expr.src ())
1157
+ {
1158
+ mp_integer op_width = pointer_offset_bits (it->type (), ns);
1159
+
1160
+ if (op_width <= 0 )
1161
+ return true ;
1162
+
1163
+ if (start + 1 == offset && end + op_width == offset)
1164
+ {
1165
+ exprt tmp = *it;
1166
+ if (tmp.type () != expr.type ())
1167
+ return true ;
1168
+
1169
+ expr.swap (tmp);
1170
+ return false ;
1171
+ }
1172
+
1173
+ offset -= op_width;
1174
+ }
1175
+ }
1146
1176
1147
1177
return true ;
1148
1178
}
0 commit comments