1/* Helper function for high degree Toom-Cook algorithms. 2 3 Contributed to the GNU project by Marco Bodrato. 4 5 THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY 6 SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST 7 GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE. 8 9Copyright 2009, 2010 Free Software Foundation, Inc. 10 11This file is part of the GNU MP Library. 12 13The GNU MP Library is free software; you can redistribute it and/or modify 14it under the terms of the GNU Lesser General Public License as published by 15the Free Software Foundation; either version 3 of the License, or (at your 16option) any later version. 17 18The GNU MP Library is distributed in the hope that it will be useful, but 19WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 20or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 21License for more details. 22 23You should have received a copy of the GNU Lesser General Public License 24along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ 25 26 27#include "gmp.h" 28#include "gmp-impl.h" 29 30/* Gets {pp,n} and (sign?-1:1)*{np,n}. Computes at once: 31 {pp,n} <- ({pp,n}+{np,n})/2^{ps+1} 32 {pn,n} <- ({pp,n}-{np,n})/2^{ns+1} 33 Finally recompose them obtaining: 34 {pp,n+off} <- {pp,n}+{np,n}*2^{off*GMP_NUMB_BITS} 35*/ 36void 37mpn_toom_couple_handling (mp_ptr pp, mp_size_t n, mp_ptr np, 38 int nsign, mp_size_t off, int ps, int ns) 39{ 40 if (nsign) { 41#ifdef HAVE_NATIVE_mpn_rsh1sub_n 42 mpn_rsh1sub_n (np, pp, np, n); 43#else 44 mpn_sub_n (np, pp, np, n); 45 mpn_rshift (np, np, n, 1); 46#endif 47 } else { 48#ifdef HAVE_NATIVE_mpn_rsh1add_n 49 mpn_rsh1add_n (np, pp, np, n); 50#else 51 mpn_add_n (np, pp, np, n); 52 mpn_rshift (np, np, n, 1); 53#endif 54 } 55 56#ifdef HAVE_NATIVE_mpn_rsh1sub_n 57 if (ps == 1) 58 mpn_rsh1sub_n (pp, pp, np, n); 59 else 60#endif 61 { 62 mpn_sub_n (pp, pp, np, n); 63 if (ps > 0) 64 mpn_rshift (pp, pp, n, ps); 65 } 66 if (ns > 0) 67 mpn_rshift (np, np, n, ns); 68 pp[n] = mpn_add_n (pp+off, pp+off, np, n-off); 69 ASSERT_NOCARRY (mpn_add_1(pp+n, np+n-off, off, pp[n]) ); 70} 71