@@ -168,3 +168,80 @@ exprt verilog_non_indexed_part_select_exprt::lower() const
168
168
{
169
169
return ::lower (*this );
170
170
}
171
+
172
+ static exprt
173
+ lower (const verilog_indexed_part_select_plus_or_minus_exprt &part_select)
174
+ {
175
+ auto get_width = [](const typet &t) -> mp_integer
176
+ {
177
+ if (t.id () == ID_bool)
178
+ return 1 ;
179
+
180
+ if (
181
+ t.id () == ID_unsignedbv || t.id () == ID_signedbv ||
182
+ t.id () == ID_verilog_signedbv || t.id () == ID_verilog_unsignedbv)
183
+ {
184
+ return to_bitvector_type (t).get_width ();
185
+ }
186
+
187
+ PRECONDITION (false );
188
+ };
189
+
190
+ PRECONDITION (
191
+ part_select.id () == ID_verilog_indexed_part_select_plus ||
192
+ part_select.id () == ID_verilog_indexed_part_select_minus);
193
+
194
+ const exprt &src = part_select.src ();
195
+
196
+ mp_integer src_width = get_width (src.type ());
197
+ mp_integer src_offset = string2integer (src.type ().get_string (ID_C_offset));
198
+
199
+ // The width of the indexed part select must be an
200
+ // elaboration-time constant.
201
+ auto width =
202
+ numeric_cast_v<mp_integer>(to_constant_expr (part_select.width ()));
203
+
204
+ // The index need not be a constant.
205
+ const exprt &index = part_select.index ();
206
+
207
+ if (index .is_constant ())
208
+ {
209
+ auto index_int = numeric_cast_v<mp_integer>(to_constant_expr (index ));
210
+
211
+ // Construct the extractbits expression
212
+ mp_integer bottom;
213
+
214
+ if (part_select.id () == ID_verilog_indexed_part_select_plus)
215
+ {
216
+ bottom = index_int - src_offset;
217
+ }
218
+ else // ID_verilog_indexed_part_select_minus
219
+ {
220
+ bottom = bottom - width + 1 ;
221
+ }
222
+
223
+ return extractbits_exprt{
224
+ std::move (src), from_integer (bottom, integer_typet{}), part_select.type ()}
225
+ .with_source_location (part_select);
226
+ }
227
+ else
228
+ {
229
+ // Index not constant.
230
+ // Use logical right-shift followed by (constant) extractbits.
231
+ auto index_adjusted =
232
+ minus_exprt{index , from_integer (src_offset, index .type ())};
233
+
234
+ auto src_shifted = lshr_exprt (src, index_adjusted);
235
+
236
+ return extractbits_exprt{
237
+ std::move (src_shifted),
238
+ from_integer (0 , integer_typet{}),
239
+ part_select.type ()}
240
+ .with_source_location (part_select);
241
+ }
242
+ }
243
+
244
+ exprt verilog_indexed_part_select_plus_or_minus_exprt::lower () const
245
+ {
246
+ return ::lower (*this );
247
+ }
0 commit comments