@@ -290,7 +290,37 @@ literalt bv_utilst::carry(literalt a, literalt b, literalt c)
290290 }
291291}
292292
293- literalt bv_utilst::adder (
293+ static literalt carry_out_of_sum (
294+ propt &prop,
295+ const bvt &op0,
296+ const bvt &op1,
297+ const bvt &sum)
298+ {
299+ literalt a = op0.back ();
300+ literalt b = op1.back ();
301+ literalt s = sum.back ();
302+
303+ const auto const_count =
304+ a.is_constant () + b.is_constant () + s.is_constant ();
305+
306+ if (const_count >= 2 || true )
307+ {
308+ return
309+ prop.lor (
310+ prop.land (a, b),
311+ prop.land (!s, prop.lor (a, b)));
312+ }
313+
314+ literalt c = prop.new_variable ();
315+
316+ // TODO
317+ assert (false );
318+ prop.lcnf ({a, b, s, c});
319+
320+ return c;
321+ }
322+
323+ void bv_utilst::adder (
294324 bvt &sum,
295325 const bvt &op,
296326 literalt carry_in)
@@ -305,8 +335,6 @@ literalt bv_utilst::adder(
305335 {
306336 sum[i] = full_adder (sum[i], op[i], carry_out, carry_out);
307337 }
308-
309- return carry_out;
310338 }
311339 else
312340 {
@@ -376,10 +404,6 @@ literalt bv_utilst::adder(
376404 prop.lcnf ({!sum[i], !first_op[i], !op[i], !sum[i-1 ], first_op[i-1 ]});
377405 prop.lcnf ({!sum[i], !first_op[i], !op[i], !sum[i-1 ], op[i-1 ]});
378406 }
379-
380- return prop.lor (
381- prop.land (first_op.back (), op.back ()),
382- prop.land (!sum.back (), prop.lor (first_op.back (), op.back ())));
383407 }
384408}
385409
@@ -418,8 +442,7 @@ bvt bv_utilst::add_sub(const bvt &op0, const bvt &op1, bool subtract)
418442 bvt result=op0;
419443 bvt tmp_op1=subtract?inverted (op1):op1;
420444
421- // we ignore the carry-out
422- (void )adder (result, tmp_op1, carry_in);
445+ adder (result, tmp_op1, carry_in);
423446
424447 return result;
425448}
@@ -431,8 +454,7 @@ bvt bv_utilst::add_sub(const bvt &op0, const bvt &op1, literalt subtract)
431454
432455 bvt result=op0;
433456
434- // we ignore the carry-out
435- (void )adder (result, op1_sign_applied, subtract);
457+ adder (result, op1_sign_applied, subtract);
436458
437459 return result;
438460}
@@ -452,7 +474,8 @@ bvt bv_utilst::saturating_add_sub(
452474 bvt add_sub_result = op0;
453475 bvt tmp_op1 = subtract ? inverted (op1) : op1;
454476
455- literalt carry_out = adder (add_sub_result, tmp_op1, carry_in);
477+ adder (add_sub_result, tmp_op1, carry_in);
478+ literalt carry_out = carry_out_of_sum (prop, op0, tmp_op1, add_sub_result);
456479
457480 bvt result;
458481 result.reserve (add_sub_result.size ());
@@ -572,8 +595,7 @@ void bv_utilst::adder_no_overflow(
572595 literalt sign_the_same=
573596 prop.lequal (sum[sum.size ()-1 ], tmp_op[tmp_op.size ()-1 ]);
574597
575- // we ignore the carry-out
576- (void )adder (sum, tmp_op, const_literal (subtract));
598+ adder (sum, tmp_op, const_literal (subtract));
577599
578600 // result of addition in sum
579601 prop.l_set_to_false (
@@ -584,14 +606,18 @@ void bv_utilst::adder_no_overflow(
584606 INVARIANT (
585607 rep == representationt::UNSIGNED,
586608 " representation has either value signed or unsigned" );
587- literalt carry_out = adder (sum, tmp_op, const_literal (subtract));
609+ bvt op0 = sum;
610+ adder (sum, tmp_op, const_literal (subtract));
611+ literalt carry_out = carry_out_of_sum (prop, op0, tmp_op, sum);
588612 prop.l_set_to (carry_out, subtract);
589613 }
590614}
591615
592616void bv_utilst::adder_no_overflow (bvt &sum, const bvt &op)
593617{
594- literalt carry_out = adder (sum, op, const_literal (false ));
618+ bvt op0 = sum;
619+ adder (sum, op, const_literal (false ));
620+ literalt carry_out = carry_out_of_sum (prop, op0, op, sum);
595621 prop.l_set_to_false (carry_out); // enforce no overflow
596622}
597623
0 commit comments