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