mb/google/nissa: Create pujjogatwin variant
[coreboot2.git] / payloads / libpayload / arch / arm / memmove.S
blobbd5f8f1ac51a153096aebdcb20490fc6eb2acefa
1 /*
2  *  linux/arch/arm/lib/memmove.S
3  *
4  *  Author:     Nicolas Pitre
5  *  Created:    Sep 28, 2005
6  *  Copyright:  (C) 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  */
13 #include <arch/asm.h>
14 #include "asmlib.h"
17  * Prototype: void *memmove(void *dest, const void *src, size_t n);
18  *
19  * Note:
20  *
21  * If the memory regions don't overlap, we simply branch to memcpy which is
22  * normally a bit faster. Otherwise the copy is done going downwards.  This
23  * is a transposition of the code from copy_template.S but with the copy
24  * occurring in the opposite direction.
25  */
27 ENTRY(memmove)
29                 subs    ip, r0, r1
30                 cmphi   r2, ip
31                 bls     memcpy
33                 stmfd   sp!, {r0, r4, lr}
34                 add     r1, r1, r2
35                 add     r0, r0, r2
36                 subs    r2, r2, #4
37                 blt     8f
38                 ands    ip, r0, #3
39         PLD(    pld     [r1, #-4]               )
40                 bne     9f
41                 ands    ip, r1, #3
42                 bne     10f
44 1:              subs    r2, r2, #(28)
45                 stmfd   sp!, {r5 - r8}
46                 blt     5f
48         CALGN(  ands    ip, r0, #31             )
49         CALGN(  sbcnes  r4, ip, r2              )  @ C is always set here
50         CALGN(  bcs     2f                      )
51         CALGN(  adr     r4, 6f                  )
52         CALGN(  subs    r2, r2, ip              )  @ C is set here
53         CALGN(  rsb     ip, ip, #32             )
54         CALGN(  add     pc, r4, ip              )
56         PLD(    pld     [r1, #-4]               )
57 2:      PLD(    subs    r2, r2, #96             )
58         PLD(    pld     [r1, #-32]              )
59         PLD(    blt     4f                      )
60         PLD(    pld     [r1, #-64]              )
61         PLD(    pld     [r1, #-96]              )
63 3:      PLD(    pld     [r1, #-128]             )
64 4:              ldmdb   r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
65                 subs    r2, r2, #32
66                 stmdb   r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
67                 bge     3b
68         PLD(    cmn     r2, #96                 )
69         PLD(    bge     4b                      )
71 5:              ands    ip, r2, #28
72                 rsb     ip, ip, #32
73                 addne   pc, pc, ip              @ C is always clear here
74                 b       7f
75 6:              W(nop)
76                 W(ldr)  r3, [r1, #-4]!
77                 W(ldr)  r4, [r1, #-4]!
78                 W(ldr)  r5, [r1, #-4]!
79                 W(ldr)  r6, [r1, #-4]!
80                 W(ldr)  r7, [r1, #-4]!
81                 W(ldr)  r8, [r1, #-4]!
82                 W(ldr)  lr, [r1, #-4]!
84                 add     pc, pc, ip
85                 nop
86                 W(nop)
87                 W(str)  r3, [r0, #-4]!
88                 W(str)  r4, [r0, #-4]!
89                 W(str)  r5, [r0, #-4]!
90                 W(str)  r6, [r0, #-4]!
91                 W(str)  r7, [r0, #-4]!
92                 W(str)  r8, [r0, #-4]!
93                 W(str)  lr, [r0, #-4]!
95         CALGN(  bcs     2b                      )
97 7:              ldmfd   sp!, {r5 - r8}
99 8:              movs    r2, r2, lsl #31
100                 ldrneb  r3, [r1, #-1]!
101                 ldrcsb  r4, [r1, #-1]!
102                 ldrcsb  ip, [r1, #-1]
103                 strneb  r3, [r0, #-1]!
104                 strcsb  r4, [r0, #-1]!
105                 strcsb  ip, [r0, #-1]
106                 ldmfd   sp!, {r0, r4, pc}
108 9:              cmp     ip, #2
109                 ldrgtb  r3, [r1, #-1]!
110                 ldrgeb  r4, [r1, #-1]!
111                 ldrb    lr, [r1, #-1]!
112                 strgtb  r3, [r0, #-1]!
113                 strgeb  r4, [r0, #-1]!
114                 subs    r2, r2, ip
115                 strb    lr, [r0, #-1]!
116                 blt     8b
117                 ands    ip, r1, #3
118                 beq     1b
120 10:             bic     r1, r1, #3
121                 cmp     ip, #2
122                 ldr     r3, [r1, #0]
123                 beq     17f
124                 blt     18f
127                 .macro  backward_copy_shift push pull
129                 subs    r2, r2, #28
130                 blt     14f
132         CALGN(  ands    ip, r0, #31             )
133         CALGN(  sbcnes  r4, ip, r2              )  @ C is always set here
134         CALGN(  subcc   r2, r2, ip              )
135         CALGN(  bcc     15f                     )
137 11:             stmfd   sp!, {r5 - r9}
139         PLD(    pld     [r1, #-4]               )
140         PLD(    subs    r2, r2, #96             )
141         PLD(    pld     [r1, #-32]              )
142         PLD(    blt     13f                     )
143         PLD(    pld     [r1, #-64]              )
144         PLD(    pld     [r1, #-96]              )
146 12:     PLD(    pld     [r1, #-128]             )
147 13:             ldmdb   r1!, {r7, r8, r9, ip}
148                 mov     lr, r3, push #\push
149                 subs    r2, r2, #32
150                 ldmdb   r1!, {r3, r4, r5, r6}
151                 orr     lr, lr, ip, pull #\pull
152                 mov     ip, ip, push #\push
153                 orr     ip, ip, r9, pull #\pull
154                 mov     r9, r9, push #\push
155                 orr     r9, r9, r8, pull #\pull
156                 mov     r8, r8, push #\push
157                 orr     r8, r8, r7, pull #\pull
158                 mov     r7, r7, push #\push
159                 orr     r7, r7, r6, pull #\pull
160                 mov     r6, r6, push #\push
161                 orr     r6, r6, r5, pull #\pull
162                 mov     r5, r5, push #\push
163                 orr     r5, r5, r4, pull #\pull
164                 mov     r4, r4, push #\push
165                 orr     r4, r4, r3, pull #\pull
166                 stmdb   r0!, {r4 - r9, ip, lr}
167                 bge     12b
168         PLD(    cmn     r2, #96                 )
169         PLD(    bge     13b                     )
171                 ldmfd   sp!, {r5 - r9}
173 14:             ands    ip, r2, #28
174                 beq     16f
176 15:             mov     lr, r3, push #\push
177                 ldr     r3, [r1, #-4]!
178                 subs    ip, ip, #4
179                 orr     lr, lr, r3, pull #\pull
180                 str     lr, [r0, #-4]!
181                 bgt     15b
182         CALGN(  cmp     r2, #0                  )
183         CALGN(  bge     11b                     )
185 16:             add     r1, r1, #(\pull / 8)
186                 b       8b
188                 .endm
191                 backward_copy_shift     push=8  pull=24
193 17:             backward_copy_shift     push=16 pull=16
195 18:             backward_copy_shift     push=24 pull=8
197 ENDPROC(memmove)