#include "radix.h"
void
_radix_mulhigh_known_low(nn_ptr out, nn_srcptr x, slong xn, nn_srcptr y, slong yn,
nn_srcptr kl, slong kl_len, slong klo, slong khi, nn_ptr scratch,
const radix_t radix)
{
slong outn = khi - klo;
if (klo > 3 && (xn + yn) >= khi
&& LIMB_RADIX(radix) >= (ulong) FLINT_MIN(xn, yn))
{
ulong g3[3], one = 1;
slong j;
for (j = 0; j < 3; j++)
{
slong idx = klo - 3 + j;
g3[j] = (idx < kl_len) ? kl[idx] : 0;
}
radix_mulmid(scratch, x, xn, y, yn, klo - 3, khi, radix);
radix_sub(scratch, scratch, outn + 3, g3, 3, radix);
if (scratch[2] != 0)
radix_add(scratch + 3, scratch + 3, outn, &one, 1, radix);
flint_mpn_copyi(out, scratch + 3, outn);
}
else
{
slong pl = FLINT_MIN(khi, xn + yn);
radix_mulmid(scratch, x, xn, y, yn, 0, pl, radix);
if (pl < khi)
flint_mpn_zero(scratch + pl, khi - pl);
flint_mpn_copyi(out, scratch + klo, outn);
}
}