FIX BUILD (with GHC 6.2.x): System.Directory.Internals is no more
[ghc-hetmet.git] / rts / gmp / mpn / sparc32 / add_n.asm
1 dnl  SPARC mpn_add_n -- Add two limb vectors of the same length > 0 and store
2 dnl  sum in a third limb vector.
3
4 dnl  Copyright (C) 1995, 1996, 2000 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 2.1 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; see the file COPYING.LIB.  If not, write to
20 dnl  the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21 dnl  MA 02111-1307, USA.
22
23
24 include(`../config.m4')
25
26 C INPUT PARAMETERS
27 define(res_ptr,%o0)
28 define(s1_ptr,%o1)
29 define(s2_ptr,%o2)
30 define(n,%o3)
31
32 ASM_START()
33 PROLOGUE(mpn_add_n)
34         xor     s2_ptr,res_ptr,%g1
35         andcc   %g1,4,%g0
36         bne     L(1)                    C branch if alignment differs
37         nop
38 C **  V1a  **
39 L(0):   andcc   res_ptr,4,%g0           C res_ptr unaligned? Side effect: cy=0
40         be      L(v1)                   C if no, branch
41         nop
42 C Add least significant limb separately to align res_ptr and s2_ptr
43         ld      [s1_ptr],%g4
44         add     s1_ptr,4,s1_ptr
45         ld      [s2_ptr],%g2
46         add     s2_ptr,4,s2_ptr
47         add     n,-1,n
48         addcc   %g4,%g2,%o4
49         st      %o4,[res_ptr]
50         add     res_ptr,4,res_ptr
51 L(v1):  addx    %g0,%g0,%o4             C save cy in register
52         cmp     n,2                     C if n < 2 ...
53         bl      L(end2)                 C ... branch to tail code
54         subcc   %g0,%o4,%g0             C restore cy
55
56         ld      [s1_ptr+0],%g4
57         addcc   n,-10,n
58         ld      [s1_ptr+4],%g1
59         ldd     [s2_ptr+0],%g2
60         blt     L(fin1)
61         subcc   %g0,%o4,%g0             C restore cy
62 C Add blocks of 8 limbs until less than 8 limbs remain
63 L(loop1):
64         addxcc  %g4,%g2,%o4
65         ld      [s1_ptr+8],%g4
66         addxcc  %g1,%g3,%o5
67         ld      [s1_ptr+12],%g1
68         ldd     [s2_ptr+8],%g2
69         std     %o4,[res_ptr+0]
70         addxcc  %g4,%g2,%o4
71         ld      [s1_ptr+16],%g4
72         addxcc  %g1,%g3,%o5
73         ld      [s1_ptr+20],%g1
74         ldd     [s2_ptr+16],%g2
75         std     %o4,[res_ptr+8]
76         addxcc  %g4,%g2,%o4
77         ld      [s1_ptr+24],%g4
78         addxcc  %g1,%g3,%o5
79         ld      [s1_ptr+28],%g1
80         ldd     [s2_ptr+24],%g2
81         std     %o4,[res_ptr+16]
82         addxcc  %g4,%g2,%o4
83         ld      [s1_ptr+32],%g4
84         addxcc  %g1,%g3,%o5
85         ld      [s1_ptr+36],%g1
86         ldd     [s2_ptr+32],%g2
87         std     %o4,[res_ptr+24]
88         addx    %g0,%g0,%o4             C save cy in register
89         addcc   n,-8,n
90         add     s1_ptr,32,s1_ptr
91         add     s2_ptr,32,s2_ptr
92         add     res_ptr,32,res_ptr
93         bge     L(loop1)
94         subcc   %g0,%o4,%g0             C restore cy
95
96 L(fin1):
97         addcc   n,8-2,n
98         blt     L(end1)
99         subcc   %g0,%o4,%g0             C restore cy
100 C Add blocks of 2 limbs until less than 2 limbs remain
101 L(loope1):
102         addxcc  %g4,%g2,%o4
103         ld      [s1_ptr+8],%g4
104         addxcc  %g1,%g3,%o5
105         ld      [s1_ptr+12],%g1
106         ldd     [s2_ptr+8],%g2
107         std     %o4,[res_ptr+0]
108         addx    %g0,%g0,%o4             C save cy in register
109         addcc   n,-2,n
110         add     s1_ptr,8,s1_ptr
111         add     s2_ptr,8,s2_ptr
112         add     res_ptr,8,res_ptr
113         bge     L(loope1)
114         subcc   %g0,%o4,%g0             C restore cy
115 L(end1):
116         addxcc  %g4,%g2,%o4
117         addxcc  %g1,%g3,%o5
118         std     %o4,[res_ptr+0]
119         addx    %g0,%g0,%o4             C save cy in register
120
121         andcc   n,1,%g0
122         be      L(ret1)
123         subcc   %g0,%o4,%g0             C restore cy
124 C Add last limb
125         ld      [s1_ptr+8],%g4
126         ld      [s2_ptr+8],%g2
127         addxcc  %g4,%g2,%o4
128         st      %o4,[res_ptr+8]
129
130 L(ret1):
131         retl
132         addx    %g0,%g0,%o0     C return carry-out from most sign. limb
133
134 L(1):   xor     s1_ptr,res_ptr,%g1
135         andcc   %g1,4,%g0
136         bne     L(2)
137         nop
138 C **  V1b  **
139         mov     s2_ptr,%g1
140         mov     s1_ptr,s2_ptr
141         b       L(0)
142         mov     %g1,s1_ptr
143
144 C **  V2  **
145 C If we come here, the alignment of s1_ptr and res_ptr as well as the
146 C alignment of s2_ptr and res_ptr differ.  Since there are only two ways
147 C things can be aligned (that we care about) we now know that the alignment
148 C of s1_ptr and s2_ptr are the same.
149
150 L(2):   cmp     n,1
151         be      L(jone)
152         nop
153         andcc   s1_ptr,4,%g0            C s1_ptr unaligned? Side effect: cy=0
154         be      L(v2)                   C if no, branch
155         nop
156 C Add least significant limb separately to align s1_ptr and s2_ptr
157         ld      [s1_ptr],%g4
158         add     s1_ptr,4,s1_ptr
159         ld      [s2_ptr],%g2
160         add     s2_ptr,4,s2_ptr
161         add     n,-1,n
162         addcc   %g4,%g2,%o4
163         st      %o4,[res_ptr]
164         add     res_ptr,4,res_ptr
165
166 L(v2):  addx    %g0,%g0,%o4             C save cy in register
167         addcc   n,-8,n
168         blt     L(fin2)
169         subcc   %g0,%o4,%g0             C restore cy
170 C Add blocks of 8 limbs until less than 8 limbs remain
171 L(loop2):
172         ldd     [s1_ptr+0],%g2
173         ldd     [s2_ptr+0],%o4
174         addxcc  %g2,%o4,%g2
175         st      %g2,[res_ptr+0]
176         addxcc  %g3,%o5,%g3
177         st      %g3,[res_ptr+4]
178         ldd     [s1_ptr+8],%g2
179         ldd     [s2_ptr+8],%o4
180         addxcc  %g2,%o4,%g2
181         st      %g2,[res_ptr+8]
182         addxcc  %g3,%o5,%g3
183         st      %g3,[res_ptr+12]
184         ldd     [s1_ptr+16],%g2
185         ldd     [s2_ptr+16],%o4
186         addxcc  %g2,%o4,%g2
187         st      %g2,[res_ptr+16]
188         addxcc  %g3,%o5,%g3
189         st      %g3,[res_ptr+20]
190         ldd     [s1_ptr+24],%g2
191         ldd     [s2_ptr+24],%o4
192         addxcc  %g2,%o4,%g2
193         st      %g2,[res_ptr+24]
194         addxcc  %g3,%o5,%g3
195         st      %g3,[res_ptr+28]
196         addx    %g0,%g0,%o4             C save cy in register
197         addcc   n,-8,n
198         add     s1_ptr,32,s1_ptr
199         add     s2_ptr,32,s2_ptr
200         add     res_ptr,32,res_ptr
201         bge     L(loop2)
202         subcc   %g0,%o4,%g0             C restore cy
203
204 L(fin2):
205         addcc   n,8-2,n
206         blt     L(end2)
207         subcc   %g0,%o4,%g0             C restore cy
208 L(loope2):
209         ldd     [s1_ptr+0],%g2
210         ldd     [s2_ptr+0],%o4
211         addxcc  %g2,%o4,%g2
212         st      %g2,[res_ptr+0]
213         addxcc  %g3,%o5,%g3
214         st      %g3,[res_ptr+4]
215         addx    %g0,%g0,%o4             C save cy in register
216         addcc   n,-2,n
217         add     s1_ptr,8,s1_ptr
218         add     s2_ptr,8,s2_ptr
219         add     res_ptr,8,res_ptr
220         bge     L(loope2)
221         subcc   %g0,%o4,%g0             C restore cy
222 L(end2):
223         andcc   n,1,%g0
224         be      L(ret2)
225         subcc   %g0,%o4,%g0             C restore cy
226 C Add last limb
227 L(jone):
228         ld      [s1_ptr],%g4
229         ld      [s2_ptr],%g2
230         addxcc  %g4,%g2,%o4
231         st      %o4,[res_ptr]
232
233 L(ret2):
234         retl
235         addx    %g0,%g0,%o0     C return carry-out from most sign. limb
236 EPILOGUE(mpn_add_n)