@@ -228,3 +228,80 @@ exprt verilog_non_indexed_part_select_exprt::lower() const
228
228
{
229
229
return ::lower (*this );
230
230
}
231
+
232
+ static exprt
233
+ lower (const verilog_indexed_part_select_plus_or_minus_exprt &part_select)
234
+ {
235
+ auto get_width = [](const typet &t) -> mp_integer
236
+ {
237
+ if (t.id () == ID_bool)
238
+ return 1 ;
239
+
240
+ if (
241
+ t.id () == ID_unsignedbv || t.id () == ID_signedbv ||
242
+ t.id () == ID_verilog_signedbv || t.id () == ID_verilog_unsignedbv)
243
+ {
244
+ return to_bitvector_type (t).get_width ();
245
+ }
246
+
247
+ PRECONDITION (false );
248
+ };
249
+
250
+ PRECONDITION (
251
+ part_select.id () == ID_verilog_indexed_part_select_plus ||
252
+ part_select.id () == ID_verilog_indexed_part_select_minus);
253
+
254
+ const exprt &src = part_select.src ();
255
+
256
+ mp_integer src_width = get_width (src.type ());
257
+ mp_integer src_offset = string2integer (src.type ().get_string (ID_C_offset));
258
+
259
+ // The width of the indexed part select must be an
260
+ // elaboration-time constant.
261
+ auto width =
262
+ numeric_cast_v<mp_integer>(to_constant_expr (part_select.width ()));
263
+
264
+ // The index need not be a constant.
265
+ const exprt &index = part_select.index ();
266
+
267
+ if (index .is_constant ())
268
+ {
269
+ auto index_int = numeric_cast_v<mp_integer>(to_constant_expr (index ));
270
+
271
+ // Construct the extractbits expression
272
+ mp_integer bottom;
273
+
274
+ if (part_select.id () == ID_verilog_indexed_part_select_plus)
275
+ {
276
+ bottom = index_int - src_offset;
277
+ }
278
+ else // ID_verilog_indexed_part_select_minus
279
+ {
280
+ bottom = bottom - width + 1 ;
281
+ }
282
+
283
+ return extractbits_exprt{
284
+ std::move (src), from_integer (bottom, integer_typet{}), part_select.type ()}
285
+ .with_source_location (part_select);
286
+ }
287
+ else
288
+ {
289
+ // Index not constant.
290
+ // Use logical right-shift followed by (constant) extractbits.
291
+ auto index_adjusted =
292
+ minus_exprt{index , from_integer (src_offset, index .type ())};
293
+
294
+ auto src_shifted = lshr_exprt (src, index_adjusted);
295
+
296
+ return extractbits_exprt{
297
+ std::move (src_shifted),
298
+ from_integer (0 , integer_typet{}),
299
+ part_select.type ()}
300
+ .with_source_location (part_select);
301
+ }
302
+ }
303
+
304
+ exprt verilog_indexed_part_select_plus_or_minus_exprt::lower () const
305
+ {
306
+ return ::lower (*this );
307
+ }
0 commit comments