@@ -94,6 +94,8 @@ namespace bv {
94
94
m_tmp2.push_back (0 );
95
95
m_tmp2.push_back (0 );
96
96
m_zero.push_back (0 );
97
+ m_one.push_back (0 );
98
+ m_one[0 ] = 1 ;
97
99
}
98
100
return r;
99
101
}
@@ -207,10 +209,8 @@ namespace bv {
207
209
for (unsigned i = a.nw ; i < 2 * a.nw ; ++i)
208
210
if (m_tmp2[i] != 0 )
209
211
return true ;
210
- for (unsigned i = a.bw ; i < sizeof (digit_t ) * 8 * a.nw ; ++i)
211
- if (a.get (m_tmp2, i))
212
- return true ;
213
- return false ;
212
+ return !a.has_overflow (m_tmp);
213
+ return true ;
214
214
};
215
215
216
216
switch (e->get_decl_kind ()) {
@@ -247,7 +247,7 @@ namespace bv {
247
247
auto const & b = wval0 (e->get_arg (1 ));
248
248
digit_t c = 0 ;
249
249
mpn.add (a.bits .data (), a.nw , b.bits .data (), b.nw , m_tmp.data (), a.nw , &c);
250
- return c != 0 ;
250
+ return c != 0 || a. has_overflow (m_tmp) ;
251
251
}
252
252
case OP_BNEG_OVFL:
253
253
case OP_BSADD_OVFL:
@@ -442,23 +442,110 @@ namespace bv {
442
442
for (unsigned i = 0 ; i < a.bw ; ++i)
443
443
val.set (val.bits , i, i + sh < a.bw && b.get (b.bits , i + sh));
444
444
if (sign)
445
- for (unsigned i = 0 ; i < sh; ++i)
446
- val.set (val.bits , a.bw - i, true );
445
+ val.set_range (val.bits , 0 , a.bw - sh, true );
447
446
}
448
447
break ;
449
448
}
450
- case OP_BSDIV:
451
- case OP_BSDIV_I:
452
- case OP_BSDIV0:
453
- case OP_BUDIV:
454
- case OP_BUDIV_I:
455
- case OP_BUDIV0:
449
+ case OP_SIGN_EXT: {
450
+ auto & a = wval0 (e->get_arg (0 ));
451
+ a.set (val.bits );
452
+ bool sign = a.get (a.bits , a.bw - 1 );
453
+ val.set_range (val.bits , a.bw , val.bw , sign);
454
+ break ;
455
+ }
456
+ case OP_ZERO_EXT: {
457
+ auto & a = wval0 (e->get_arg (0 ));
458
+ a.set (val.bits );
459
+ val.set_range (val.bits , a.bw , val.bw , false );
460
+ break ;
461
+ }
456
462
case OP_BUREM:
457
463
case OP_BUREM_I:
458
- case OP_BUREM0:
464
+ case OP_BUREM0: {
465
+ auto & a = wval0 (e->get_arg (0 ));
466
+ auto & b = wval0 (e->get_arg (1 ));
467
+
468
+ if (b.is_zero ())
469
+ val.set (a.bits );
470
+ else {
471
+ mpn.div (a.bits .data (), a.nw ,
472
+ b.bits .data (), b.nw ,
473
+ m_tmp.data (), // quotient
474
+ m_tmp2.data ()); // remainder
475
+ val.set (m_tmp2);
476
+ }
477
+ break ;
478
+ }
459
479
case OP_BSMOD:
460
480
case OP_BSMOD_I:
461
- case OP_BSMOD0:
481
+ case OP_BSMOD0: {
482
+ // u = mod(x,y)
483
+ // u = 0 -> 0
484
+ // y = 0 -> x
485
+ // x < 0, y < 0 -> -u
486
+ // x < 0, y >= 0 -> y - u
487
+ // x >= 0, y < 0 -> y + u
488
+ // x >= 0, y >= 0 -> u
489
+ auto & a = wval0 (e->get_arg (0 ));
490
+ auto & b = wval0 (e->get_arg (1 ));
491
+ if (b.is_zero ())
492
+ val.set (a.bits );
493
+ else {
494
+ digit_t c;
495
+ mpn.div (a.bits .data (), a.nw ,
496
+ b.bits .data (), b.nw ,
497
+ m_tmp.data (), // quotient
498
+ m_tmp2.data ()); // remainder
499
+ if (val.is_zero (m_tmp2))
500
+ val.set (m_tmp2);
501
+ else if (a.sign () && b.sign ())
502
+ mpn.sub (m_zero.data (), a.nw , m_tmp2.data (), a.nw , m_tmp.data (), &c),
503
+ val.set (m_tmp);
504
+ else if (a.sign ())
505
+ mpn.sub (b.bits .data (), a.nw , m_tmp2.data (), a.nw , m_tmp.data (), &c),
506
+ val.set (m_tmp);
507
+ else if (b.sign ())
508
+ mpn.add (b.bits .data (), a.nw , m_tmp2.data (), a.nw , m_tmp.data (), a.nw , &c),
509
+ val.set (m_tmp);
510
+ else
511
+ val.set (m_tmp2);
512
+ }
513
+ break ;
514
+ }
515
+ case OP_BUDIV:
516
+ case OP_BUDIV_I:
517
+ case OP_BUDIV0: {
518
+ // x div 0 = -1
519
+ auto & a = wval0 (e->get_arg (0 ));
520
+ auto & b = wval0 (e->get_arg (1 ));
521
+ if (b.is_zero ()) {
522
+ val.set (m_zero);
523
+ for (unsigned i = 0 ; i < a.nw ; ++i)
524
+ val.bits [i] = ~val.bits [i];
525
+ }
526
+ else {
527
+ mpn.div (a.bits .data (), a.nw ,
528
+ b.bits .data (), b.nw ,
529
+ m_tmp.data (), // quotient
530
+ m_tmp2.data ()); // remainder
531
+ val.set (m_tmp);
532
+ }
533
+ break ;
534
+ }
535
+
536
+ case OP_BSDIV:
537
+ case OP_BSDIV_I:
538
+ case OP_BSDIV0:
539
+ // d = udiv(abs(x), abs(y))
540
+ // y = 0, x > 0 -> 1
541
+ // y = 0, x <= 0 -> -1
542
+ // x = 0, y != 0 -> 0
543
+ // x > 0, y < 0 -> -d
544
+ // x < 0, y > 0 -> -d
545
+ // x > 0, y > 0 -> d
546
+ // x < 0, y < 0 -> d
547
+
548
+
462
549
case OP_BREDAND:
463
550
case OP_BREDOR:
464
551
case OP_BXNOR:
@@ -595,10 +682,18 @@ namespace bv {
595
682
else
596
683
return try_repair_sle (!bval0 (e), wval0 (e, i), wval0 (e, 1 - i));
597
684
case OP_BASHR:
685
+ return try_repair_ashr (wval0 (e), wval0 (e, 0 ), wval0 (e, 1 ), i);
598
686
case OP_BLSHR:
687
+ return try_repair_lshr (wval0 (e), wval0 (e, 0 ), wval0 (e, 1 ), i);
599
688
case OP_BSHL:
689
+ return try_repair_shl (wval0 (e), wval0 (e, 0 ), wval0 (e, 1 ), i);
690
+ case OP_BIT2BOOL: {
691
+ unsigned idx;
692
+ expr* arg;
693
+ VERIFY (bv.is_bit2bool (e, arg, idx));
694
+ return try_repair_bit2bool (wval0 (e, 0 ), idx);
695
+ }
600
696
case OP_BCOMP:
601
- case OP_BIT2BOOL:
602
697
case OP_BNAND:
603
698
case OP_BREDAND:
604
699
case OP_BREDOR:
@@ -751,15 +846,20 @@ namespace bv {
751
846
* 8*e = a*(2b), then a = 4e*b^-1
752
847
*/
753
848
bool sls_eval::try_repair_mul (bvval const & e, bvval& a, bvval const & b) {
754
- unsigned parity_e = e.parity (e.bits );
755
- unsigned parity_b = b.parity (b.bits );
756
- if (parity_e < parity_b)
849
+ if (b.is_zero ()) {
850
+ if (a.is_zero ()) {
851
+ a.set (m_tmp, 1 );
852
+ return a.try_set (m_tmp);
853
+ }
757
854
return false ;
855
+ }
758
856
rational ne, nb;
759
857
e.get_value (e.bits , ne);
760
858
b.get_value (b.bits , nb);
859
+ unsigned parity_e = e.parity (e.bits );
860
+ unsigned parity_b = b.parity (b.bits );
761
861
if (parity_b > 0 )
762
- ne /= rational::power_of_two (parity_b);
862
+ ne /= rational::power_of_two (std::min ( parity_b, parity_e) );
763
863
auto inv_b = nb.pseudo_inverse (b.bw );
764
864
rational na = mod (inv_b * ne, rational::power_of_two (a.bw ));
765
865
a.set_value (m_tmp, na);
@@ -774,18 +874,16 @@ namespace bv {
774
874
775
875
bool sls_eval::try_repair_bneg (bvval const & e, bvval& a) {
776
876
digit_t c;
777
- mpn.sub (m_zero.data (), e.nw , e.bits .data (), e.nw , m_tmp.data (), &c);
877
+ mpn.sub (m_zero.data (), e.nw , e.bits .data (), e.nw , m_tmp.data (), &c);
778
878
return a.try_set (m_tmp);
779
879
}
780
880
781
881
bool sls_eval::try_repair_ule (bool e, bvval& a, bvval const & b) {
782
882
if (e)
783
883
return a.try_set (b.bits );
784
884
else {
785
- digit_t c;
786
- a.set (m_zero, 0 , true );
787
- mpn.add (b.bits .data (), a.nw , m_zero.data (), a.nw , &c, a.nw , m_tmp.data ());
788
- a.set (m_zero, 0 , false );
885
+ digit_t c;
886
+ mpn.add (b.bits .data (), a.nw , m_one.data (), a.nw , &c, a.nw , m_tmp.data ());
789
887
return a.try_set (m_tmp);
790
888
}
791
889
}
@@ -795,18 +893,71 @@ namespace bv {
795
893
return a.try_set (b.bits );
796
894
else {
797
895
digit_t c;
798
- a.set (m_zero, 0 , true );
799
- mpn.sub (b.bits .data (), a.nw , m_zero.data (), a.nw , m_tmp.data (), &c);
800
- a.set (m_zero, 0 , false );
896
+ mpn.sub (b.bits .data (), a.nw , m_one.data (), a.nw , m_tmp.data (), &c);
801
897
return a.try_set (m_tmp);
802
898
}
803
899
}
804
900
805
901
bool sls_eval::try_repair_sle (bool e, bvval& a, bvval const & b) {
806
- return false ;
902
+ return try_repair_ule (e, a, b) ;
807
903
}
808
904
809
905
bool sls_eval::try_repair_sge (bool e, bvval& a, bvval const & b) {
906
+ return try_repair_uge (e, a, b);
907
+ }
908
+
909
+ bool sls_eval::try_repair_bit2bool (bvval& a, unsigned idx) {
910
+ for (unsigned i = 0 ; i < a.nw ; ++i)
911
+ m_tmp[i] = a.bits [i];
912
+ a.set (m_tmp, idx, !a.get (a.bits , idx));
913
+ return a.try_set (m_tmp);
914
+ }
915
+
916
+ bool sls_eval::try_repair_shl (bvval const & e, bvval& a, bvval& b, unsigned i) {
917
+ if (i == 0 ) {
918
+ unsigned sh = b.to_nat (b.bits , b.bw );
919
+ if (sh == 0 )
920
+ return a.try_set (e.bits );
921
+ else if (sh >= b.bw ) {
922
+ return false ;
923
+ }
924
+ else {
925
+ //
926
+ // e = a << sh
927
+ // set bw - sh low order bits to bw - sh high-order of e.
928
+ // a[bw - sh - 1: 0] = e[bw - 1: sh]
929
+ // a[bw - 1: bw - sh] = unchanged
930
+ //
931
+ for (unsigned i = 0 ; i < e.bw - sh; ++i)
932
+ e.set (m_tmp, i, e.get (e.bits , sh + i));
933
+ for (unsigned i = e.bw - sh; i < e.bw ; ++i)
934
+ e.set (m_tmp, i, e.get (a.bits , i));
935
+ return a.try_set (m_tmp);
936
+ }
937
+ }
938
+ else {
939
+ SASSERT (i == 1 );
940
+ }
941
+ return false ;
942
+ }
943
+
944
+ bool sls_eval::try_repair_ashr (bvval const & e, bvval & a, bvval& b, unsigned i) {
945
+ if (i == 0 ) {
946
+
947
+ }
948
+ else {
949
+
950
+ }
951
+ return false ;
952
+ }
953
+
954
+ bool sls_eval::try_repair_lshr (bvval const & e, bvval& a, bvval& b, unsigned i) {
955
+ if (i == 0 ) {
956
+
957
+ }
958
+ else {
959
+
960
+ }
810
961
return false ;
811
962
}
812
963
0 commit comments