Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[linux-2.6] / arch / sparc / lib / GENmemcpy.S
1 /* GENmemcpy.S: Generic sparc64 memcpy.
2  *
3  * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
4  */
5
6 #ifdef __KERNEL__
7 #define GLOBAL_SPARE    %g7
8 #else
9 #define GLOBAL_SPARE    %g5
10 #endif
11
12 #ifndef EX_LD
13 #define EX_LD(x)        x
14 #endif
15
16 #ifndef EX_ST
17 #define EX_ST(x)        x
18 #endif
19
20 #ifndef EX_RETVAL
21 #define EX_RETVAL(x)    x
22 #endif
23
24 #ifndef LOAD
25 #define LOAD(type,addr,dest)    type [addr], dest
26 #endif
27
28 #ifndef STORE
29 #define STORE(type,src,addr)    type src, [addr]
30 #endif
31
32 #ifndef FUNC_NAME
33 #define FUNC_NAME       GENmemcpy
34 #endif
35
36 #ifndef PREAMBLE
37 #define PREAMBLE
38 #endif
39
40 #ifndef XCC
41 #define XCC xcc
42 #endif
43
44         .register       %g2,#scratch
45         .register       %g3,#scratch
46
47         .text
48         .align          64
49
50         .globl  FUNC_NAME
51         .type   FUNC_NAME,#function
52 FUNC_NAME:      /* %o0=dst, %o1=src, %o2=len */
53         srlx            %o2, 31, %g2
54         cmp             %g2, 0
55         tne             %XCC, 5
56         PREAMBLE
57         mov             %o0, GLOBAL_SPARE
58
59         cmp             %o2, 0
60         be,pn           %XCC, 85f
61          or             %o0, %o1, %o3
62         cmp             %o2, 16
63         blu,a,pn        %XCC, 80f
64          or             %o3, %o2, %o3
65
66         xor             %o0, %o1, %o4
67         andcc           %o4, 0x7, %g0
68         bne,a,pn        %XCC, 90f
69          sub            %o0, %o1, %o3
70
71         and             %o0, 0x7, %o4
72         sub             %o4, 0x8, %o4
73         sub             %g0, %o4, %o4
74         sub             %o2, %o4, %o2
75 1:      subcc           %o4, 1, %o4
76         EX_LD(LOAD(ldub, %o1, %g1))
77         EX_ST(STORE(stb, %g1, %o0))
78         add             %o1, 1, %o1
79         bne,pt          %XCC, 1b
80         add             %o0, 1, %o0
81
82         andn            %o2, 0x7, %g1
83         sub             %o2, %g1, %o2
84 1:      subcc           %g1, 0x8, %g1
85         EX_LD(LOAD(ldx, %o1, %g2))
86         EX_ST(STORE(stx, %g2, %o0))
87         add             %o1, 0x8, %o1
88         bne,pt          %XCC, 1b
89          add            %o0, 0x8, %o0
90
91         brz,pt          %o2, 85f
92          sub            %o0, %o1, %o3
93         ba,a,pt         %XCC, 90f
94
95         .align          64
96 80: /* 0 < len <= 16 */
97         andcc           %o3, 0x3, %g0
98         bne,pn          %XCC, 90f
99          sub            %o0, %o1, %o3
100
101 1:
102         subcc           %o2, 4, %o2
103         EX_LD(LOAD(lduw, %o1, %g1))
104         EX_ST(STORE(stw, %g1, %o1 + %o3))
105         bgu,pt          %XCC, 1b
106          add            %o1, 4, %o1
107
108 85:     retl
109          mov            EX_RETVAL(GLOBAL_SPARE), %o0
110
111         .align          32
112 90:
113         subcc           %o2, 1, %o2
114         EX_LD(LOAD(ldub, %o1, %g1))
115         EX_ST(STORE(stb, %g1, %o1 + %o3))
116         bgu,pt          %XCC, 90b
117          add            %o1, 1, %o1
118         retl
119          mov            EX_RETVAL(GLOBAL_SPARE), %o0
120
121         .size           FUNC_NAME, .-FUNC_NAME