@@ -290,20 +290,21 @@ literalt bv_utilst::carry(literalt a, literalt b, literalt c)
290290 }
291291}
292292
293- void bv_utilst::adder (
294- bvt &sum,
295- const bvt &op,
296- literalt carry_in,
297- literalt &carry_out)
293+ std::pair<bvt, literalt>
294+ bv_utilst::adder (const bvt &op0, const bvt &op1, literalt carry_in)
298295{
299- PRECONDITION (sum .size () == op .size ());
296+ PRECONDITION (op0 .size () == op1 .size ());
300297
301- carry_out=carry_in;
298+ std::pair<bvt, literalt> result{bvt{}, carry_in};
299+ result.first .reserve (op0.size ());
300+ literalt &carry_out = result.second ;
302301
303- for (std::size_t i= 0 ; i<sum .size (); i++)
302+ for (std::size_t i = 0 ; i < op0 .size (); i++)
304303 {
305- sum[i] = full_adder (sum [i], op [i], carry_out, carry_out);
304+ result. first . push_back ( full_adder (op0 [i], op1 [i], carry_out, carry_out) );
306305 }
306+
307+ return result;
307308}
308309
309310literalt bv_utilst::carry_out (
@@ -327,37 +328,28 @@ bvt bv_utilst::add_sub_no_overflow(
327328 bool subtract,
328329 representationt rep)
329330{
330- bvt sum=op0;
331- adder_no_overflow (sum, op1, subtract, rep);
332- return sum;
331+ return adder_no_overflow (op0, op1, subtract, rep);
333332}
334333
335334bvt bv_utilst::add_sub (const bvt &op0, const bvt &op1, bool subtract)
336335{
337336 PRECONDITION (op0.size () == op1.size ());
338337
339338 literalt carry_in=const_literal (subtract);
340- literalt carry_out;
341339
342- bvt result=op0;
343340 bvt tmp_op1=subtract?inverted (op1):op1;
344341
345- adder (result, tmp_op1, carry_in, carry_out);
346-
347- return result;
342+ // we ignore the carry-out
343+ return adder (op0, tmp_op1, carry_in).first ;
348344}
349345
350346bvt bv_utilst::add_sub (const bvt &op0, const bvt &op1, literalt subtract)
351347{
352348 const bvt op1_sign_applied=
353349 select (subtract, inverted (op1), op1);
354350
355- bvt result=op0;
356- literalt carry_out;
357-
358- adder (result, op1_sign_applied, subtract, carry_out);
359-
360- return result;
351+ // we ignore the carry-out
352+ return adder (op0, op1_sign_applied, subtract).first ;
361353}
362354
363355bvt bv_utilst::saturating_add_sub (
@@ -371,23 +363,22 @@ bvt bv_utilst::saturating_add_sub(
371363 rep == representationt::SIGNED || rep == representationt::UNSIGNED);
372364
373365 literalt carry_in = const_literal (subtract);
374- literalt carry_out;
375366
376- bvt add_sub_result = op0;
377367 bvt tmp_op1 = subtract ? inverted (op1) : op1;
378368
379- adder (add_sub_result, tmp_op1, carry_in, carry_out);
369+ auto add_sub_result = adder (op0, tmp_op1, carry_in);
370+ literalt carry_out = add_sub_result.second ;
380371
381372 bvt result;
382- result.reserve (add_sub_result.size ());
373+ result.reserve (add_sub_result.first . size ());
383374 if (rep == representationt::UNSIGNED)
384375 {
385376 // An unsigned overflow has occurred when carry_out is not equal to
386377 // subtract: addition with a carry-out means an overflow beyond the maximum
387378 // representable value, subtraction without a carry-out means an underflow
388379 // below zero. For saturating arithmetic the former implies that all bits
389380 // should be set to 1, in the latter case all bits should be set to zero.
390- for (const auto &literal : add_sub_result)
381+ for (const auto &literal : add_sub_result. first )
391382 {
392383 result.push_back (
393384 subtract ? prop.land (literal, carry_out)
@@ -403,27 +394,27 @@ bvt bv_utilst::saturating_add_sub(
403394 literalt overflow_to_max_int = prop.land (bvt{
404395 !sign_bit (op0),
405396 subtract ? sign_bit (op1) : !sign_bit (op1),
406- sign_bit (add_sub_result)});
397+ sign_bit (add_sub_result. first )});
407398 // A signed underflow below the minimum representable value occurs when
408399 // adding two negative numbers and arriving at a positive result, or
409400 // subtracting a positive from a negative number (and, again, obtaining a
410401 // positive wrap-around result).
411402 literalt overflow_to_min_int = prop.land (bvt{
412403 sign_bit (op0),
413404 subtract ? !sign_bit (op1) : sign_bit (op1),
414- !sign_bit (add_sub_result)});
405+ !sign_bit (add_sub_result. first )});
415406
416407 // set all bits except for the sign bit
417- PRECONDITION (!add_sub_result.empty ());
418- for (std::size_t i = 0 ; i < add_sub_result.size () - 1 ; ++i)
408+ PRECONDITION (!add_sub_result.first . empty ());
409+ for (std::size_t i = 0 ; i < add_sub_result.first . size () - 1 ; ++i)
419410 {
420- const auto &literal = add_sub_result[i];
411+ const auto &literal = add_sub_result. first [i];
421412 result.push_back (prop.land (
422413 prop.lor (overflow_to_max_int, literal), !overflow_to_min_int));
423414 }
424415 // finally add the sign bit
425416 result.push_back (prop.land (
426- prop.lor (overflow_to_min_int, add_sub_result.back ( )),
417+ prop.lor (overflow_to_min_int, sign_bit ( add_sub_result.first )),
427418 !overflow_to_max_int));
428419 }
429420
@@ -479,48 +470,44 @@ literalt bv_utilst::overflow_sub(
479470 UNREACHABLE;
480471}
481472
482- void bv_utilst::adder_no_overflow (
483- bvt &sum ,
484- const bvt &op ,
473+ bvt bv_utilst::adder_no_overflow (
474+ const bvt &op0 ,
475+ const bvt &op1 ,
485476 bool subtract,
486477 representationt rep)
487478{
488- const bvt tmp_op= subtract? inverted (op):op ;
479+ const bvt tmp_op = subtract ? inverted (op1) : op1 ;
489480
490481 if (rep==representationt::SIGNED)
491482 {
492483 // an overflow occurs if the signs of the two operands are the same
493484 // and the sign of the sum is the opposite
494485
495- literalt old_sign=sum[sum.size ()-1 ];
496- literalt sign_the_same=
497- prop.lequal (sum[sum.size ()-1 ], tmp_op[tmp_op.size ()-1 ]);
486+ literalt old_sign = sign_bit (op0);
487+ literalt sign_the_same = prop.lequal (sign_bit (op0), sign_bit (tmp_op));
498488
499- literalt carry;
500- adder (sum , tmp_op, const_literal (subtract), carry) ;
489+ // we ignore the carry-out
490+ bvt sum = adder (op0 , tmp_op, const_literal (subtract)). first ;
501491
502- // result of addition in sum
503492 prop.l_set_to_false (
504- prop.land (sign_the_same, prop.lxor (sum[sum.size ()-1 ], old_sign)));
493+ prop.land (sign_the_same, prop.lxor (sign_bit (sum), old_sign)));
494+
495+ return sum;
505496 }
506497 else
507498 {
508499 INVARIANT (
509500 rep == representationt::UNSIGNED,
510501 " representation has either value signed or unsigned" );
511- literalt carry_out ;
512- adder (sum, tmp_op, const_literal ( subtract), carry_out );
513- prop. l_set_to (carry_out, subtract );
502+ auto result = adder (op0, tmp_op, const_literal (subtract)) ;
503+ prop. l_set_to (result. second , subtract);
504+ return std::move (result. first );
514505 }
515506}
516507
517- void bv_utilst::adder_no_overflow (bvt &sum , const bvt &op )
508+ bvt bv_utilst::adder_no_overflow (const bvt &op0 , const bvt &op1 )
518509{
519- literalt carry_out=const_literal (false );
520-
521- adder (sum, op, carry_out, carry_out);
522-
523- prop.l_set_to_false (carry_out); // enforce no overflow
510+ return adder_no_overflow (op0, op1, false , representationt::UNSIGNED);
524511}
525512
526513bvt bv_utilst::shift (const bvt &op, const shiftt s, const bvt &dist)
@@ -790,7 +777,7 @@ bvt bv_utilst::unsigned_multiplier_no_overflow(
790777 for (std::size_t idx=sum; idx<product.size (); idx++)
791778 tmpop.push_back (prop.land (op1[idx-sum], op0[sum]));
792779
793- adder_no_overflow (product, tmpop);
780+ product = adder_no_overflow (product, tmpop);
794781
795782 for (std::size_t idx=op1.size ()-sum; idx<op1.size (); idx++)
796783 prop.l_set_to_false (prop.land (op1[idx], op0[sum]));
@@ -1006,9 +993,7 @@ void bv_utilst::unsigned_divider(
1006993
1007994 // res*op1 + rem = op0
1008995
1009- bvt sum=product;
1010-
1011- adder_no_overflow (sum, rem);
996+ bvt sum = adder_no_overflow (product, rem);
1012997
1013998 literalt is_equal=equal (sum, op0);
1014999
0 commit comments