ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / sparc64 / lib / VISbzero.S
1 /* $Id: VISbzero.S,v 1.11 2001/03/15 08:51:24 anton Exp $
2  * VISbzero.S: High speed clear operations utilizing the UltraSparc
3  *        Visual Instruction Set.
4  *
5  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
6  * Copyright (C) 1996, 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz)
7  */
8
9 #include "VIS.h"
10
11 #ifdef __KERNEL__
12 #include <asm/visasm.h>
13
14 #define EXN(x,y,a,b,z)                          \
15 98:     x,y;                                    \
16         .section .fixup;                        \
17         .align  4;                              \
18 99:     ba      VISbzerofixup_ret##z;           \
19          a, b, %o0;                             \
20         .section __ex_table;                    \
21         .align  4;                              \
22         .word   98b, 99b;                       \
23         .text;                                  \
24         .align  4;
25 #define EXC(x,y,a,b,c...)                       \
26 98:     x,y;                                    \
27         .section .fixup;                        \
28         .align  4;                              \
29 99:     c;                                      \
30         ba      VISbzerofixup_ret0;             \
31          a, b, %o0;                             \
32         .section __ex_table;                    \
33         .align  4;                              \
34         .word   98b, 99b;                       \
35         .text;                                  \
36         .align  4;
37 #define EXO1(x,y)                               \
38 98:     x,y;                                    \
39         .section __ex_table;                    \
40         .align  4;                              \
41         .word   98b, VISbzerofixup_reto1;       \
42         .text;                                  \
43         .align  4;
44 #define EX(x,y,a,b) EXN(x,y,a,b,0)
45 #define EX1(x,y,a,b) EXN(x,y,a,b,1)
46 #define EX2(x,y,a,b) EXN(x,y,a,b,2)
47 #define EXT(start,end,handler)                  \
48         .section __ex_table;                    \
49         .align  4;                              \
50         .word   start, 0, end, handler;         \
51         .text;                                  \
52         .align  4
53 #else
54 #define EX(x,y,a,b)             x,y
55 #define EX1(x,y,a,b)            x,y
56 #define EX2(x,y,a,b)            x,y
57 #define EXC(x,y,a,b,c...)       x,y
58 #define EXO1(x,y)               x,y
59 #define EXT(a,b,c)
60 #endif
61
62 #define ZERO_BLOCKS(base, offset, source)                       \
63         STX     source, [base - offset - 0x38] ASINORMAL;       \
64         STX     source, [base - offset - 0x30] ASINORMAL;       \
65         STX     source, [base - offset - 0x28] ASINORMAL;       \
66         STX     source, [base - offset - 0x20] ASINORMAL;       \
67         STX     source, [base - offset - 0x18] ASINORMAL;       \
68         STX     source, [base - offset - 0x10] ASINORMAL;       \
69         STX     source, [base - offset - 0x08] ASINORMAL;       \
70         STX     source, [base - offset - 0x00] ASINORMAL;
71
72 #ifdef __KERNEL__
73 #define RETL    clr %o0
74 #else
75 #define RETL    mov %g3, %o0
76 #endif
77
78         /* Well, bzero is a lot easier to get right than bcopy... */
79 #ifdef __KERNEL__
80         .section        __ex_table,#alloc
81         .section        .fixup,#alloc,#execinstr
82 #endif
83         .text
84         .align          32
85 #ifdef __KERNEL__
86         .globl          __bzero_begin
87 __bzero_begin:
88         .globl          __bzero, __bzero_noasi
89 __bzero_noasi:
90         rd              %asi, %g5
91         ba,pt           %xcc, __bzero+12
92          mov            %g5, %o4
93 __bzero:
94         rd              %asi, %g5
95         wr              %g0, ASI_P, %asi                ! LSU   Group
96         mov             ASI_P, %o4
97 #else
98         .globl          bzero
99 bzero_private:
100 bzero:
101 #ifndef REGS_64BIT
102         srl             %o1, 0, %o1
103 #endif
104         mov             %o0, %g3
105 #endif
106         cmp             %o1, 7
107         bleu,pn         %xcc, 17f
108          andcc          %o0, 3, %o2
109         be,a,pt         %xcc, 4f
110          andcc          %o0, 4, %g0
111         cmp             %o2, 3
112         be,pn           %xcc, 2f
113          EXO1(STB       %g0, [%o0 + 0x00] ASINORMAL)
114         cmp             %o2, 2
115         be,pt           %xcc, 2f
116          EX(STB         %g0, [%o0 + 0x01] ASINORMAL, sub %o1, 1)
117         EX(STB          %g0, [%o0 + 0x02] ASINORMAL, sub %o1, 2)
118 2:      sub             %o2, 4, %o2
119         sub             %o0, %o2, %o0
120         add             %o1, %o2, %o1
121         andcc           %o0, 4, %g0
122 4:      be,pt           %xcc, 2f
123          cmp            %o1, 128
124         EXO1(STW        %g0, [%o0] ASINORMAL)
125         sub             %o1, 4, %o1
126         add             %o0, 4, %o0
127 2:      blu,pn          %xcc, 9f
128          andcc          %o0, 0x38, %o2
129         be,pn           %icc, 6f
130          mov            64, %o5
131         andcc           %o0, 8, %g0
132         be,pn           %icc, 1f
133          sub            %o5, %o2, %o5
134         EX(STX          %g0, [%o0] ASINORMAL, sub %o1, 0)
135         add             %o0, 8, %o0
136 1:      andcc           %o5, 16, %g0
137         be,pn           %icc, 1f
138          sub            %o1, %o5, %o1
139         EX1(STX         %g0, [%o0] ASINORMAL, add %g0, 0)
140         EX1(STX         %g0, [%o0 + 8] ASINORMAL, sub %g0, 8)
141         add             %o0, 16, %o0
142 1:      andcc           %o5, 32, %g0
143         be,pn           %icc, 7f
144          andncc         %o1, 0x3f, %o3
145         EX(STX          %g0, [%o0] ASINORMAL, add %o1, 32)
146         EX(STX          %g0, [%o0 + 8] ASINORMAL, add %o1, 24)
147         EX(STX          %g0, [%o0 + 16] ASINORMAL, add %o1, 16)
148         EX(STX          %g0, [%o0 + 24] ASINORMAL, add %o1, 8)
149         add             %o0, 32, %o0
150 6:      andncc          %o1, 0x3f, %o3
151 7:      be,pn           %xcc, 9f
152 #ifdef __KERNEL__
153          or             %o4, ASI_BLK_OR, %g7 
154         wr              %g7, %g0, %asi
155         VISEntryHalf
156 #else
157          wr             %g0, ASI_BLK_P, %asi
158 #endif
159         membar          #StoreLoad | #StoreStore | #LoadStore
160         fzero           %f0
161         andcc           %o3, 0xc0, %o2
162         and             %o1, 0x3f, %o1
163         fzero           %f2
164         andn            %o3, 0xff, %o3
165         faddd           %f0, %f2, %f4
166         fmuld           %f0, %f2, %f6
167         cmp             %o2, 64
168         faddd           %f0, %f2, %f8
169         fmuld           %f0, %f2, %f10
170         faddd           %f0, %f2, %f12
171         brz,pn          %o2, 10f
172          fmuld          %f0, %f2, %f14
173         be,pn           %icc, 2f
174          EXC(STBLK      %f0, [%o0 + 0x00] ASIBLK, add %o3, %o2, add %o2, %o1, %o2)
175         cmp             %o2, 128
176         be,pn           %icc, 2f
177          EXC(STBLK      %f0, [%o0 + 0x40] ASIBLK, add %o3, %o2, add %o2, %o1, %o2; sub %o2, 64, %o2)
178         EXC(STBLK       %f0, [%o0 + 0x80] ASIBLK, add %o3, %o2, add %o2, %o1, %o2; sub %o2, 128, %o2)
179 2:      brz,pn          %o3, 12f
180          add            %o0, %o2, %o0
181 10:     EX(STBLK        %f0, [%o0 + 0x00] ASIBLK, add %o3, %o1)
182         EXC(STBLK       %f0, [%o0 + 0x40] ASIBLK, add %o3, %o1, sub %o1, 64, %o1)
183         EXC(STBLK       %f0, [%o0 + 0x80] ASIBLK, add %o3, %o1, sub %o1, 128, %o1)
184         EXC(STBLK       %f0, [%o0 + 0xc0] ASIBLK, add %o3, %o1, sub %o1, 192, %o1)
185 11:     subcc           %o3, 256, %o3
186         bne,pt          %xcc, 10b
187          add            %o0, 256, %o0
188 12:
189 #ifdef __KERNEL__
190         VISExitHalf
191         wr              %o4, 0x0, %asi
192 #else
193 #ifndef REGS_64BIT
194         wr              %g0, FPRS_FEF, %fprs
195 #endif
196 #endif
197         membar          #StoreLoad | #StoreStore
198 9:      andcc           %o1, 0xf8, %o2
199         be,pn           %xcc, 13f
200          andcc          %o1, 7, %o1
201 #ifdef __KERNEL__
202 14:     sethi           %hi(13f), %o4
203         srl             %o2, 1, %o3
204         sub             %o4, %o3, %o4
205         jmpl            %o4 + %lo(13f), %g0
206          add            %o0, %o2, %o0
207 #else
208 14:     rd              %pc, %o4
209         srl             %o2, 1, %o3
210         sub             %o4, %o3, %o4
211         jmpl            %o4 + (13f - 14b), %g0
212          add            %o0, %o2, %o0
213 #endif
214 12:     ZERO_BLOCKS(%o0, 0xc8, %g0)
215         ZERO_BLOCKS(%o0, 0x88, %g0)
216         ZERO_BLOCKS(%o0, 0x48, %g0)
217         ZERO_BLOCKS(%o0, 0x08, %g0)
218         EXT(12b,13f,VISbzerofixup_zb)
219 13:     be,pn           %xcc, 8f
220          andcc          %o1, 4, %g0
221         be,pn           %xcc, 1f
222          andcc          %o1, 2, %g0
223         EX(STW          %g0, [%o0] ASINORMAL, and %o1, 7)
224         add             %o0, 4, %o0
225 1:      be,pn           %xcc, 1f
226          andcc          %o1, 1, %g0
227         EX(STH          %g0, [%o0] ASINORMAL, and %o1, 3)
228         add             %o0, 2, %o0
229 1:      bne,a,pn        %xcc, 8f
230          EX(STB         %g0, [%o0] ASINORMAL, add %g0, 1)
231 8:
232 #ifdef __KERNEL__
233         wr              %g5, %g0, %asi
234 #endif
235         retl
236          RETL
237 17:     be,pn           %xcc, 13b
238          orcc           %o1, 0, %g0
239         be,pn           %xcc, 0f
240 8:       add            %o0, 1, %o0
241         subcc           %o1, 1, %o1
242         bne,pt          %xcc, 8b
243          EX(STB         %g0, [%o0 - 1] ASINORMAL, add %o1, 1)
244 0:
245 #ifdef __KERNEL__
246         wr              %g5, %g0, %asi
247 #endif
248         retl
249          RETL
250
251 #ifdef __KERNEL__
252         .section        .fixup
253         .align          4
254 VISbzerofixup_reto1:
255         mov             %o1, %o0
256 VISbzerofixup_ret0:
257         wr              %g5, %g0, %asi
258         retl
259          wr             %g0, 0, %fprs
260 VISbzerofixup_ret1:
261         and             %o5, 0x30, %o5
262         add             %o5, %o1, %o5
263         ba,pt           %xcc, VISbzerofixup_ret0
264          add            %o0, %o5, %o0
265 VISbzerofixup_ret2:
266         and             %o5, 0x20, %o5
267         add             %o5, %o1, %o5
268         ba,pt           %xcc, VISbzerofixup_ret0
269          add            %o0, %o5, %o0
270 VISbzerofixup_zb:
271         andcc           %o1, 7, %o1
272         sll             %g2, 3, %g2
273         add             %o1, 256, %o1
274         ba,pt           %xcc, VISbzerofixup_ret0
275          sub            %o1, %g2, %o0
276 #endif
277         .globl          __bzero_end
278 __bzero_end: