@@ -188,22 +188,51 @@ 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{
216+ typecast_exprt{
217+ typecast_exprt{aval (src), underlying_src}, underlying_dest},
218+ bv_typet{dest_width}};
219+ auto new_bval = typecast_exprt{
220+ typecast_exprt{
221+ typecast_exprt{bval (src), underlying_src}, underlying_dest},
222+ bv_typet{dest_width}};
223+ return combine_aval_bval (new_aval, new_bval, dest);
224+ }
225+ else
226+ {
227+ auto new_aval = adjust_size (aval (src), dest_width);
228+ auto new_bval = adjust_size (bval (src), dest_width);
229+ return combine_aval_bval (new_aval, new_bval, dest);
230+ }
231+ }
204232 }
205233 else
206234 {
235+ // two-valued to four-valued
207236 const bv_typet bv_type{dest_width};
208237 auto aval =
209238 typecast_exprt{typecast_exprt{src, aval_bval_underlying (dest)}, bv_type};
@@ -501,14 +530,34 @@ exprt aval_bval(const verilog_implies_exprt &expr)
501530
502531exprt aval_bval (const typecast_exprt &expr)
503532{
504- // 'true' is defined as a "nonzero known value" (1800-2017 12.4).
533+ auto &dest_type = expr.type ();
534+
505535 PRECONDITION (is_aval_bval (expr.op ()));
506- PRECONDITION (expr.type ().id () == ID_bool);
507536
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}};
537+ if (dest_type.id () == ID_bool)
538+ {
539+ // 'true' is defined as a "nonzero known value" (1800-2017 12.4).
540+ auto op_has_xz = ::has_xz (expr.op ());
541+ auto op_aval = aval (expr.op ());
542+ auto op_aval_zero = to_bv_type (op_aval.type ()).all_zeros_expr ();
543+ return and_exprt{
544+ not_exprt{op_has_xz}, notequal_exprt{op_aval, op_aval_zero}};
545+ }
546+ else if (
547+ dest_type.id () == ID_verilog_unsignedbv ||
548+ dest_type.id () == ID_verilog_signedbv)
549+ {
550+ // four-valued to four-valued
551+ auto aval_bval_type = lower_to_aval_bval (dest_type);
552+ return aval_bval_conversion (expr.op (), aval_bval_type);
553+ }
554+ else if (dest_type.id () == ID_unsignedbv || dest_type.id () == ID_signedbv)
555+ {
556+ // four-valued to two-valued
557+ return typecast_exprt{aval (expr.op ()), dest_type};
558+ }
559+ else
560+ PRECONDITION (false );
512561}
513562
514563exprt aval_bval (const shift_exprt &expr)
0 commit comments