Switched to GPLv3.
[gnupg.git] / mpi / sparc32 / udiv.S
1 /* SPARC v7 __udiv_qrnnd division support, used from longlong.h.
2  *           This is for v7 CPUs without a floating-point unit.
3  *
4  *      Copyright (C) 1993, 1994, 1996, 1998,
5  *                    2001 Free Software Foundation, Inc.
6  *       
7  * This file is part of GnuPG.
8  *
9  * GnuPG is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * GnuPG is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, see <http://www.gnu.org/licenses/>.
21  *
22  * Note: This code is heavily based on the GNU MP Library.
23  *       Actually it's the same code with only minor changes in the
24  *       way the data is stored; this is to support the abstraction
25  *       of an optional secure memory allocation which may be used
26  *       to avoid revealing of sensitive data due to paging etc.
27  *       The GNU MP Library itself is published under the LGPL;
28  *       however I decided to publish this code under the plain GPL.
29  */
30
31
32 ! INPUT PARAMETERS
33 ! rem_ptr       o0
34 ! n1            o1
35 ! n0            o2
36 ! d             o3
37
38 #include "sysdep.h"
39
40         .text
41         .align 4
42         .global C_SYMBOL_NAME(__udiv_qrnnd)
43 C_SYMBOL_NAME(__udiv_qrnnd):
44         tst     %o3
45         bneg    Largedivisor
46         mov     8,%g1
47
48         b       Lp1
49         addxcc  %o2,%o2,%o2
50
51 Lplop:  bcc     Ln1
52         addxcc  %o2,%o2,%o2
53 Lp1:    addx    %o1,%o1,%o1
54         subcc   %o1,%o3,%o4
55         bcc     Ln2
56         addxcc  %o2,%o2,%o2
57 Lp2:    addx    %o1,%o1,%o1
58         subcc   %o1,%o3,%o4
59         bcc     Ln3
60         addxcc  %o2,%o2,%o2
61 Lp3:    addx    %o1,%o1,%o1
62         subcc   %o1,%o3,%o4
63         bcc     Ln4
64         addxcc  %o2,%o2,%o2
65 Lp4:    addx    %o1,%o1,%o1
66         addcc   %g1,-1,%g1
67         bne     Lplop
68         subcc   %o1,%o3,%o4
69         bcc     Ln5
70         addxcc  %o2,%o2,%o2
71 Lp5:    st      %o1,[%o0]
72         retl
73         xnor    %g0,%o2,%o0
74
75 Lnlop:  bcc     Lp1
76         addxcc  %o2,%o2,%o2
77 Ln1:    addx    %o4,%o4,%o4
78         subcc   %o4,%o3,%o1
79         bcc     Lp2
80         addxcc  %o2,%o2,%o2
81 Ln2:    addx    %o4,%o4,%o4
82         subcc   %o4,%o3,%o1
83         bcc     Lp3
84         addxcc  %o2,%o2,%o2
85 Ln3:    addx    %o4,%o4,%o4
86         subcc   %o4,%o3,%o1
87         bcc     Lp4
88         addxcc  %o2,%o2,%o2
89 Ln4:    addx    %o4,%o4,%o4
90         addcc   %g1,-1,%g1
91         bne     Lnlop
92         subcc   %o4,%o3,%o1
93         bcc     Lp5
94         addxcc  %o2,%o2,%o2
95 Ln5:    st      %o4,[%o0]
96         retl
97         xnor    %g0,%o2,%o0
98
99 Largedivisor:
100         and     %o2,1,%o5       ! %o5 = n0 & 1
101
102         srl     %o2,1,%o2
103         sll     %o1,31,%g2
104         or      %g2,%o2,%o2     ! %o2 = lo(n1n0 >> 1)
105         srl     %o1,1,%o1       ! %o1 = hi(n1n0 >> 1)
106
107         and     %o3,1,%g2
108         srl     %o3,1,%g3       ! %g3 = floor(d / 2)
109         add     %g3,%g2,%g3     ! %g3 = ceil(d / 2)
110
111         b       LLp1
112         addxcc  %o2,%o2,%o2
113
114 LLplop: bcc     LLn1
115         addxcc  %o2,%o2,%o2
116 LLp1:   addx    %o1,%o1,%o1
117         subcc   %o1,%g3,%o4
118         bcc     LLn2
119         addxcc  %o2,%o2,%o2
120 LLp2:   addx    %o1,%o1,%o1
121         subcc   %o1,%g3,%o4
122         bcc     LLn3
123         addxcc  %o2,%o2,%o2
124 LLp3:   addx    %o1,%o1,%o1
125         subcc   %o1,%g3,%o4
126         bcc     LLn4
127         addxcc  %o2,%o2,%o2
128 LLp4:   addx    %o1,%o1,%o1
129         addcc   %g1,-1,%g1
130         bne     LLplop
131         subcc   %o1,%g3,%o4
132         bcc     LLn5
133         addxcc  %o2,%o2,%o2
134 LLp5:   add     %o1,%o1,%o1     ! << 1
135         tst     %g2
136         bne     Oddp
137         add     %o5,%o1,%o1
138         st      %o1,[%o0]
139         retl
140         xnor    %g0,%o2,%o0
141
142 LLnlop: bcc     LLp1
143         addxcc  %o2,%o2,%o2
144 LLn1:   addx    %o4,%o4,%o4
145         subcc   %o4,%g3,%o1
146         bcc     LLp2
147         addxcc  %o2,%o2,%o2
148 LLn2:   addx    %o4,%o4,%o4
149         subcc   %o4,%g3,%o1
150         bcc     LLp3
151         addxcc  %o2,%o2,%o2
152 LLn3:   addx    %o4,%o4,%o4
153         subcc   %o4,%g3,%o1
154         bcc     LLp4
155         addxcc  %o2,%o2,%o2
156 LLn4:   addx    %o4,%o4,%o4
157         addcc   %g1,-1,%g1
158         bne     LLnlop
159         subcc   %o4,%g3,%o1
160         bcc     LLp5
161         addxcc  %o2,%o2,%o2
162 LLn5:   add     %o4,%o4,%o4     ! << 1
163         tst     %g2
164         bne     Oddn
165         add     %o5,%o4,%o4
166         st      %o4,[%o0]
167         retl
168         xnor    %g0,%o2,%o0
169
170 Oddp:   xnor    %g0,%o2,%o2
171         ! q' in %o2. r' in %o1
172         addcc   %o1,%o2,%o1
173         bcc     LLp6
174         addx    %o2,0,%o2
175         sub     %o1,%o3,%o1
176 LLp6:   subcc   %o1,%o3,%g0
177         bcs     LLp7
178         subx    %o2,-1,%o2
179         sub     %o1,%o3,%o1
180 LLp7:   st      %o1,[%o0]
181         retl
182         mov     %o2,%o0
183
184 Oddn:   xnor    %g0,%o2,%o2
185         ! q' in %o2. r' in %o4
186         addcc   %o4,%o2,%o4
187         bcc     LLn6
188         addx    %o2,0,%o2
189         sub     %o4,%o3,%o4
190 LLn6:   subcc   %o4,%o3,%g0
191         bcs     LLn7
192         subx    %o2,-1,%o2
193         sub     %o4,%o3,%o4
194 LLn7:   st      %o4,[%o0]
195         retl
196         mov     %o2,%o0