1
/* Normally compiler builtins are used, but sometimes the compiler calls out
2
of line code. Based on asm-i386/string.h.
5
#include <linux/string.h>
6
#include <linux/module.h>
9
void *memmove(void *dest, const void *src, size_t count)
11
unsigned long d0,d1,d2,d3,d4,d5,d6,d7;
15
/* Handle more 32bytes in loop */
20
/* Decide forward/backward copy mode */
25
* movsq instruction have many startup latency
26
* so we handle small size by general register.
31
* movsq instruction is only good for aligned case.
33
"cmpb %%dil, %%sil\n\t"
38
* We gobble 32byts forward in each loop.
42
"movq 0*8(%1), %4\n\t"
43
"movq 1*8(%1), %5\n\t"
44
"movq 2*8(%1), %6\n\t"
45
"movq 3*8(%1), %7\n\t"
46
"leaq 4*8(%1), %1\n\t"
48
"movq %4, 0*8(%2)\n\t"
49
"movq %5, 1*8(%2)\n\t"
50
"movq %6, 2*8(%2)\n\t"
51
"movq %7, 3*8(%2)\n\t"
52
"leaq 4*8(%2), %2\n\t"
57
* Handle data forward by movsq.
62
"movq -8(%1, %0), %4\n\t"
63
"lea -8(%2, %0), %5\n\t"
69
* Handle data backward by movsq.
76
"leaq -8(%1, %0), %1\n\t"
77
"leaq -8(%2, %0), %2\n\t"
86
* Start to prepare for backward copy.
92
"cmp %%dil, %%sil\n\t"
96
* Calculate copy position to tail.
102
* We gobble 32byts backward in each loop.
106
"movq -1*8(%1), %4\n\t"
107
"movq -2*8(%1), %5\n\t"
108
"movq -3*8(%1), %6\n\t"
109
"movq -4*8(%1), %7\n\t"
110
"leaq -4*8(%1), %1\n\t"
112
"movq %4, -1*8(%2)\n\t"
113
"movq %5, -2*8(%2)\n\t"
114
"movq %6, -3*8(%2)\n\t"
115
"movq %7, -4*8(%2)\n\t"
116
"leaq -4*8(%2), %2\n\t"
119
* Calculate copy position to head.
128
* Move data from 16 bytes to 31 bytes.
130
"movq 0*8(%1), %4\n\t"
131
"movq 1*8(%1), %5\n\t"
132
"movq -2*8(%1, %0), %6\n\t"
133
"movq -1*8(%1, %0), %7\n\t"
134
"movq %4, 0*8(%2)\n\t"
135
"movq %5, 1*8(%2)\n\t"
136
"movq %6, -2*8(%2, %0)\n\t"
137
"movq %7, -1*8(%2, %0)\n\t"
144
* Move data from 8 bytes to 15 bytes.
146
"movq 0*8(%1), %4\n\t"
147
"movq -1*8(%1, %0), %5\n\t"
148
"movq %4, 0*8(%2)\n\t"
149
"movq %5, -1*8(%2, %0)\n\t"
155
* Move data from 4 bytes to 7 bytes.
158
"movl -4(%1, %0), %5d\n\t"
160
"movl %5d, -4(%2, %0)\n\t"
166
* Move data from 2 bytes to 3 bytes.
169
"movw -2(%1, %0), %5w\n\t"
171
"movw %5w, -2(%2, %0)\n\t"
177
* Move data for 1 byte.
182
: "=&d" (d0), "=&S" (d1), "=&D" (d2), "=&a" (ret) ,
183
"=r"(d3), "=r"(d4), "=r"(d5), "=r"(d6), "=&c" (d7)
192
EXPORT_SYMBOL(memmove);