Merge branch 'gup_flag-cleanups'
[cascardo/linux.git] / arch / sparc / lib / memscan_64.S
1 /*
2  * memscan.S: Optimized memscan for Sparc64.
3  *
4  * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz)
5  * Copyright (C) 1998 David S. Miller (davem@redhat.com)
6  */
7
8         #include <asm/export.h>
9
10 #define HI_MAGIC        0x8080808080808080
11 #define LO_MAGIC        0x0101010101010101
12 #define ASI_PL          0x88
13
14         .text
15         .align  32
16         .globl          __memscan_zero, __memscan_generic
17         .globl          memscan
18         EXPORT_SYMBOL(__memscan_zero)
19         EXPORT_SYMBOL(__memscan_generic)
20
21 __memscan_zero:
22         /* %o0 = bufp, %o1 = size */
23         brlez,pn        %o1, szzero
24          andcc          %o0, 7, %g0
25         be,pt           %icc, we_are_aligned
26          sethi          %hi(HI_MAGIC), %o4
27         ldub            [%o0], %o5
28 1:      subcc           %o1, 1, %o1
29         brz,pn          %o5, 10f
30          add            %o0, 1, %o0
31
32         be,pn           %xcc, szzero
33          andcc          %o0, 7, %g0
34         bne,a,pn        %icc, 1b
35          ldub           [%o0], %o5
36 we_are_aligned:
37         ldxa            [%o0] ASI_PL, %o5
38         or              %o4, %lo(HI_MAGIC), %o3
39         sllx            %o3, 32, %o4
40         or              %o4, %o3, %o3
41
42         srlx            %o3, 7, %o2
43 msloop:
44         sub             %o1, 8, %o1
45         add             %o0, 8, %o0
46         sub             %o5, %o2, %o4
47         xor             %o4, %o5, %o4
48         andcc           %o4, %o3, %g3
49         bne,pn          %xcc, check_bytes
50          srlx           %o4, 32, %g3
51
52         brgz,a,pt       %o1, msloop
53          ldxa           [%o0] ASI_PL, %o5
54 check_bytes:
55         bne,a,pn        %icc, 2f
56          andcc          %o5, 0xff, %g0
57         add             %o0, -5, %g2
58         ba,pt           %xcc, 3f
59          srlx           %o5, 32, %g7
60
61 2:      srlx            %o5, 8, %g7
62         be,pn           %icc, 1f
63          add            %o0, -8, %g2
64         andcc           %g7, 0xff, %g0
65         srlx            %g7, 8, %g7
66         be,pn           %icc, 1f
67          inc            %g2
68         andcc           %g7, 0xff, %g0
69
70         srlx            %g7, 8, %g7
71         be,pn           %icc, 1f
72          inc            %g2
73         andcc           %g7, 0xff, %g0
74         srlx            %g7, 8, %g7
75         be,pn           %icc, 1f
76          inc            %g2
77         andcc           %g3, %o3, %g0
78
79         be,a,pn         %icc, 2f
80          mov            %o0, %g2
81 3:      andcc           %g7, 0xff, %g0
82         srlx            %g7, 8, %g7
83         be,pn           %icc, 1f
84          inc            %g2
85         andcc           %g7, 0xff, %g0
86         srlx            %g7, 8, %g7
87
88         be,pn           %icc, 1f
89          inc            %g2
90         andcc           %g7, 0xff, %g0
91         srlx            %g7, 8, %g7
92         be,pn           %icc, 1f
93          inc            %g2
94         andcc           %g7, 0xff, %g0
95         srlx            %g7, 8, %g7
96
97         be,pn           %icc, 1f
98          inc            %g2
99 2:      brgz,a,pt       %o1, msloop
100          ldxa           [%o0] ASI_PL, %o5
101         inc             %g2
102 1:      add             %o0, %o1, %o0
103         cmp             %g2, %o0
104         retl
105
106          movle          %xcc, %g2, %o0
107 10:     retl
108          sub            %o0, 1, %o0
109 szzero: retl
110          nop
111
112 memscan:
113 __memscan_generic:
114         /* %o0 = addr, %o1 = c, %o2 = size */
115         brz,pn          %o2, 3f
116          add            %o0, %o2, %o3
117         ldub            [%o0], %o5
118         sub             %g0, %o2, %o4
119 1:
120         cmp             %o5, %o1
121         be,pn           %icc, 2f
122          addcc          %o4, 1, %o4
123         bne,a,pt        %xcc, 1b
124          ldub           [%o3 + %o4], %o5
125         retl
126         /* The delay slot is the same as the next insn, this is just to make it look more awful */
127 2:
128          add            %o3, %o4, %o0
129         retl
130          sub            %o0, 1, %o0
131 3:
132         retl
133          nop