Minor coding style cleanup.
[platform/kernel/u-boot.git] / arch / arm / lib / memcpy.S
1 /*
2  *  linux/arch/arm/lib/memcpy.S
3  *
4  *  Author:     Nicolas Pitre
5  *  Created:    Sep 28, 2005
6  *  Copyright:  MontaVista Software, Inc.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License version 2 as
10  *  published by the Free Software Foundation.
11  */
12
13 #include <asm/assembler.h>
14
15 #define W(instr)        instr
16
17 #define LDR1W_SHIFT     0
18 #define STR1W_SHIFT     0
19
20         .macro ldr1w ptr reg abort
21         W(ldr) \reg, [\ptr], #4
22         .endm
23
24         .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
25         ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
26         .endm
27
28         .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
29         ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
30         .endm
31
32         .macro ldr1b ptr reg cond=al abort
33         ldr\cond\()b \reg, [\ptr], #1
34         .endm
35
36         .macro str1w ptr reg abort
37         W(str) \reg, [\ptr], #4
38         .endm
39
40         .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
41         stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
42         .endm
43
44         .macro str1b ptr reg cond=al abort
45         str\cond\()b \reg, [\ptr], #1
46         .endm
47
48         .macro enter reg1 reg2
49         stmdb sp!, {r0, \reg1, \reg2}
50         .endm
51
52         .macro exit reg1 reg2
53         ldmfd sp!, {r0, \reg1, \reg2}
54         .endm
55
56         .text
57
58 /* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
59
60 .globl memcpy
61 memcpy:
62
63                 enter   r4, lr
64
65                 subs    r2, r2, #4
66                 blt     8f
67                 ands    ip, r0, #3
68         PLD(    pld     [r1, #0]                )
69                 bne     9f
70                 ands    ip, r1, #3
71                 bne     10f
72
73 1:              subs    r2, r2, #(28)
74                 stmfd   sp!, {r5 - r8}
75                 blt     5f
76
77         CALGN(  ands    ip, r0, #31             )
78         CALGN(  rsb     r3, ip, #32             )
79         CALGN(  sbcnes  r4, r3, r2              )  @ C is always set here
80         CALGN(  bcs     2f                      )
81         CALGN(  adr     r4, 6f                  )
82         CALGN(  subs    r2, r2, r3              )  @ C gets set
83         CALGN(  add     pc, r4, ip              )
84
85         PLD(    pld     [r1, #0]                )
86 2:      PLD(    subs    r2, r2, #96             )
87         PLD(    pld     [r1, #28]               )
88         PLD(    blt     4f                      )
89         PLD(    pld     [r1, #60]               )
90         PLD(    pld     [r1, #92]               )
91
92 3:      PLD(    pld     [r1, #124]              )
93 4:              ldr8w   r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
94                 subs    r2, r2, #32
95                 str8w   r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
96                 bge     3b
97         PLD(    cmn     r2, #96                 )
98         PLD(    bge     4b                      )
99
100 5:              ands    ip, r2, #28
101                 rsb     ip, ip, #32
102 #if LDR1W_SHIFT > 0
103                 lsl     ip, ip, #LDR1W_SHIFT
104 #endif
105                 addne   pc, pc, ip              @ C is always clear here
106                 b       7f
107 6:
108                 .rept   (1 << LDR1W_SHIFT)
109                 W(nop)
110                 .endr
111                 ldr1w   r1, r3, abort=20f
112                 ldr1w   r1, r4, abort=20f
113                 ldr1w   r1, r5, abort=20f
114                 ldr1w   r1, r6, abort=20f
115                 ldr1w   r1, r7, abort=20f
116                 ldr1w   r1, r8, abort=20f
117                 ldr1w   r1, lr, abort=20f
118
119 #if LDR1W_SHIFT < STR1W_SHIFT
120                 lsl     ip, ip, #STR1W_SHIFT - LDR1W_SHIFT
121 #elif LDR1W_SHIFT > STR1W_SHIFT
122                 lsr     ip, ip, #LDR1W_SHIFT - STR1W_SHIFT
123 #endif
124                 add     pc, pc, ip
125                 nop
126                 .rept   (1 << STR1W_SHIFT)
127                 W(nop)
128                 .endr
129                 str1w   r0, r3, abort=20f
130                 str1w   r0, r4, abort=20f
131                 str1w   r0, r5, abort=20f
132                 str1w   r0, r6, abort=20f
133                 str1w   r0, r7, abort=20f
134                 str1w   r0, r8, abort=20f
135                 str1w   r0, lr, abort=20f
136
137         CALGN(  bcs     2b                      )
138
139 7:              ldmfd   sp!, {r5 - r8}
140
141 8:              movs    r2, r2, lsl #31
142                 ldr1b   r1, r3, ne, abort=21f
143                 ldr1b   r1, r4, cs, abort=21f
144                 ldr1b   r1, ip, cs, abort=21f
145                 str1b   r0, r3, ne, abort=21f
146                 str1b   r0, r4, cs, abort=21f
147                 str1b   r0, ip, cs, abort=21f
148
149                 exit    r4, pc
150
151 9:              rsb     ip, ip, #4
152                 cmp     ip, #2
153                 ldr1b   r1, r3, gt, abort=21f
154                 ldr1b   r1, r4, ge, abort=21f
155                 ldr1b   r1, lr, abort=21f
156                 str1b   r0, r3, gt, abort=21f
157                 str1b   r0, r4, ge, abort=21f
158                 subs    r2, r2, ip
159                 str1b   r0, lr, abort=21f
160                 blt     8b
161                 ands    ip, r1, #3
162                 beq     1b
163
164 10:             bic     r1, r1, #3
165                 cmp     ip, #2
166                 ldr1w   r1, lr, abort=21f
167                 beq     17f
168                 bgt     18f
169
170
171                 .macro  forward_copy_shift pull push
172
173                 subs    r2, r2, #28
174                 blt     14f
175
176         CALGN(  ands    ip, r0, #31             )
177         CALGN(  rsb     ip, ip, #32             )
178         CALGN(  sbcnes  r4, ip, r2              )  @ C is always set here
179         CALGN(  subcc   r2, r2, ip              )
180         CALGN(  bcc     15f                     )
181
182 11:             stmfd   sp!, {r5 - r9}
183
184         PLD(    pld     [r1, #0]                )
185         PLD(    subs    r2, r2, #96             )
186         PLD(    pld     [r1, #28]               )
187         PLD(    blt     13f                     )
188         PLD(    pld     [r1, #60]               )
189         PLD(    pld     [r1, #92]               )
190
191 12:     PLD(    pld     [r1, #124]              )
192 13:             ldr4w   r1, r4, r5, r6, r7, abort=19f
193                 mov     r3, lr, pull #\pull
194                 subs    r2, r2, #32
195                 ldr4w   r1, r8, r9, ip, lr, abort=19f
196                 orr     r3, r3, r4, push #\push
197                 mov     r4, r4, pull #\pull
198                 orr     r4, r4, r5, push #\push
199                 mov     r5, r5, pull #\pull
200                 orr     r5, r5, r6, push #\push
201                 mov     r6, r6, pull #\pull
202                 orr     r6, r6, r7, push #\push
203                 mov     r7, r7, pull #\pull
204                 orr     r7, r7, r8, push #\push
205                 mov     r8, r8, pull #\pull
206                 orr     r8, r8, r9, push #\push
207                 mov     r9, r9, pull #\pull
208                 orr     r9, r9, ip, push #\push
209                 mov     ip, ip, pull #\pull
210                 orr     ip, ip, lr, push #\push
211                 str8w   r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
212                 bge     12b
213         PLD(    cmn     r2, #96                 )
214         PLD(    bge     13b                     )
215
216                 ldmfd   sp!, {r5 - r9}
217
218 14:             ands    ip, r2, #28
219                 beq     16f
220
221 15:             mov     r3, lr, pull #\pull
222                 ldr1w   r1, lr, abort=21f
223                 subs    ip, ip, #4
224                 orr     r3, r3, lr, push #\push
225                 str1w   r0, r3, abort=21f
226                 bgt     15b
227         CALGN(  cmp     r2, #0                  )
228         CALGN(  bge     11b                     )
229
230 16:             sub     r1, r1, #(\push / 8)
231                 b       8b
232
233                 .endm
234
235
236                 forward_copy_shift      pull=8  push=24
237
238 17:             forward_copy_shift      pull=16 push=16
239
240 18:             forward_copy_shift      pull=24 push=8