Skip to content

Commit 32aaead

Browse files
committed
smt2_convt::convert_byte_update can now do non-constant offsets
1 parent a290568 commit 32aaead

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

src/solvers/smt2/smt2_conv.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,7 @@ void smt2_convt::convert_byte_update(const byte_update_exprt &expr)
756756
{
757757
assert(expr.operands().size()==3);
758758

759+
#if 0
759760
// The situation: expr.op0 needs to be split in 3 parts
760761
// |<--- L --->|<--- M --->|<--- R --->|
761762
// where M is the expr.op1'th byte
@@ -828,7 +829,31 @@ void smt2_convt::convert_byte_update(const byte_update_exprt &expr)
828829
}
829830
}
830831

831-
unflatten(END, expr.type());
832+
unflatten(END, expr.type());
833+
834+
#else
835+
836+
// We'll do an AND-mask for op(), and then OR-in
837+
// the value() shifted by the offset * 8.
838+
839+
std::size_t total_width=boolbv_width(expr.op().type());
840+
std::size_t value_width=boolbv_width(expr.value().type());
841+
842+
mp_integer mask=power(2, value_width)-1;
843+
exprt one_mask=from_integer(mask, unsignedbv_typet(total_width));
844+
845+
exprt distance=mult_exprt(
846+
expr.offset(),
847+
from_integer(8, expr.offset().type()));
848+
849+
exprt and_expr=bitand_exprt(expr.op(), bitnot_exprt(one_mask));
850+
exprt ext_value=typecast_exprt(expr.value(), one_mask.type());
851+
exprt or_expr=bitor_exprt(and_expr, shl_exprt(ext_value, distance));
852+
853+
unflatten(BEGIN, expr.type());
854+
flatten2bv(or_expr);
855+
unflatten(END, expr.type());
856+
#endif
832857
}
833858

834859
/*******************************************************************\

0 commit comments

Comments
 (0)