-
+ FB984A326A9BCDA1A4CBC05EE279E55CFEFCF157393D2F66405760B256395C3A73F1F41EBFC335722022EA04C79F6E02AB3179ECC9A66E037DD7A106572B4924
mpi/udiv-w-sdiv.c
(0 . 0)(1 . 132)
11227 /* mpihelp_udiv_w_sdiv -- implement udiv_qrnnd on machines with only signed
11228 * division.
11229 * Copyright (C) 1992, 1994, 1996, 1998 Free Software Foundation, Inc.
11230 * Contributed by Peter L. Montgomery.
11231 *
11232 * This file is part of GnuPG.
11233 *
11234 * GnuPG is free software; you can redistribute it and/or modify
11235 * it under the terms of the GNU General Public License as published by
11236 * the Free Software Foundation; either version 3 of the License, or
11237 * (at your option) any later version.
11238 *
11239 * GnuPG is distributed in the hope that it will be useful,
11240 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11241 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11242 * GNU General Public License for more details.
11243 *
11244 * You should have received a copy of the GNU General Public License
11245 * along with this program; if not, see <http://www.gnu.org/licenses/>.
11246 */
11247
11248 #include <config.h>
11249 #include <stdio.h>
11250 #include <stdlib.h>
11251 #include "mpi-internal.h"
11252 #include "longlong.h"
11253
11254
11255 #if 0 /* not yet ported to MPI */
11256
11257 mpi_limb_t
11258 mpihelp_udiv_w_sdiv( mpi_limp_t *rp,
11259 mpi_limp_t *a1,
11260 mpi_limp_t *a0,
11261 mpi_limp_t *d )
11262 {
11263 mp_limb_t q, r;
11264 mp_limb_t c0, c1, b1;
11265
11266 if ((mpi_limb_signed_t) d >= 0)
11267 {
11268 if (a1 < d - a1 - (a0 >> (BITS_PER_MP_LIMB - 1)))
11269 {
11270 /* dividend, divisor, and quotient are nonnegative */
11271 sdiv_qrnnd (q, r, a1, a0, d);
11272 }
11273 else
11274 {
11275 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
11276 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (BITS_PER_MP_LIMB - 1));
11277 /* Divide (c1*2^32 + c0) by d */
11278 sdiv_qrnnd (q, r, c1, c0, d);
11279 /* Add 2^31 to quotient */
11280 q += (mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1);
11281 }
11282 }
11283 else
11284 {
11285 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
11286 c1 = a1 >> 1; /* A/2 */
11287 c0 = (a1 << (BITS_PER_MP_LIMB - 1)) + (a0 >> 1);
11288
11289 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
11290 {
11291 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
11292
11293 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
11294 if ((d & 1) != 0)
11295 {
11296 if (r >= q)
11297 r = r - q;
11298 else if (q - r <= d)
11299 {
11300 r = r - q + d;
11301 q--;
11302 }
11303 else
11304 {
11305 r = r - q + 2*d;
11306 q -= 2;
11307 }
11308 }
11309 }
11310 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
11311 {
11312 c1 = (b1 - 1) - c1;
11313 c0 = ~c0; /* logical NOT */
11314
11315 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
11316
11317 q = ~q; /* (A/2)/b1 */
11318 r = (b1 - 1) - r;
11319
11320 r = 2*r + (a0 & 1); /* A/(2*b1) */
11321
11322 if ((d & 1) != 0)
11323 {
11324 if (r >= q)
11325 r = r - q;
11326 else if (q - r <= d)
11327 {
11328 r = r - q + d;
11329 q--;
11330 }
11331 else
11332 {
11333 r = r - q + 2*d;
11334 q -= 2;
11335 }
11336 }
11337 }
11338 else /* Implies c1 = b1 */
11339 { /* Hence a1 = d - 1 = 2*b1 - 1 */
11340 if (a0 >= -d)
11341 {
11342 q = -1;
11343 r = a0 + d;
11344 }
11345 else
11346 {
11347 q = -2;
11348 r = a0 + 2*d;
11349 }
11350 }
11351 }
11352
11353 *rp = r;
11354 return q;
11355 }
11356
11357 #endif
11358