Switched to GPLv3.
[gnupg.git] / mpi / powerpc32 / mpih-mul3.S
1 /* PowerPC-32 submul_1 -- Multiply a limb vector with a limb and subtract
2  *                        the result from a second limb vector.
3  *
4  * Copyright (C) 1993, 1994, 1995, 1997, 1998 Free Software Foundation, Inc.
5  *
6  * This file is part of GnuPG.
7  *
8  * GnuPG is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * GnuPG is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "sysdep.h"
23 #include "asm-syntax.h"
24
25
26 #ifndef USE_PPC_PATCHES
27
28 /*******************
29  * mpi_limb_t
30  * mpihelp_submul_1( mpi_ptr_t res_ptr,      (r3)
31  *                   mpi_ptr_t s1_ptr,       (r4)
32  *                   mpi_size_t s1_size,     (r5)
33  *                   mpi_limb_t s2_limb)     (r6)
34  *
35  * This is a fairly straightforward implementation.  The timing of the PC601
36  * is hard to understand, so I will wait to optimize this until I have some
37  * hardware to play with.
38  *
39  * The code trivially generalizes to 64 bit limbs for the PC620.
40  */
41
42         .toc
43         .csect .mpihelp_submul_1[PR]
44         .align 2
45         .globl mpihelp_submul_1
46         .globl .mpihelp_submul_1
47         .csect mpihelp_submul_1[DS]
48 mpihelp_submul_1:
49         .long .mpihelp_submul_1[PR], TOC[tc0], 0
50         .csect .mpihelp_submul_1[PR]
51 .mpihelp_submul_1:
52         mtctr   5
53
54         lwz     0,0(4)
55         mullw   7,0,6
56         mulhwu  10,0,6
57         lwz     9,0(3)
58         subfc   8,7,9
59         addc    7,7,8           # invert cy (r7 is junk)
60         addi    3,3,-4
61         bdz     Lend
62
63 Loop:   lwzu    0,4(4)
64         stwu    8,4(3)
65         mullw   8,0,6
66         adde    7,8,10
67         mulhwu  10,0,6
68         lwz     9,4(3)
69         addze   10,10
70         subfc   8,7,9
71         addc    7,7,8           # invert cy (r7 is junk)
72         bdnz    Loop
73
74 Lend:   stw     8,4(3)
75         addze   3,10
76         blr
77
78 #else
79
80 /* mp_limb_t mpn_submul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
81                            mp_size_t s1_size, mp_limb_t s2_limb)
82    Calculate res-s1*s2 and put result back in res; return carry.  */
83
84 ENTRY(mpihelp_submul_1)
85        mtctr   %r5
86
87        lwz     %r0,0(%r4)
88        mullw   %r7,%r0,%r6
89        mulhwu  %r10,%r0,%r6
90        lwz     %r9,0(%r3)
91        subf    %r8,%r7,%r9
92        addc    %r7,%r7,%r8             # invert cy (r7 is junk)
93        addi    %r3,%r3,-4              # adjust res_ptr
94        bdz     1f
95
96 0:     lwzu    %r0,4(%r4)
97        stwu    %r8,4(%r3)
98        mullw   %r8,%r0,%r6
99        adde    %r7,%r8,%r10
100        mulhwu  %r10,%r0,%r6
101        lwz     %r9,4(%r3)
102        addze   %r10,%r10
103        subf    %r8,%r7,%r9
104        addc    %r7,%r7,%r8             # invert cy (r7 is junk)
105        bdnz    0b
106
107 1:     stw     %r8,4(%r3)
108        addze   %r3,%r10
109        blr
110 END(mpihelp_submul_1)
111 #endif