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
);