Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
[linux-2.6] / arch / sparc64 / lib / strncpy_from_user.S
1 /* $Id: strncpy_from_user.S,v 1.6 1999/05/25 16:53:05 jj Exp $
2  * strncpy_from_user.S: Sparc64 strncpy from userspace.
3  *
4  *  Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz)
5  */
6
7 #include <asm/asi.h>
8 #include <asm/errno.h>
9
10         .data
11         .align  8
12 0:      .xword  0x0101010101010101
13
14         .text
15         .align  32
16
17         /* Must return:
18          *
19          * -EFAULT              for an exception
20          * count                if we hit the buffer limit
21          * bytes copied         if we hit a null byte
22          * (without the null byte)
23          *
24          * This implementation assumes:
25          * %o1 is 8 aligned => !(%o2 & 7)
26          * %o0 is 8 aligned (if not, it will be slooooow, but will work)
27          *
28          * This is optimized for the common case:
29          * in my stats, 90% of src are 8 aligned (even on sparc32)
30          * and average length is 18 or so.
31          */
32
33         .globl  __strncpy_from_user
34         .type   __strncpy_from_user,#function
35 __strncpy_from_user:
36         /* %o0=dest, %o1=src, %o2=count */
37         andcc   %o1, 7, %g0             ! IEU1  Group
38         bne,pn  %icc, 30f               ! CTI
39          add    %o0, %o2, %g3           ! IEU0
40 60:     ldxa    [%o1] %asi, %g1         ! Load  Group
41         brlez,pn %o2, 10f               ! CTI
42          mov    %o0, %o3                ! IEU0
43 50:     sethi   %hi(0b), %o4            ! IEU0  Group
44         ldx     [%o4 + %lo(0b)], %o4    ! Load
45         sllx    %o4, 7, %o5             ! IEU1  Group
46 1:      sub     %g1, %o4, %g2           ! IEU0  Group
47         stx     %g1, [%o0]              ! Store
48         add     %o0, 8, %o0             ! IEU1
49         andcc   %g2, %o5, %g0           ! IEU1  Group
50         bne,pn  %xcc, 5f                ! CTI
51          add    %o1, 8, %o1             ! IEU0
52         cmp     %o0, %g3                ! IEU1  Group
53         bl,a,pt %xcc, 1b                ! CTI
54 61:      ldxa   [%o1] %asi, %g1         ! Load
55 10:     retl                            ! CTI   Group
56          mov    %o2, %o0                ! IEU0
57 5:      srlx    %g2, 32, %g7            ! IEU0  Group
58         sethi   %hi(0xff00), %o4        ! IEU1
59         andcc   %g7, %o5, %g0           ! IEU1  Group
60         be,pn   %icc, 2f                ! CTI
61          or     %o4, %lo(0xff00), %o4   ! IEU0
62         srlx    %g1, 48, %g7            ! IEU0  Group
63         andcc   %g7, %o4, %g0           ! IEU1  Group
64         be,pn   %icc, 50f               ! CTI
65          andcc  %g7, 0xff, %g0          ! IEU1  Group
66         be,pn   %icc, 51f               ! CTI
67          srlx   %g1, 32, %g7            ! IEU0
68         andcc   %g7, %o4, %g0           ! IEU1  Group
69         be,pn   %icc, 52f               ! CTI
70          andcc  %g7, 0xff, %g0          ! IEU1  Group
71         be,pn   %icc, 53f               ! CTI
72 2:       andcc  %g2, %o5, %g0           ! IEU1  Group
73         be,pn   %icc, 2f                ! CTI
74          srl    %g1, 16, %g7            ! IEU0
75         andcc   %g7, %o4, %g0           ! IEU1  Group
76         be,pn   %icc, 54f               ! CTI
77          andcc  %g7, 0xff, %g0          ! IEU1  Group
78         be,pn   %icc, 55f               ! CTI
79          andcc  %g1, %o4, %g0           ! IEU1  Group
80         be,pn   %icc, 56f               ! CTI
81          andcc  %g1, 0xff, %g0          ! IEU1  Group
82         be,a,pn %icc, 57f               ! CTI
83          sub    %o0, %o3, %o0           ! IEU0
84 2:      cmp     %o0, %g3                ! IEU1  Group
85         bl,a,pt %xcc, 50b               ! CTI
86 62:      ldxa   [%o1] %asi, %g1         ! Load
87         retl                            ! CTI   Group
88          mov    %o2, %o0                ! IEU0
89 50:     sub     %o0, %o3, %o0
90         retl
91          sub    %o0, 8, %o0
92 51:     sub     %o0, %o3, %o0
93         retl
94          sub    %o0, 7, %o0
95 52:     sub     %o0, %o3, %o0
96         retl
97          sub    %o0, 6, %o0
98 53:     sub     %o0, %o3, %o0
99         retl
100          sub    %o0, 5, %o0
101 54:     sub     %o0, %o3, %o0
102         retl
103          sub    %o0, 4, %o0
104 55:     sub     %o0, %o3, %o0
105         retl
106          sub    %o0, 3, %o0
107 56:     sub     %o0, %o3, %o0
108         retl
109          sub    %o0, 2, %o0
110 57:     retl
111          sub    %o0, 1, %o0
112 30:     brlez,pn %o2, 3f
113          sub    %g0, %o2, %o3
114         add     %o0, %o2, %o0
115 63:     lduba   [%o1] %asi, %o4
116 1:      add     %o1, 1, %o1
117         brz,pn  %o4, 2f
118          stb    %o4, [%o0 + %o3]
119         addcc   %o3, 1, %o3
120         bne,pt  %xcc, 1b
121 64:      lduba  [%o1] %asi, %o4
122 3:      retl
123          mov    %o2, %o0
124 2:      retl
125          add    %o2, %o3, %o0
126         .size   __strncpy_from_user, .-__strncpy_from_user
127
128         .section __ex_table,#alloc
129         .align  4
130         .word   60b, __retl_efault
131         .word   61b, __retl_efault
132         .word   62b, __retl_efault
133         .word   63b, __retl_efault
134         .word   64b, __retl_efault
135         .previous