diff options
Diffstat (limited to 'Build/source/libs/gmp/gmp-src/mpz/ior.c')
-rw-r--r-- | Build/source/libs/gmp/gmp-src/mpz/ior.c | 224 |
1 files changed, 89 insertions, 135 deletions
diff --git a/Build/source/libs/gmp/gmp-src/mpz/ior.c b/Build/source/libs/gmp/gmp-src/mpz/ior.c index 5c181f04c4c..32f304278c9 100644 --- a/Build/source/libs/gmp/gmp-src/mpz/ior.c +++ b/Build/source/libs/gmp/gmp-src/mpz/ior.c @@ -1,7 +1,7 @@ /* mpz_ior -- Logical inclusive or. -Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001, 2005, 2012, 2013 Free -Software Foundation, Inc. +Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001, 2005, 2012, 2013, +2015-2018 Free Software Foundation, Inc. This file is part of the GNU MP Library. @@ -29,7 +29,6 @@ You should have received copies of the GNU General Public License and the GNU Lesser General Public License along with the GNU MP Library. If not, see https://www.gnu.org/licenses/. */ -#include "gmp.h" #include "gmp-impl.h" void @@ -40,76 +39,49 @@ mpz_ior (mpz_ptr res, mpz_srcptr op1, mpz_srcptr op2) mp_ptr res_ptr; mp_size_t res_size; mp_size_t i; - TMP_DECL; - TMP_MARK; op1_size = SIZ(op1); op2_size = SIZ(op2); + if (op1_size < op2_size) + { + MPZ_SRCPTR_SWAP (op1, op2); + MP_SIZE_T_SWAP (op1_size, op2_size); + } + op1_ptr = PTR(op1); - op2_ptr = PTR(op2); res_ptr = PTR(res); - if (op1_size >= 0) + if (op2_size >= 0) { - if (op2_size >= 0) - { - if (op1_size >= op2_size) - { - if (ALLOC(res) < op1_size) - { - res_ptr = MPZ_REALLOC (res, op1_size); - /* No overlapping possible: op1_ptr = PTR(op1); */ - op2_ptr = PTR(op2); - } - - if (res_ptr != op1_ptr) - MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size, - op1_size - op2_size); - if (LIKELY (op2_size != 0)) - mpn_ior_n (res_ptr, op1_ptr, op2_ptr, op2_size); - res_size = op1_size; - } - else - { - if (ALLOC(res) < op2_size) - { - res_ptr = MPZ_REALLOC (res, op2_size); - op1_ptr = PTR(op1); - /* No overlapping possible: op2_ptr = PTR(op2); */ - } - - if (res_ptr != op2_ptr) - MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size, - op2_size - op1_size); - if (LIKELY (op1_size != 0)) - mpn_ior_n (res_ptr, op1_ptr, op2_ptr, op1_size); - res_size = op2_size; - } - - SIZ(res) = res_size; - return; - } - else /* op2_size < 0 */ + if (res_ptr != op1_ptr) { - /* Fall through to the code at the end of the function. */ + res_ptr = MPZ_REALLOC (res, op1_size); + /* No overlapping possible: op1_ptr = PTR(op1); */ + MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size, + op1_size - op2_size); } + if (LIKELY (op2_size != 0)) + mpn_ior_n (res_ptr, op1_ptr, PTR(op2), op2_size); + + SIZ(res) = op1_size; } else { - if (op2_size < 0) + mp_ptr opx; + TMP_DECL; + + TMP_MARK; + if (op1_size < 0) { - mp_ptr opx, opy; + mp_ptr opy; /* Both operands are negative, so will be the result. -((-OP1) | (-OP2)) = -(~(OP1 - 1) | ~(OP2 - 1)) = = ~(~(OP1 - 1) | ~(OP2 - 1)) + 1 = = ((OP1 - 1) & (OP2 - 1)) + 1 */ - op1_size = -op1_size; - op2_size = -op2_size; - - res_size = MIN (op1_size, op2_size); + res_size = -op1_size; /* Possible optimization: Decrease mpn_sub precision, as we won't use the entire res of both. */ @@ -117,19 +89,19 @@ mpz_ior (mpz_ptr res, mpz_srcptr op1, mpz_srcptr op2) mpn_sub_1 (opx, op1_ptr, res_size, (mp_limb_t) 1); op1_ptr = opx; - mpn_sub_1 (opy, op2_ptr, res_size, (mp_limb_t) 1); + mpn_sub_1 (opy, PTR(op2), res_size, (mp_limb_t) 1); op2_ptr = opy; /* First loop finds the size of the result. */ - for (i = res_size - 1; i >= 0; i--) + for (i = res_size; --i >= 0;) if ((op1_ptr[i] & op2_ptr[i]) != 0) break; res_size = i + 1; + res_ptr = MPZ_NEWALLOC (res, res_size + 1); + if (res_size != 0) { - res_ptr = MPZ_NEWALLOC (res, res_size + 1); - /* Second loop computes the real result. */ mpn_and_n (res_ptr, op1_ptr, op2_ptr, res_size); @@ -144,87 +116,69 @@ mpz_ior (mpz_ptr res, mpz_srcptr op1, mpz_srcptr op2) } SIZ(res) = -res_size; - TMP_FREE; - return; } else { - /* We should compute -OP1 | OP2. Swap OP1 and OP2 and fall - through to the code that handles OP1 | -OP2. */ - MPZ_SRCPTR_SWAP (op1, op2); - MPN_SRCPTR_SWAP (op1_ptr,op1_size, op2_ptr,op2_size); + mp_limb_t cy; + mp_size_t count; + + /* Operand 2 negative, so will be the result. + -(OP1 | (-OP2)) = -(OP1 | ~(OP2 - 1)) = + = ~(OP1 | ~(OP2 - 1)) + 1 = + = (~OP1 & (OP2 - 1)) + 1 */ + + op2_size = -op2_size; + + res_ptr = MPZ_REALLOC (res, op2_size); + op1_ptr = PTR(op1); + + opx = TMP_ALLOC_LIMBS (op2_size); + mpn_sub_1 (opx, PTR(op2), op2_size, (mp_limb_t) 1); + op2_ptr = opx; + op2_size -= op2_ptr[op2_size - 1] == 0; + + if (op1_size >= op2_size) + { + /* We can just ignore the part of OP1 that stretches above OP2, + because the result limbs are zero there. */ + + /* First loop finds the size of the result. */ + for (i = op2_size; --i >= 0;) + if ((~op1_ptr[i] & op2_ptr[i]) != 0) + break; + res_size = i + 1; + count = res_size; + } + else + { + res_size = op2_size; + + /* Copy the part of OP2 that stretches above OP1, to RES. */ + MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size, op2_size - op1_size); + count = op1_size; + } + + if (res_size != 0) + { + /* Second loop computes the real result. */ + if (LIKELY (count != 0)) + mpn_andn_n (res_ptr, op2_ptr, op1_ptr, count); + + cy = mpn_add_1 (res_ptr, res_ptr, res_size, (mp_limb_t) 1); + if (cy) + { + res_ptr[res_size] = cy; + ++res_size; + } + } + else + { + res_ptr[0] = 1; + res_size = 1; + } + + SIZ(res) = -res_size; } + TMP_FREE; } - - { - mp_ptr opx; - mp_limb_t cy; - mp_size_t res_alloc; - mp_size_t count; - - /* Operand 2 negative, so will be the result. - -(OP1 | (-OP2)) = -(OP1 | ~(OP2 - 1)) = - = ~(OP1 | ~(OP2 - 1)) + 1 = - = (~OP1 & (OP2 - 1)) + 1 */ - - op2_size = -op2_size; - - res_alloc = op2_size; - - opx = TMP_ALLOC_LIMBS (op2_size); - mpn_sub_1 (opx, op2_ptr, op2_size, (mp_limb_t) 1); - op2_ptr = opx; - op2_size -= op2_ptr[op2_size - 1] == 0; - - if (ALLOC(res) < res_alloc) - { - _mpz_realloc (res, res_alloc); - op1_ptr = PTR(op1); - /* op2_ptr points to temporary space. */ - res_ptr = PTR(res); - } - - if (op1_size >= op2_size) - { - /* We can just ignore the part of OP1 that stretches above OP2, - because the result limbs are zero there. */ - - /* First loop finds the size of the result. */ - for (i = op2_size - 1; i >= 0; i--) - if ((~op1_ptr[i] & op2_ptr[i]) != 0) - break; - res_size = i + 1; - count = res_size; - } - else - { - res_size = op2_size; - - /* Copy the part of OP2 that stretches above OP1, to RES. */ - MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size, op2_size - op1_size); - count = op1_size; - } - - if (res_size != 0) - { - /* Second loop computes the real result. */ - if (LIKELY (count != 0)) - mpn_andn_n (res_ptr, op2_ptr, op1_ptr, count); - - cy = mpn_add_1 (res_ptr, res_ptr, res_size, (mp_limb_t) 1); - if (cy) - { - res_ptr[res_size] = cy; - res_size++; - } - } - else - { - res_ptr[0] = 1; - res_size = 1; - } - - SIZ(res) = -res_size; - } - TMP_FREE; } |