3c3492d00c5b69ad1f9e8d0fb1a04322fa3d0541
[platform/upstream/gmp.git] / mpn / power / submul_1.asm
1 dnl  IBM POWER mpn_submul_1 -- Multiply a limb vector with a limb and subtract
2 dnl  the result from a second limb vector.
3
4 dnl  Copyright 1992, 1994, 1999, 2000, 2001 Free Software Foundation, Inc.
5
6 dnl  This file is part of the GNU MP Library.
7
8 dnl  The GNU MP Library is free software; you can redistribute it and/or modify
9 dnl  it under the terms of the GNU Lesser General Public License as published
10 dnl  by the Free Software Foundation; either version 3 of the License, or (at
11 dnl  your option) any later version.
12
13 dnl  The GNU MP Library is distributed in the hope that it will be useful, but
14 dnl  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 dnl  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16 dnl  License for more details.
17
18 dnl  You should have received a copy of the GNU Lesser General Public License
19 dnl  along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
20
21
22 dnl  INPUT PARAMETERS
23 dnl  res_ptr    r3
24 dnl  s1_ptr     r4
25 dnl  size       r5
26 dnl  s2_limb    r6
27
28 dnl  The POWER architecture has no unsigned 32x32->64 bit multiplication
29 dnl  instruction.  To obtain that operation, we have to use the 32x32->64
30 dnl  signed multiplication instruction, and add the appropriate compensation to
31 dnl  the high limb of the result.  We add the multiplicand if the multiplier
32 dnl  has its most significant bit set, and we add the multiplier if the
33 dnl  multiplicand has its most significant bit set.  We need to preserve the
34 dnl  carry flag between each iteration, so we have to compute the compensation
35 dnl  carefully (the natural, srai+and doesn't work).  Since all POWER can
36 dnl  branch in zero cycles, we use conditional branches for the compensation.
37
38 include(`../config.m4')
39
40 ASM_START()
41 PROLOGUE(mpn_submul_1)
42         cal     3,-4(3)
43         l       0,0(4)
44         cmpi    0,6,0
45         mtctr   5
46         mul     9,0,6
47         srai    7,0,31
48         and     7,7,6
49         mfmq    11
50         cax     9,9,7
51         l       7,4(3)
52         sf      8,11,7          C add res_limb
53         a       11,8,11         C invert cy (r11 is junk)
54         blt     Lneg
55 Lpos:   bdz     Lend
56
57 Lploop: lu      0,4(4)
58         stu     8,4(3)
59         cmpi    0,0,0
60         mul     10,0,6
61         mfmq    0
62         ae      11,0,9          C low limb + old_cy_limb + old cy
63         l       7,4(3)
64         aze     10,10           C propagate cy to new cy_limb
65         sf      8,11,7          C add res_limb
66         a       11,8,11         C invert cy (r11 is junk)
67         bge     Lp0
68         cax     10,10,6         C adjust high limb for negative limb from s1
69 Lp0:    bdz     Lend0
70         lu      0,4(4)
71         stu     8,4(3)
72         cmpi    0,0,0
73         mul     9,0,6
74         mfmq    0
75         ae      11,0,10
76         l       7,4(3)
77         aze     9,9
78         sf      8,11,7
79         a       11,8,11         C invert cy (r11 is junk)
80         bge     Lp1
81         cax     9,9,6           C adjust high limb for negative limb from s1
82 Lp1:    bdn     Lploop
83
84         b       Lend
85
86 Lneg:   cax     9,9,0
87         bdz     Lend
88 Lnloop: lu      0,4(4)
89         stu     8,4(3)
90         cmpi    0,0,0
91         mul     10,0,6
92         mfmq    7
93         ae      11,7,9
94         l       7,4(3)
95         ae      10,10,0         C propagate cy to new cy_limb
96         sf      8,11,7          C add res_limb
97         a       11,8,11         C invert cy (r11 is junk)
98         bge     Ln0
99         cax     10,10,6         C adjust high limb for negative limb from s1
100 Ln0:    bdz     Lend0
101         lu      0,4(4)
102         stu     8,4(3)
103         cmpi    0,0,0
104         mul     9,0,6
105         mfmq    7
106         ae      11,7,10
107         l       7,4(3)
108         ae      9,9,0           C propagate cy to new cy_limb
109         sf      8,11,7          C add res_limb
110         a       11,8,11         C invert cy (r11 is junk)
111         bge     Ln1
112         cax     9,9,6           C adjust high limb for negative limb from s1
113 Ln1:    bdn     Lnloop
114         b       Lend
115
116 Lend0:  cal     9,0(10)
117 Lend:   st      8,4(3)
118         aze     3,9
119         br
120 EPILOGUE(mpn_submul_1)