@@ -1817,6 +1817,50 @@ bvt bv_utilst::unsigned_multiplier(const bvt &_op0, const bvt &_op1)
1817
1817
}
1818
1818
}
1819
1819
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
+
1820
1864
bvt bv_utilst::unsigned_multiplier_no_overflow (
1821
1865
const bvt &op0,
1822
1866
const bvt &op1)
@@ -1867,7 +1911,11 @@ bvt bv_utilst::signed_multiplier(const bvt &op0, const bvt &op1)
1867
1911
bvt neg0=cond_negate (op0, sign0);
1868
1912
bvt neg1=cond_negate (op1, sign1);
1869
1913
1914
+ #ifdef USE_KARATSUBA
1915
+ bvt result = unsigned_karatsuba_multiplier (neg0, neg1);
1916
+ #else
1870
1917
bvt result=unsigned_multiplier (neg0, neg1);
1918
+ #endif
1871
1919
1872
1920
literalt result_sign=prop.lxor (sign0, sign1);
1873
1921
@@ -1935,7 +1983,12 @@ bvt bv_utilst::multiplier(
1935
1983
switch (rep)
1936
1984
{
1937
1985
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
1938
1990
case representationt::UNSIGNED: return unsigned_multiplier (op0, op1);
1991
+ #endif
1939
1992
}
1940
1993
1941
1994
UNREACHABLE;
0 commit comments