2
* internal version of memcpy(), issued by the compiler to copy blocks of
3
* data around. This is really memmove() - it has to be able to deal with
4
* possible overlaps, because that ambiguity is when the compiler gives up
5
* and calls a function. We have our own, internal version so that we get
6
* something we trust, even if the user has redefined the normal symbol.
8
* Copyright 2004-2009 Analog Devices Inc.
10
* Licensed under the ADI BSD license or the GPL-2 (or later)
13
#include <linux/linkage.h>
15
/* void *memcpy(void *dest, const void *src, size_t n);
16
* R0 = To Address (dest) (leave unchanged to form result)
17
* R1 = From Address (src)
20
* Note: Favours word alignment
23
#ifdef CONFIG_MEMCPY_L1
32
CC = R2 <= 0; /* length not positive? */
33
IF CC JUMP .L_P1L2147483647; /* Nothing to do */
37
P2 = R2 ; /* length */
39
/* check for overlapping data */
40
CC = R1 < R0; /* src < dst */
41
IF !CC JUMP .Lno_overlap;
43
CC = R0 < R3; /* and dst < src+len */
44
IF CC JUMP .Lhas_overlap;
47
/* Check for aligned data.*/
52
CC = R3; /* low bits set on either address? */
53
IF CC JUMP .Lnot_aligned;
55
/* Both addresses are word-aligned, so we can copy
56
at least part of the data using word copies.*/
59
IF !CC JUMP .Lmore_than_seven;
60
/* less than eight bytes... */
62
LSETUP(.Lthree_start, .Lthree_end) LC0=P2;
71
/* There's at least eight bytes to copy. */
72
P2 += -1; /* because we unroll one iteration */
73
LSETUP(.Lword_loops, .Lword_loope) LC0=P2;
84
MNOP || [P0++] = R3 || R3 = [I1++];
87
/* Any remaining bytes to copy? */
91
P1 = I1; /* in case there's something left, */
92
IF !CC JUMP .Lbytes_left;
94
.Lbytes_left: P2 = R3;
96
/* From here, we're copying byte-by-byte. */
97
LSETUP (.Lbyte_start, .Lbyte_end) LC0=P2;
107
/* Need to reverse the copying, because the
108
* dst would clobber the src.
109
* Don't bother to work out alignment for
116
LSETUP(.Lover_start, .Lover_end) LC0=P2;