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