@@ -2136,10 +2136,30 @@ static exprt lower_byte_update(
2136
2136
instantiate_byte_array (value_as_byte_array, 0 , (type_bits + 7 ) / 8 , ns);
2137
2137
}
2138
2138
2139
+ const std::size_t update_size_bits = update_bytes.size () * 8 ;
2140
+ const std::size_t bit_width = std::max (type_bits, update_size_bits);
2141
+
2142
+ const bool is_little_endian = src.id () == ID_byte_update_little_endian;
2143
+
2144
+ exprt val_before =
2145
+ typecast_exprt::conditional_cast (src.op (), bv_typet{type_bits});
2146
+ if (bit_width > type_bits)
2147
+ {
2148
+ val_before =
2149
+ concatenation_exprt{from_integer (0 , bv_typet{bit_width - type_bits}),
2150
+ val_before,
2151
+ bv_typet{bit_width}};
2152
+
2153
+ if (!is_little_endian)
2154
+ to_concatenation_expr (val_before)
2155
+ .op0 ()
2156
+ .swap (to_concatenation_expr (val_before).op1 ());
2157
+ }
2158
+
2139
2159
if (non_const_update_bound.has_value ())
2140
2160
{
2141
2161
const exprt src_as_bytes = unpack_rec (
2142
- src. op () ,
2162
+ val_before ,
2143
2163
src.id () == ID_byte_update_little_endian,
2144
2164
mp_integer{0 },
2145
2165
mp_integer{update_bytes.size ()},
@@ -2158,19 +2178,15 @@ static exprt lower_byte_update(
2158
2178
}
2159
2179
}
2160
2180
2161
- const std::size_t update_size = update_bytes.size ();
2162
- const std::size_t width = std::max (type_bits, update_size * 8 );
2163
-
2164
- const bool is_little_endian = src.id () == ID_byte_update_little_endian;
2165
-
2166
2181
// build mask
2167
2182
exprt mask;
2168
2183
if (is_little_endian)
2169
- mask = from_integer (power (2 , update_size * 8 ) - 1 , bv_typet{width });
2184
+ mask = from_integer (power (2 , update_size_bits ) - 1 , bv_typet{bit_width });
2170
2185
else
2171
2186
{
2172
2187
mask = from_integer (
2173
- power (2 , width) - power (2 , width - update_size * 8 ), bv_typet{width});
2188
+ power (2 , bit_width) - power (2 , bit_width - update_size_bits),
2189
+ bv_typet{bit_width});
2174
2190
}
2175
2191
2176
2192
const typet &offset_type = src.offset ().type ();
@@ -2186,34 +2202,20 @@ static exprt lower_byte_update(
2186
2202
mask_shifted.true_case ().swap (mask_shifted.false_case ());
2187
2203
2188
2204
// original_bits &= ~mask
2189
- exprt val_before =
2190
- typecast_exprt::conditional_cast (src.op (), bv_typet{type_bits});
2191
- if (width > type_bits)
2192
- {
2193
- val_before =
2194
- concatenation_exprt{from_integer (0 , bv_typet{width - type_bits}),
2195
- val_before,
2196
- bv_typet{width}};
2197
-
2198
- if (!is_little_endian)
2199
- to_concatenation_expr (val_before)
2200
- .op0 ()
2201
- .swap (to_concatenation_expr (val_before).op1 ());
2202
- }
2203
2205
bitand_exprt bitand_expr{val_before, bitnot_exprt{mask_shifted}};
2204
2206
2205
2207
// concatenate and zero-extend the value
2206
- concatenation_exprt value{update_bytes, bv_typet{update_size * 8 }};
2208
+ concatenation_exprt value{update_bytes, bv_typet{update_size_bits }};
2207
2209
if (is_little_endian)
2208
2210
std::reverse (value.operands ().begin (), value.operands ().end ());
2209
2211
2210
2212
exprt zero_extended;
2211
- if (width > update_size * 8 )
2213
+ if (bit_width > update_size_bits )
2212
2214
{
2213
- zero_extended =
2214
- concatenation_exprt{ from_integer (0 , bv_typet{width - update_size * 8 }),
2215
- value,
2216
- bv_typet{width }};
2215
+ zero_extended = concatenation_exprt{
2216
+ from_integer (0 , bv_typet{bit_width - update_size_bits }),
2217
+ value,
2218
+ bv_typet{bit_width }};
2217
2219
2218
2220
if (!is_little_endian)
2219
2221
to_concatenation_expr (zero_extended)
@@ -2233,12 +2235,22 @@ static exprt lower_byte_update(
2233
2235
// original_bits |= newvalue
2234
2236
bitor_exprt bitor_expr{bitand_expr, value_shifted};
2235
2237
2236
- if (!is_little_endian && width > type_bits)
2238
+ if (!is_little_endian && bit_width > type_bits)
2239
+ {
2240
+ return simplify_expr (
2241
+ typecast_exprt::conditional_cast (
2242
+ extractbits_exprt{bitor_expr,
2243
+ bit_width - 1 ,
2244
+ bit_width - type_bits,
2245
+ bv_typet{type_bits}},
2246
+ src.type ()),
2247
+ ns);
2248
+ }
2249
+ else if (bit_width > type_bits)
2237
2250
{
2238
2251
return simplify_expr (
2239
2252
typecast_exprt::conditional_cast (
2240
- extractbits_exprt{
2241
- bitor_expr, width - 1 , width - type_bits, bv_typet{type_bits}},
2253
+ extractbits_exprt{bitor_expr, type_bits - 1 , 0 , bv_typet{type_bits}},
2242
2254
src.type ()),
2243
2255
ns);
2244
2256
}
0 commit comments