@@ -1817,6 +1817,50 @@ bvt bv_utilst::unsigned_multiplier(const bvt &_op0, const bvt &_op1)
18171817 }
18181818}
18191819
1820+ bvt bv_utilst::unsigned_karatsuba_multiplier (const bvt &_op0, const bvt &_op1)
1821+ {
1822+ if (_op0.size () != _op1.size ())
1823+ return unsigned_multiplier (_op0, _op1);
1824+
1825+ const std::size_t op_size = _op0.size ();
1826+ if (op_size != 32 && op_size != 16 && op_size != 8 )
1827+ return unsigned_multiplier (_op0, _op1);
1828+
1829+ const std::size_t half_op_size = op_size >> 1 ;
1830+
1831+ bvt x0{_op0.begin (), _op0.begin () + half_op_size};
1832+ x0.resize (op_size, const_literal (false ));
1833+ bvt x1{_op0.begin () + half_op_size, _op0.end ()};
1834+ // x1.resize(op_size, const_literal(false));
1835+ bvt y0{_op1.begin (), _op1.begin () + half_op_size};
1836+ y0.resize (op_size, const_literal (false ));
1837+ bvt y1{_op1.begin () + half_op_size, _op1.end ()};
1838+ // y1.resize(op_size, const_literal(false));
1839+
1840+ bvt z0 = unsigned_multiplier (x0, y0);
1841+ bvt z2 = unsigned_karatsuba_multiplier (x1, y1);
1842+
1843+ bvt z0_half{z0.begin (), z0.begin () + half_op_size};
1844+ bvt z2_plus_z0 = add (z2, z0_half);
1845+ z2_plus_z0.resize (half_op_size);
1846+
1847+ bvt x0_half{x0.begin (), x0.begin () + half_op_size};
1848+ bvt xdiff = add (x0_half, x1);
1849+ // xdiff.resize(half_op_size);
1850+ bvt y0_half{y0.begin (), y0.begin () + half_op_size};
1851+ bvt ydiff = add (y1, y0_half);
1852+ // ydiff.resize(half_op_size);
1853+
1854+ bvt z1 = sub (unsigned_karatsuba_multiplier (xdiff, ydiff), z2_plus_z0);
1855+ for (std::size_t i = 0 ; i < half_op_size; ++i)
1856+ z1.insert (z1.begin (), const_literal (false ));
1857+ // result.insert(result.end(), z1.begin(), z1.end());
1858+
1859+ // z1.resize(op_size);
1860+ z0.resize (op_size);
1861+ return add (z0, z1);
1862+ }
1863+
18201864bvt bv_utilst::unsigned_multiplier_no_overflow (
18211865 const bvt &op0,
18221866 const bvt &op1)
@@ -1867,7 +1911,11 @@ bvt bv_utilst::signed_multiplier(const bvt &op0, const bvt &op1)
18671911 bvt neg0=cond_negate (op0, sign0);
18681912 bvt neg1=cond_negate (op1, sign1);
18691913
1914+ #ifdef USE_KARATSUBA
1915+ bvt result = unsigned_karatsuba_multiplier (neg0, neg1);
1916+ #else
18701917 bvt result=unsigned_multiplier (neg0, neg1);
1918+ #endif
18711919
18721920 literalt result_sign=prop.lxor (sign0, sign1);
18731921
@@ -1935,7 +1983,12 @@ bvt bv_utilst::multiplier(
19351983 switch (rep)
19361984 {
19371985 case representationt::SIGNED: return signed_multiplier (op0, op1);
1986+ #ifdef USE_KARATSUBA
1987+ case representationt::UNSIGNED:
1988+ return unsigned_karatsuba_multiplier (op0, op1);
1989+ #else
19381990 case representationt::UNSIGNED: return unsigned_multiplier (op0, op1);
1991+ #endif
19391992 }
19401993
19411994 UNREACHABLE;
0 commit comments