@@ -188,22 +188,45 @@ exprt aval_bval_conversion(const exprt &src, const typet &dest)
188188
189189 if (is_aval_bval (src.type ()))
190190 {
191+ // four-valued to four-valued
191192 auto src_width = aval_bval_width (src.type ());
192193
193194 if (src_width == dest_width)
194195 {
195196 // same size
196197 return typecast_exprt{src, dest};
197198 }
198- else
199+ else if (src_width > dest_width)
199200 {
201+ // shrink
200202 auto new_aval = adjust_size (aval (src), dest_width);
201203 auto new_bval = adjust_size (bval (src), dest_width);
202204 return combine_aval_bval (new_aval, new_bval, dest);
203205 }
206+ else
207+ {
208+ // extend
209+ auto underlying_src = aval_bval_underlying (src.type ());
210+ auto underlying_dest = aval_bval_underlying (dest);
211+
212+ if (underlying_src.id () == ID_signedbv)
213+ {
214+ // sign extend both aval and bval
215+ auto new_aval = typecast_exprt{typecast_exprt{typecast_exprt{aval (src), underlying_src}, underlying_dest}, bv_typet{dest_width}};
216+ auto new_bval = typecast_exprt{typecast_exprt{typecast_exprt{bval (src), underlying_src}, underlying_dest}, bv_typet{dest_width}};
217+ return combine_aval_bval (new_aval, new_bval, dest);
218+ }
219+ else
220+ {
221+ auto new_aval = adjust_size (aval (src), dest_width);
222+ auto new_bval = adjust_size (bval (src), dest_width);
223+ return combine_aval_bval (new_aval, new_bval, dest);
224+ }
225+ }
204226 }
205227 else
206228 {
229+ // two-valued to four-valued
207230 const bv_typet bv_type{dest_width};
208231 auto aval =
209232 typecast_exprt{typecast_exprt{src, aval_bval_underlying (dest)}, bv_type};
@@ -501,14 +524,25 @@ exprt aval_bval(const verilog_implies_exprt &expr)
501524
502525exprt aval_bval (const typecast_exprt &expr)
503526{
504- // 'true' is defined as a "nonzero known value" (1800-2017 12.4).
527+ auto &dest_type = expr.type ();
528+
505529 PRECONDITION (is_aval_bval (expr.op ()));
506- PRECONDITION (expr.type ().id () == ID_bool);
507530
508- auto op_has_xz = ::has_xz (expr.op ());
509- auto op_aval = aval (expr.op ());
510- auto op_aval_zero = to_bv_type (op_aval.type ()).all_zeros_expr ();
511- return and_exprt{not_exprt{op_has_xz}, notequal_exprt{op_aval, op_aval_zero}};
531+ if (dest_type.id () == ID_bool)
532+ {
533+ // 'true' is defined as a "nonzero known value" (1800-2017 12.4).
534+ auto op_has_xz = ::has_xz (expr.op ());
535+ auto op_aval = aval (expr.op ());
536+ auto op_aval_zero = to_bv_type (op_aval.type ()).all_zeros_expr ();
537+ return and_exprt{not_exprt{op_has_xz}, notequal_exprt{op_aval, op_aval_zero}};
538+ }
539+ else if (dest_type.id () == ID_verilog_unsignedbv || dest_type.id () == ID_verilog_signedbv)
540+ {
541+ auto aval_bval_type = lower_to_aval_bval (dest_type);
542+ return aval_bval_conversion (expr.op (), aval_bval_type);
543+ }
544+ else
545+ PRECONDITION (false );
512546}
513547
514548exprt aval_bval (const shift_exprt &expr)
0 commit comments