1 | /* mpn_addmul_1 -- multiply the S1_SIZE long limb vector pointed to by S1_PTR |
2 | by S2_LIMB, add the S1_SIZE least significant limbs of the product to the |
3 | limb vector pointed to by RES_PTR. Return the most significant limb of |
4 | the product, adjusted for carry-out from the addition. |
5 | |
6 | Copyright (C) 1992-2022 Free Software Foundation, Inc. |
7 | |
8 | This file is part of the GNU MP Library. |
9 | |
10 | The GNU MP Library is free software; you can redistribute it and/or modify |
11 | it under the terms of the GNU Lesser General Public License as published by |
12 | the Free Software Foundation; either version 2.1 of the License, or (at your |
13 | option) any later version. |
14 | |
15 | The GNU MP Library is distributed in the hope that it will be useful, but |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
17 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
18 | License for more details. |
19 | |
20 | You should have received a copy of the GNU Lesser General Public License |
21 | along with the GNU MP Library; see the file COPYING.LIB. If not, see |
22 | <https://www.gnu.org/licenses/>. */ |
23 | |
24 | #include <gmp.h> |
25 | #include "gmp-impl.h" |
26 | #include "longlong.h" |
27 | |
28 | mp_limb_t |
29 | mpn_addmul_1 (register mp_ptr res_ptr, register mp_srcptr s1_ptr, |
30 | mp_size_t s1_size, register mp_limb_t s2_limb) |
31 | { |
32 | register mp_limb_t cy_limb; |
33 | register mp_size_t j; |
34 | register mp_limb_t prod_high, prod_low; |
35 | register mp_limb_t x; |
36 | |
37 | /* The loop counter and index J goes from -SIZE to -1. This way |
38 | the loop becomes faster. */ |
39 | j = -s1_size; |
40 | |
41 | /* Offset the base pointers to compensate for the negative indices. */ |
42 | res_ptr -= j; |
43 | s1_ptr -= j; |
44 | |
45 | cy_limb = 0; |
46 | do |
47 | { |
48 | umul_ppmm (prod_high, prod_low, s1_ptr[j], s2_limb); |
49 | |
50 | prod_low += cy_limb; |
51 | cy_limb = (prod_low < cy_limb) + prod_high; |
52 | |
53 | x = res_ptr[j]; |
54 | prod_low = x + prod_low; |
55 | cy_limb += (prod_low < x); |
56 | res_ptr[j] = prod_low; |
57 | } |
58 | while (++j != 0); |
59 | |
60 | return cy_limb; |
61 | } |
62 | |