ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / 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  4
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 __strncpy_from_user:
35         /* %o0=dest, %o1=src, %o2=count */
36         sethi   %hi(0b), %o5            ! IEU0  Group
37         andcc   %o1, 7, %g0             ! IEU1
38         bne,pn  %icc, 30f               ! CTI
39          ldx    [%o5 + %lo(0b)], %o4    ! Load  Group
40         add     %o0, %o2, %g3           ! IEU0
41 60:     ldxa    [%o1] %asi, %g1         ! Load  Group
42         brlez,pn %o2, 10f               ! CTI
43          sllx   %o4, 7, %o5             ! IEU0  Group
44         mov     %o0, %o3                ! IEU1
45 1:      sub     %g1, %o4, %g2           ! IEU0  Group
46         stx     %g1, [%o0]              ! Store
47         add     %o0, 8, %o0             ! IEU1
48         andcc   %g2, %o5, %g0           ! IEU1  Group
49         bne,pn  %xcc, 5f                ! CTI
50          add    %o1, 8, %o1             ! IEU0
51         cmp     %o0, %g3                ! IEU1  Group
52         bl,a,pt %xcc, 1b                ! CTI
53 61:      ldxa   [%o1] %asi, %g1         ! Load
54 10:     retl                            ! CTI   Group
55          mov    %o2, %o0                ! IEU0
56 5:      srlx    %g2, 32, %g7            ! IEU0  Group
57         sethi   %hi(0xff00), %g5        ! IEU1
58         andcc   %g7, %o5, %g0           ! IEU1  Group
59         be,pn   %icc, 2f                ! CTI
60          or     %g5, %lo(0xff00), %g5   ! IEU0
61         srlx    %g1, 48, %g7            ! IEU0  Group
62         andcc   %g7, %g5, %g0           ! IEU1  Group
63         be,pn   %icc, 50f               ! CTI
64          andcc  %g7, 0xff, %g0          ! IEU1  Group
65         be,pn   %icc, 51f               ! CTI
66          srlx   %g1, 32, %g7            ! IEU0
67         andcc   %g7, %g5, %g0           ! IEU1  Group
68         be,pn   %icc, 52f               ! CTI
69          andcc  %g7, 0xff, %g0          ! IEU1  Group
70         be,pn   %icc, 53f               ! CTI
71 2:       andcc  %g2, %o5, %g0           ! IEU1  Group
72         be,pn   %icc, 2f                ! CTI
73          srl    %g1, 16, %g7            ! IEU0
74         andcc   %g7, %g5, %g0           ! IEU1  Group
75         be,pn   %icc, 54f               ! CTI
76          andcc  %g7, 0xff, %g0          ! IEU1  Group
77         be,pn   %icc, 55f               ! CTI
78          andcc  %g1, %g5, %g0           ! IEU1  Group
79         be,pn   %icc, 56f               ! CTI
80          andcc  %g1, 0xff, %g0          ! IEU1  Group
81         be,a,pn %icc, 57f               ! CTI
82          sub    %o0, %o3, %o0           ! IEU0
83 2:      cmp     %o0, %g3                ! IEU1  Group
84         bl,a,pt %xcc, 1b                ! CTI
85 62:      ldxa   [%o1] %asi, %g1         ! Load
86         retl                            ! CTI   Group
87          mov    %o2, %o0                ! IEU0
88 50:     sub     %o0, %o3, %o0
89         retl
90          sub    %o0, 8, %o0
91 51:     sub     %o0, %o3, %o0
92         retl
93          sub    %o0, 7, %o0
94 52:     sub     %o0, %o3, %o0
95         retl
96          sub    %o0, 6, %o0
97 53:     sub     %o0, %o3, %o0
98         retl
99          sub    %o0, 5, %o0
100 54:     sub     %o0, %o3, %o0
101         retl
102          sub    %o0, 4, %o0
103 55:     sub     %o0, %o3, %o0
104         retl
105          sub    %o0, 3, %o0
106 56:     sub     %o0, %o3, %o0
107         retl
108          sub    %o0, 2, %o0
109 57:     retl
110          sub    %o0, 1, %o0
111 30:     brlez,pn %o2, 3f
112          sub    %g0, %o2, %o3
113         add     %o0, %o2, %o0
114 63:     lduba   [%o1] %asi, %o4
115 1:      add     %o1, 1, %o1
116         brz,pn  %o4, 2f
117          stb    %o4, [%o0 + %o3]
118         addcc   %o3, 1, %o3
119         bne,pt  %xcc, 1b
120 64:      lduba  [%o1] %asi, %o4
121 3:      retl
122          mov    %o2, %o0
123 2:      retl
124          add    %o2, %o3, %o0
125
126         .section .fixup,#alloc,#execinstr
127         .align  4
128 4:      retl
129          mov    -EFAULT, %o0
130
131         .section __ex_table,#alloc
132         .align  4
133         .word   60b, 4b
134         .word   61b, 4b
135         .word   62b, 4b
136         .word   63b, 4b
137         .word   64b, 4b