@@ -290,7 +290,37 @@ literalt bv_utilst::carry(literalt a, literalt b, literalt c)
290
290
}
291
291
}
292
292
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 (
294
324
bvt &sum,
295
325
const bvt &op,
296
326
literalt carry_in)
@@ -305,8 +335,6 @@ literalt bv_utilst::adder(
305
335
{
306
336
sum[i] = full_adder (sum[i], op[i], carry_out, carry_out);
307
337
}
308
-
309
- return carry_out;
310
338
}
311
339
else
312
340
{
@@ -376,10 +404,6 @@ literalt bv_utilst::adder(
376
404
prop.lcnf ({!sum[i], !first_op[i], !op[i], !sum[i-1 ], first_op[i-1 ]});
377
405
prop.lcnf ({!sum[i], !first_op[i], !op[i], !sum[i-1 ], op[i-1 ]});
378
406
}
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 ())));
383
407
}
384
408
}
385
409
@@ -418,8 +442,7 @@ bvt bv_utilst::add_sub(const bvt &op0, const bvt &op1, bool subtract)
418
442
bvt result=op0;
419
443
bvt tmp_op1=subtract?inverted (op1):op1;
420
444
421
- // we ignore the carry-out
422
- (void )adder (result, tmp_op1, carry_in);
445
+ adder (result, tmp_op1, carry_in);
423
446
424
447
return result;
425
448
}
@@ -431,8 +454,7 @@ bvt bv_utilst::add_sub(const bvt &op0, const bvt &op1, literalt subtract)
431
454
432
455
bvt result=op0;
433
456
434
- // we ignore the carry-out
435
- (void )adder (result, op1_sign_applied, subtract);
457
+ adder (result, op1_sign_applied, subtract);
436
458
437
459
return result;
438
460
}
@@ -452,7 +474,8 @@ bvt bv_utilst::saturating_add_sub(
452
474
bvt add_sub_result = op0;
453
475
bvt tmp_op1 = subtract ? inverted (op1) : op1;
454
476
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);
456
479
457
480
bvt result;
458
481
result.reserve (add_sub_result.size ());
@@ -572,8 +595,7 @@ void bv_utilst::adder_no_overflow(
572
595
literalt sign_the_same=
573
596
prop.lequal (sum[sum.size ()-1 ], tmp_op[tmp_op.size ()-1 ]);
574
597
575
- // we ignore the carry-out
576
- (void )adder (sum, tmp_op, const_literal (subtract));
598
+ adder (sum, tmp_op, const_literal (subtract));
577
599
578
600
// result of addition in sum
579
601
prop.l_set_to_false (
@@ -584,14 +606,18 @@ void bv_utilst::adder_no_overflow(
584
606
INVARIANT (
585
607
rep == representationt::UNSIGNED,
586
608
" 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);
588
612
prop.l_set_to (carry_out, subtract);
589
613
}
590
614
}
591
615
592
616
void bv_utilst::adder_no_overflow (bvt &sum, const bvt &op)
593
617
{
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);
595
621
prop.l_set_to_false (carry_out); // enforce no overflow
596
622
}
597
623
0 commit comments