@@ -290,20 +290,21 @@ literalt bv_utilst::carry(literalt a, literalt b, literalt c)
290
290
}
291
291
}
292
292
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)
298
295
{
299
- PRECONDITION (sum .size () == op .size ());
296
+ PRECONDITION (op0 .size () == op1 .size ());
300
297
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 ;
302
301
303
- for (std::size_t i= 0 ; i<sum .size (); i++)
302
+ for (std::size_t i = 0 ; i < op0 .size (); i++)
304
303
{
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) );
306
305
}
306
+
307
+ return result;
307
308
}
308
309
309
310
literalt bv_utilst::carry_out (
@@ -327,37 +328,28 @@ bvt bv_utilst::add_sub_no_overflow(
327
328
bool subtract,
328
329
representationt rep)
329
330
{
330
- bvt sum=op0;
331
- adder_no_overflow (sum, op1, subtract, rep);
332
- return sum;
331
+ return adder_no_overflow (op0, op1, subtract, rep);
333
332
}
334
333
335
334
bvt bv_utilst::add_sub (const bvt &op0, const bvt &op1, bool subtract)
336
335
{
337
336
PRECONDITION (op0.size () == op1.size ());
338
337
339
338
literalt carry_in=const_literal (subtract);
340
- literalt carry_out;
341
339
342
- bvt result=op0;
343
340
bvt tmp_op1=subtract?inverted (op1):op1;
344
341
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 ;
348
344
}
349
345
350
346
bvt bv_utilst::add_sub (const bvt &op0, const bvt &op1, literalt subtract)
351
347
{
352
348
const bvt op1_sign_applied=
353
349
select (subtract, inverted (op1), op1);
354
350
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 ;
361
353
}
362
354
363
355
bvt bv_utilst::saturating_add_sub (
@@ -371,23 +363,22 @@ bvt bv_utilst::saturating_add_sub(
371
363
rep == representationt::SIGNED || rep == representationt::UNSIGNED);
372
364
373
365
literalt carry_in = const_literal (subtract);
374
- literalt carry_out;
375
366
376
- bvt add_sub_result = op0;
377
367
bvt tmp_op1 = subtract ? inverted (op1) : op1;
378
368
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 ;
380
371
381
372
bvt result;
382
- result.reserve (add_sub_result.size ());
373
+ result.reserve (add_sub_result.first . size ());
383
374
if (rep == representationt::UNSIGNED)
384
375
{
385
376
// An unsigned overflow has occurred when carry_out is not equal to
386
377
// subtract: addition with a carry-out means an overflow beyond the maximum
387
378
// representable value, subtraction without a carry-out means an underflow
388
379
// below zero. For saturating arithmetic the former implies that all bits
389
380
// 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 )
391
382
{
392
383
result.push_back (
393
384
subtract ? prop.land (literal, carry_out)
@@ -403,27 +394,27 @@ bvt bv_utilst::saturating_add_sub(
403
394
literalt overflow_to_max_int = prop.land (bvt{
404
395
!sign_bit (op0),
405
396
subtract ? sign_bit (op1) : !sign_bit (op1),
406
- sign_bit (add_sub_result)});
397
+ sign_bit (add_sub_result. first )});
407
398
// A signed underflow below the minimum representable value occurs when
408
399
// adding two negative numbers and arriving at a positive result, or
409
400
// subtracting a positive from a negative number (and, again, obtaining a
410
401
// positive wrap-around result).
411
402
literalt overflow_to_min_int = prop.land (bvt{
412
403
sign_bit (op0),
413
404
subtract ? !sign_bit (op1) : sign_bit (op1),
414
- !sign_bit (add_sub_result)});
405
+ !sign_bit (add_sub_result. first )});
415
406
416
407
// 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)
419
410
{
420
- const auto &literal = add_sub_result[i];
411
+ const auto &literal = add_sub_result. first [i];
421
412
result.push_back (prop.land (
422
413
prop.lor (overflow_to_max_int, literal), !overflow_to_min_int));
423
414
}
424
415
// finally add the sign bit
425
416
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 )),
427
418
!overflow_to_max_int));
428
419
}
429
420
@@ -479,48 +470,44 @@ literalt bv_utilst::overflow_sub(
479
470
UNREACHABLE;
480
471
}
481
472
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 ,
485
476
bool subtract,
486
477
representationt rep)
487
478
{
488
- const bvt tmp_op= subtract? inverted (op):op ;
479
+ const bvt tmp_op = subtract ? inverted (op1) : op1 ;
489
480
490
481
if (rep==representationt::SIGNED)
491
482
{
492
483
// an overflow occurs if the signs of the two operands are the same
493
484
// and the sign of the sum is the opposite
494
485
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));
498
488
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 ;
501
491
502
- // result of addition in sum
503
492
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;
505
496
}
506
497
else
507
498
{
508
499
INVARIANT (
509
500
rep == representationt::UNSIGNED,
510
501
" 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 );
514
505
}
515
506
}
516
507
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 )
518
509
{
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);
524
511
}
525
512
526
513
bvt bv_utilst::shift (const bvt &op, const shiftt s, const bvt &dist)
@@ -790,7 +777,7 @@ bvt bv_utilst::unsigned_multiplier_no_overflow(
790
777
for (std::size_t idx=sum; idx<product.size (); idx++)
791
778
tmpop.push_back (prop.land (op1[idx-sum], op0[sum]));
792
779
793
- adder_no_overflow (product, tmpop);
780
+ product = adder_no_overflow (product, tmpop);
794
781
795
782
for (std::size_t idx=op1.size ()-sum; idx<op1.size (); idx++)
796
783
prop.l_set_to_false (prop.land (op1[idx], op0[sum]));
@@ -1006,9 +993,7 @@ void bv_utilst::unsigned_divider(
1006
993
1007
994
// res*op1 + rem = op0
1008
995
1009
- bvt sum=product;
1010
-
1011
- adder_no_overflow (sum, rem);
996
+ bvt sum = adder_no_overflow (product, rem);
1012
997
1013
998
literalt is_equal=equal (sum, op0);
1014
999
0 commit comments