blob: ce10bc869af9d8fda4aaf19232fa2d449bb4d848 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* memcpy.S: Sparc optimized memcpy and memmove code
2 * Hand optimized from GNU libc's memcpy and memmove
3 * Copyright (C) 1991,1996 Free Software Foundation
4 * Copyright (C) 1995 Linus Torvalds (Linus.Torvalds@helsinki.fi)
5 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
6 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
7 * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
8 */
9
10#ifdef __KERNEL__
11
12#define FUNC(x) \
13 .globl x; \
14 .type x,@function; \
15 .align 4; \
16x:
17
18#undef FASTER_REVERSE
19#undef FASTER_NONALIGNED
20#define FASTER_ALIGNED
21
22/* In kernel these functions don't return a value.
23 * One should use macros in asm/string.h for that purpose.
24 * We return 0, so that bugs are more apparent.
25 */
26#define SETUP_RETL
27#define RETL_INSN clr %o0
28
29#else
30
31/* libc */
32
33#include "DEFS.h"
34
35#define FASTER_REVERSE
36#define FASTER_NONALIGNED
37#define FASTER_ALIGNED
38
39#define SETUP_RETL mov %o0, %g6
40#define RETL_INSN mov %g6, %o0
41
42#endif
43
44/* Both these macros have to start with exactly the same insn */
45#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
46 ldd [%src + (offset) + 0x00], %t0; \
47 ldd [%src + (offset) + 0x08], %t2; \
48 ldd [%src + (offset) + 0x10], %t4; \
49 ldd [%src + (offset) + 0x18], %t6; \
50 st %t0, [%dst + (offset) + 0x00]; \
51 st %t1, [%dst + (offset) + 0x04]; \
52 st %t2, [%dst + (offset) + 0x08]; \
53 st %t3, [%dst + (offset) + 0x0c]; \
54 st %t4, [%dst + (offset) + 0x10]; \
55 st %t5, [%dst + (offset) + 0x14]; \
56 st %t6, [%dst + (offset) + 0x18]; \
57 st %t7, [%dst + (offset) + 0x1c];
58
59#define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
60 ldd [%src + (offset) + 0x00], %t0; \
61 ldd [%src + (offset) + 0x08], %t2; \
62 ldd [%src + (offset) + 0x10], %t4; \
63 ldd [%src + (offset) + 0x18], %t6; \
64 std %t0, [%dst + (offset) + 0x00]; \
65 std %t2, [%dst + (offset) + 0x08]; \
66 std %t4, [%dst + (offset) + 0x10]; \
67 std %t6, [%dst + (offset) + 0x18];
68
69#define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
70 ldd [%src - (offset) - 0x10], %t0; \
71 ldd [%src - (offset) - 0x08], %t2; \
72 st %t0, [%dst - (offset) - 0x10]; \
73 st %t1, [%dst - (offset) - 0x0c]; \
74 st %t2, [%dst - (offset) - 0x08]; \
75 st %t3, [%dst - (offset) - 0x04];
76
77#define MOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1, t2, t3) \
78 ldd [%src - (offset) - 0x10], %t0; \
79 ldd [%src - (offset) - 0x08], %t2; \
80 std %t0, [%dst - (offset) - 0x10]; \
81 std %t2, [%dst - (offset) - 0x08];
82
83#define MOVE_SHORTCHUNK(src, dst, offset, t0, t1) \
84 ldub [%src - (offset) - 0x02], %t0; \
85 ldub [%src - (offset) - 0x01], %t1; \
86 stb %t0, [%dst - (offset) - 0x02]; \
87 stb %t1, [%dst - (offset) - 0x01];
88
89/* Both these macros have to start with exactly the same insn */
90#define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
91 ldd [%src - (offset) - 0x20], %t0; \
92 ldd [%src - (offset) - 0x18], %t2; \
93 ldd [%src - (offset) - 0x10], %t4; \
94 ldd [%src - (offset) - 0x08], %t6; \
95 st %t0, [%dst - (offset) - 0x20]; \
96 st %t1, [%dst - (offset) - 0x1c]; \
97 st %t2, [%dst - (offset) - 0x18]; \
98 st %t3, [%dst - (offset) - 0x14]; \
99 st %t4, [%dst - (offset) - 0x10]; \
100 st %t5, [%dst - (offset) - 0x0c]; \
101 st %t6, [%dst - (offset) - 0x08]; \
102 st %t7, [%dst - (offset) - 0x04];
103
104#define RMOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
105 ldd [%src - (offset) - 0x20], %t0; \
106 ldd [%src - (offset) - 0x18], %t2; \
107 ldd [%src - (offset) - 0x10], %t4; \
108 ldd [%src - (offset) - 0x08], %t6; \
109 std %t0, [%dst - (offset) - 0x20]; \
110 std %t2, [%dst - (offset) - 0x18]; \
111 std %t4, [%dst - (offset) - 0x10]; \
112 std %t6, [%dst - (offset) - 0x08];
113
114#define RMOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
115 ldd [%src + (offset) + 0x00], %t0; \
116 ldd [%src + (offset) + 0x08], %t2; \
117 st %t0, [%dst + (offset) + 0x00]; \
118 st %t1, [%dst + (offset) + 0x04]; \
119 st %t2, [%dst + (offset) + 0x08]; \
120 st %t3, [%dst + (offset) + 0x0c];
121
122#define RMOVE_SHORTCHUNK(src, dst, offset, t0, t1) \
123 ldub [%src + (offset) + 0x00], %t0; \
124 ldub [%src + (offset) + 0x01], %t1; \
125 stb %t0, [%dst + (offset) + 0x00]; \
126 stb %t1, [%dst + (offset) + 0x01];
127
128#define SMOVE_CHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2) \
129 ldd [%src + (offset) + 0x00], %t0; \
130 ldd [%src + (offset) + 0x08], %t2; \
131 srl %t0, shir, %t5; \
132 srl %t1, shir, %t6; \
133 sll %t0, shil, %t0; \
134 or %t5, %prev, %t5; \
135 sll %t1, shil, %prev; \
136 or %t6, %t0, %t0; \
137 srl %t2, shir, %t1; \
138 srl %t3, shir, %t6; \
139 sll %t2, shil, %t2; \
140 or %t1, %prev, %t1; \
141 std %t4, [%dst + (offset) + (offset2) - 0x04]; \
142 std %t0, [%dst + (offset) + (offset2) + 0x04]; \
143 sll %t3, shil, %prev; \
144 or %t6, %t2, %t4;
145
146#define SMOVE_ALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2) \
147 ldd [%src + (offset) + 0x00], %t0; \
148 ldd [%src + (offset) + 0x08], %t2; \
149 srl %t0, shir, %t4; \
150 srl %t1, shir, %t5; \
151 sll %t0, shil, %t6; \
152 or %t4, %prev, %t0; \
153 sll %t1, shil, %prev; \
154 or %t5, %t6, %t1; \
155 srl %t2, shir, %t4; \
156 srl %t3, shir, %t5; \
157 sll %t2, shil, %t6; \
158 or %t4, %prev, %t2; \
159 sll %t3, shil, %prev; \
160 or %t5, %t6, %t3; \
161 std %t0, [%dst + (offset) + (offset2) + 0x00]; \
162 std %t2, [%dst + (offset) + (offset2) + 0x08];
163
164 .text
165 .align 4
166
167#ifdef FASTER_REVERSE
168
16970: /* rdword_align */
170
171 andcc %o1, 1, %g0
172 be 4f
173 andcc %o1, 2, %g0
174
175 ldub [%o1 - 1], %g2
176 sub %o1, 1, %o1
177 stb %g2, [%o0 - 1]
178 sub %o2, 1, %o2
179 be 3f
180 sub %o0, 1, %o0
1814:
182 lduh [%o1 - 2], %g2
183 sub %o1, 2, %o1
184 sth %g2, [%o0 - 2]
185 sub %o2, 2, %o2
186 b 3f
187 sub %o0, 2, %o0
188
189#endif /* FASTER_REVERSE */
190
1910:
192 retl
193 nop ! Only bcopy returns here and it retuns void...
194
195#ifdef __KERNEL__
196FUNC(amemmove)
197FUNC(__memmove)
198#endif
199FUNC(memmove)
200 cmp %o0, %o1
201 SETUP_RETL
202 bleu 9f
203 sub %o0, %o1, %o4
204
205 add %o1, %o2, %o3
206 cmp %o3, %o0
207 bleu 0f
208 andcc %o4, 3, %o5
209
210#ifndef FASTER_REVERSE
211
212 add %o1, %o2, %o1
213 add %o0, %o2, %o0
214 sub %o1, 1, %o1
215 sub %o0, 1, %o0
216
2171: /* reverse_bytes */
218
219 ldub [%o1], %o4
220 subcc %o2, 1, %o2
221 stb %o4, [%o0]
222 sub %o1, 1, %o1
223 bne 1b
224 sub %o0, 1, %o0
225
226 retl
227 RETL_INSN
228
229#else /* FASTER_REVERSE */
230
231 add %o1, %o2, %o1
232 add %o0, %o2, %o0
233 bne 77f
234 cmp %o2, 15
235 bleu 91f
236 andcc %o1, 3, %g0
237 bne 70b
2383:
239 andcc %o1, 4, %g0
240
241 be 2f
242 mov %o2, %g1
243
244 ld [%o1 - 4], %o4
245 sub %g1, 4, %g1
246 st %o4, [%o0 - 4]
247 sub %o1, 4, %o1
248 sub %o0, 4, %o0
2492:
250 andcc %g1, 0xffffff80, %g7
251 be 3f
252 andcc %o0, 4, %g0
253
254 be 74f + 4
2555:
256 RMOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
257 RMOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
258 RMOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
259 RMOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
260 subcc %g7, 128, %g7
261 sub %o1, 128, %o1
262 bne 5b
263 sub %o0, 128, %o0
2643:
265 andcc %g1, 0x70, %g7
266 be 72f
267 andcc %g1, 8, %g0
268
269 sethi %hi(72f), %o5
270 srl %g7, 1, %o4
271 add %g7, %o4, %o4
272 sub %o1, %g7, %o1
273 sub %o5, %o4, %o5
274 jmpl %o5 + %lo(72f), %g0
275 sub %o0, %g7, %o0
276
27771: /* rmemcpy_table */
278 RMOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
279 RMOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
280 RMOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
281 RMOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
282 RMOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
283 RMOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
284 RMOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
285
28672: /* rmemcpy_table_end */
287
288 be 73f
289 andcc %g1, 4, %g0
290
291 ldd [%o1 - 0x08], %g2
292 sub %o0, 8, %o0
293 sub %o1, 8, %o1
294 st %g2, [%o0]
295 st %g3, [%o0 + 0x04]
296
29773: /* rmemcpy_last7 */
298
299 be 1f
300 andcc %g1, 2, %g0
301
302 ld [%o1 - 4], %g2
303 sub %o1, 4, %o1
304 st %g2, [%o0 - 4]
305 sub %o0, 4, %o0
3061:
307 be 1f
308 andcc %g1, 1, %g0
309
310 lduh [%o1 - 2], %g2
311 sub %o1, 2, %o1
312 sth %g2, [%o0 - 2]
313 sub %o0, 2, %o0
3141:
315 be 1f
316 nop
317
318 ldub [%o1 - 1], %g2
319 stb %g2, [%o0 - 1]
3201:
321 retl
322 RETL_INSN
323
32474: /* rldd_std */
325 RMOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
326 RMOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
327 RMOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
328 RMOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
329 subcc %g7, 128, %g7
330 sub %o1, 128, %o1
331 bne 74b
332 sub %o0, 128, %o0
333
334 andcc %g1, 0x70, %g7
335 be 72b
336 andcc %g1, 8, %g0
337
338 sethi %hi(72b), %o5
339 srl %g7, 1, %o4
340 add %g7, %o4, %o4
341 sub %o1, %g7, %o1
342 sub %o5, %o4, %o5
343 jmpl %o5 + %lo(72b), %g0
344 sub %o0, %g7, %o0
345
34675: /* rshort_end */
347
348 and %o2, 0xe, %o3
3492:
350 sethi %hi(76f), %o5
351 sll %o3, 3, %o4
352 sub %o0, %o3, %o0
353 sub %o5, %o4, %o5
354 sub %o1, %o3, %o1
355 jmpl %o5 + %lo(76f), %g0
356 andcc %o2, 1, %g0
357
358 RMOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
359 RMOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
360 RMOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
361 RMOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
362 RMOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
363 RMOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
364 RMOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
365
36676: /* rshort_table_end */
367
368 be 1f
369 nop
370 ldub [%o1 - 1], %g2
371 stb %g2, [%o0 - 1]
3721:
373 retl
374 RETL_INSN
375
37691: /* rshort_aligned_end */
377
378 bne 75b
379 andcc %o2, 8, %g0
380
381 be 1f
382 andcc %o2, 4, %g0
383
384 ld [%o1 - 0x08], %g2
385 ld [%o1 - 0x04], %g3
386 sub %o1, 8, %o1
387 st %g2, [%o0 - 0x08]
388 st %g3, [%o0 - 0x04]
389 sub %o0, 8, %o0
3901:
391 b 73b
392 mov %o2, %g1
393
39477: /* rnon_aligned */
395 cmp %o2, 15
396 bleu 75b
397 andcc %o0, 3, %g0
398 be 64f
399 andcc %o0, 1, %g0
400 be 63f
401 andcc %o0, 2, %g0
402 ldub [%o1 - 1], %g5
403 sub %o1, 1, %o1
404 stb %g5, [%o0 - 1]
405 sub %o0, 1, %o0
406 be 64f
407 sub %o2, 1, %o2
40863:
409 ldub [%o1 - 1], %g5
410 sub %o1, 2, %o1
411 stb %g5, [%o0 - 1]
412 sub %o0, 2, %o0
413 ldub [%o1], %g5
414 sub %o2, 2, %o2
415 stb %g5, [%o0]
41664:
417 and %o1, 3, %g2
418 and %o1, -4, %o1
419 and %o2, 0xc, %g3
420 add %o1, 4, %o1
421 cmp %g3, 4
422 sll %g2, 3, %g4
423 mov 32, %g2
424 be 4f
425 sub %g2, %g4, %g7
426
427 blu 3f
428 cmp %g3, 8
429
430 be 2f
431 srl %o2, 2, %g3
432
433 ld [%o1 - 4], %o3
434 add %o0, -8, %o0
435 ld [%o1 - 8], %o4
436 add %o1, -16, %o1
437 b 7f
438 add %g3, 1, %g3
4392:
440 ld [%o1 - 4], %o4
441 add %o0, -4, %o0
442 ld [%o1 - 8], %g1
443 add %o1, -12, %o1
444 b 8f
445 add %g3, 2, %g3
4463:
447 ld [%o1 - 4], %o5
448 add %o0, -12, %o0
449 ld [%o1 - 8], %o3
450 add %o1, -20, %o1
451 b 6f
452 srl %o2, 2, %g3
4534:
454 ld [%o1 - 4], %g1
455 srl %o2, 2, %g3
456 ld [%o1 - 8], %o5
457 add %o1, -24, %o1
458 add %o0, -16, %o0
459 add %g3, -1, %g3
460
461 ld [%o1 + 12], %o3
4625:
463 sll %o5, %g4, %g2
464 srl %g1, %g7, %g5
465 or %g2, %g5, %g2
466 st %g2, [%o0 + 12]
4676:
468 ld [%o1 + 8], %o4
469 sll %o3, %g4, %g2
470 srl %o5, %g7, %g5
471 or %g2, %g5, %g2
472 st %g2, [%o0 + 8]
4737:
474 ld [%o1 + 4], %g1
475 sll %o4, %g4, %g2
476 srl %o3, %g7, %g5
477 or %g2, %g5, %g2
478 st %g2, [%o0 + 4]
4798:
480 ld [%o1], %o5
481 sll %g1, %g4, %g2
482 srl %o4, %g7, %g5
483 addcc %g3, -4, %g3
484 or %g2, %g5, %g2
485 add %o1, -16, %o1
486 st %g2, [%o0]
487 add %o0, -16, %o0
488 bne,a 5b
489 ld [%o1 + 12], %o3
490 sll %o5, %g4, %g2
491 srl %g1, %g7, %g5
492 srl %g4, 3, %g3
493 or %g2, %g5, %g2
494 add %o1, %g3, %o1
495 andcc %o2, 2, %g0
496 st %g2, [%o0 + 12]
497 be 1f
498 andcc %o2, 1, %g0
499
500 ldub [%o1 + 15], %g5
501 add %o1, -2, %o1
502 stb %g5, [%o0 + 11]
503 add %o0, -2, %o0
504 ldub [%o1 + 16], %g5
505 stb %g5, [%o0 + 12]
5061:
507 be 1f
508 nop
509 ldub [%o1 + 15], %g5
510 stb %g5, [%o0 + 11]
5111:
512 retl
513 RETL_INSN
514
515#endif /* FASTER_REVERSE */
516
517/* NOTE: This code is executed just for the cases,
518 where %src (=%o1) & 3 is != 0.
519 We need to align it to 4. So, for (%src & 3)
520 1 we need to do ldub,lduh
521 2 lduh
522 3 just ldub
523 so even if it looks weird, the branches
524 are correct here. -jj
525 */
52678: /* dword_align */
527
528 andcc %o1, 1, %g0
529 be 4f
530 andcc %o1, 2, %g0
531
532 ldub [%o1], %g2
533 add %o1, 1, %o1
534 stb %g2, [%o0]
535 sub %o2, 1, %o2
536 bne 3f
537 add %o0, 1, %o0
5384:
539 lduh [%o1], %g2
540 add %o1, 2, %o1
541 sth %g2, [%o0]
542 sub %o2, 2, %o2
543 b 3f
544 add %o0, 2, %o0
545
546#ifdef __KERNEL__
547FUNC(__memcpy)
548#endif
549FUNC(memcpy) /* %o0=dst %o1=src %o2=len */
550
551 sub %o0, %o1, %o4
552 SETUP_RETL
5539:
554 andcc %o4, 3, %o5
5550:
556 bne 86f
557 cmp %o2, 15
558
559 bleu 90f
560 andcc %o1, 3, %g0
561
562 bne 78b
5633:
564 andcc %o1, 4, %g0
565
566 be 2f
567 mov %o2, %g1
568
569 ld [%o1], %o4
570 sub %g1, 4, %g1
571 st %o4, [%o0]
572 add %o1, 4, %o1
573 add %o0, 4, %o0
5742:
575 andcc %g1, 0xffffff80, %g7
576 be 3f
577 andcc %o0, 4, %g0
578
579 be 82f + 4
5805:
581 MOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
582 MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
583 MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
584 MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
585 subcc %g7, 128, %g7
586 add %o1, 128, %o1
587 bne 5b
588 add %o0, 128, %o0
5893:
590 andcc %g1, 0x70, %g7
591 be 80f
592 andcc %g1, 8, %g0
593
594 sethi %hi(80f), %o5
595 srl %g7, 1, %o4
596 add %g7, %o4, %o4
597 add %o1, %g7, %o1
598 sub %o5, %o4, %o5
599 jmpl %o5 + %lo(80f), %g0
600 add %o0, %g7, %o0
601
60279: /* memcpy_table */
603
604 MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
605 MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
606 MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
607 MOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
608 MOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
609 MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
610 MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
611
61280: /* memcpy_table_end */
613 be 81f
614 andcc %g1, 4, %g0
615
616 ldd [%o1], %g2
617 add %o0, 8, %o0
618 st %g2, [%o0 - 0x08]
619 add %o1, 8, %o1
620 st %g3, [%o0 - 0x04]
621
62281: /* memcpy_last7 */
623
624 be 1f
625 andcc %g1, 2, %g0
626
627 ld [%o1], %g2
628 add %o1, 4, %o1
629 st %g2, [%o0]
630 add %o0, 4, %o0
6311:
632 be 1f
633 andcc %g1, 1, %g0
634
635 lduh [%o1], %g2
636 add %o1, 2, %o1
637 sth %g2, [%o0]
638 add %o0, 2, %o0
6391:
640 be 1f
641 nop
642
643 ldub [%o1], %g2
644 stb %g2, [%o0]
6451:
646 retl
647 RETL_INSN
648
64982: /* ldd_std */
650 MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
651 MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
652 MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
653 MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
654 subcc %g7, 128, %g7
655 add %o1, 128, %o1
656 bne 82b
657 add %o0, 128, %o0
658
659#ifndef FASTER_ALIGNED
660
661 andcc %g1, 0x70, %g7
662 be 80b
663 andcc %g1, 8, %g0
664
665 sethi %hi(80b), %o5
666 srl %g7, 1, %o4
667 add %g7, %o4, %o4
668 add %o1, %g7, %o1
669 sub %o5, %o4, %o5
670 jmpl %o5 + %lo(80b), %g0
671 add %o0, %g7, %o0
672
673#else /* FASTER_ALIGNED */
674
675 andcc %g1, 0x70, %g7
676 be 84f
677 andcc %g1, 8, %g0
678
679 sethi %hi(84f), %o5
680 add %o1, %g7, %o1
681 sub %o5, %g7, %o5
682 jmpl %o5 + %lo(84f), %g0
683 add %o0, %g7, %o0
684
68583: /* amemcpy_table */
686
687 MOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
688 MOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
689 MOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
690 MOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
691 MOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
692 MOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
693 MOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
694
69584: /* amemcpy_table_end */
696 be 85f
697 andcc %g1, 4, %g0
698
699 ldd [%o1], %g2
700 add %o0, 8, %o0
701 std %g2, [%o0 - 0x08]
702 add %o1, 8, %o1
70385: /* amemcpy_last7 */
704 be 1f
705 andcc %g1, 2, %g0
706
707 ld [%o1], %g2
708 add %o1, 4, %o1
709 st %g2, [%o0]
710 add %o0, 4, %o0
7111:
712 be 1f
713 andcc %g1, 1, %g0
714
715 lduh [%o1], %g2
716 add %o1, 2, %o1
717 sth %g2, [%o0]
718 add %o0, 2, %o0
7191:
720 be 1f
721 nop
722
723 ldub [%o1], %g2
724 stb %g2, [%o0]
7251:
726 retl
727 RETL_INSN
728
729#endif /* FASTER_ALIGNED */
730
73186: /* non_aligned */
732 cmp %o2, 6
733 bleu 88f
734
735#ifdef FASTER_NONALIGNED
736
737 cmp %o2, 256
738 bcc 87f
739
740#endif /* FASTER_NONALIGNED */
741
742 andcc %o0, 3, %g0
743 be 61f
744 andcc %o0, 1, %g0
745 be 60f
746 andcc %o0, 2, %g0
747
748 ldub [%o1], %g5
749 add %o1, 1, %o1
750 stb %g5, [%o0]
751 sub %o2, 1, %o2
752 bne 61f
753 add %o0, 1, %o0
75460:
755 ldub [%o1], %g3
756 add %o1, 2, %o1
757 stb %g3, [%o0]
758 sub %o2, 2, %o2
759 ldub [%o1 - 1], %g3
760 add %o0, 2, %o0
761 stb %g3, [%o0 - 1]
76261:
763 and %o1, 3, %g2
764 and %o2, 0xc, %g3
765 and %o1, -4, %o1
766 cmp %g3, 4
767 sll %g2, 3, %g4
768 mov 32, %g2
769 be 4f
770 sub %g2, %g4, %g7
771
772 blu 3f
773 cmp %g3, 0x8
774
775 be 2f
776 srl %o2, 2, %g3
777
778 ld [%o1], %o3
779 add %o0, -8, %o0
780 ld [%o1 + 4], %o4
781 b 8f
782 add %g3, 1, %g3
7832:
784 ld [%o1], %o4
785 add %o0, -12, %o0
786 ld [%o1 + 4], %o5
787 add %g3, 2, %g3
788 b 9f
789 add %o1, -4, %o1
7903:
791 ld [%o1], %g1
792 add %o0, -4, %o0
793 ld [%o1 + 4], %o3
794 srl %o2, 2, %g3
795 b 7f
796 add %o1, 4, %o1
7974:
798 ld [%o1], %o5
799 cmp %o2, 7
800 ld [%o1 + 4], %g1
801 srl %o2, 2, %g3
802 bleu 10f
803 add %o1, 8, %o1
804
805 ld [%o1], %o3
806 add %g3, -1, %g3
8075:
808 sll %o5, %g4, %g2
809 srl %g1, %g7, %g5
810 or %g2, %g5, %g2
811 st %g2, [%o0]
8127:
813 ld [%o1 + 4], %o4
814 sll %g1, %g4, %g2
815 srl %o3, %g7, %g5
816 or %g2, %g5, %g2
817 st %g2, [%o0 + 4]
8188:
819 ld [%o1 + 8], %o5
820 sll %o3, %g4, %g2
821 srl %o4, %g7, %g5
822 or %g2, %g5, %g2
823 st %g2, [%o0 + 8]
8249:
825 ld [%o1 + 12], %g1
826 sll %o4, %g4, %g2
827 srl %o5, %g7, %g5
828 addcc %g3, -4, %g3
829 or %g2, %g5, %g2
830 add %o1, 16, %o1
831 st %g2, [%o0 + 12]
832 add %o0, 16, %o0
833 bne,a 5b
834 ld [%o1], %o3
83510:
836 sll %o5, %g4, %g2
837 srl %g1, %g7, %g5
838 srl %g7, 3, %g3
839 or %g2, %g5, %g2
840 sub %o1, %g3, %o1
841 andcc %o2, 2, %g0
842 st %g2, [%o0]
843 be 1f
844 andcc %o2, 1, %g0
845
846 ldub [%o1], %g2
847 add %o1, 2, %o1
848 stb %g2, [%o0 + 4]
849 add %o0, 2, %o0
850 ldub [%o1 - 1], %g2
851 stb %g2, [%o0 + 3]
8521:
853 be 1f
854 nop
855 ldub [%o1], %g2
856 stb %g2, [%o0 + 4]
8571:
858 retl
859 RETL_INSN
860
861#ifdef FASTER_NONALIGNED
862
86387: /* faster_nonaligned */
864
865 andcc %o1, 3, %g0
866 be 3f
867 andcc %o1, 1, %g0
868
869 be 4f
870 andcc %o1, 2, %g0
871
872 ldub [%o1], %g2
873 add %o1, 1, %o1
874 stb %g2, [%o0]
875 sub %o2, 1, %o2
876 bne 3f
877 add %o0, 1, %o0
8784:
879 lduh [%o1], %g2
880 add %o1, 2, %o1
881 srl %g2, 8, %g3
882 sub %o2, 2, %o2
883 stb %g3, [%o0]
884 add %o0, 2, %o0
885 stb %g2, [%o0 - 1]
8863:
887 andcc %o1, 4, %g0
888
889 bne 2f
890 cmp %o5, 1
891
892 ld [%o1], %o4
893 srl %o4, 24, %g2
894 stb %g2, [%o0]
895 srl %o4, 16, %g3
896 stb %g3, [%o0 + 1]
897 srl %o4, 8, %g2
898 stb %g2, [%o0 + 2]
899 sub %o2, 4, %o2
900 stb %o4, [%o0 + 3]
901 add %o1, 4, %o1
902 add %o0, 4, %o0
9032:
904 be 33f
905 cmp %o5, 2
906 be 32f
907 sub %o2, 4, %o2
90831:
909 ld [%o1], %g2
910 add %o1, 4, %o1
911 srl %g2, 24, %g3
912 and %o0, 7, %g5
913 stb %g3, [%o0]
914 cmp %g5, 7
915 sll %g2, 8, %g1
916 add %o0, 4, %o0
917 be 41f
918 and %o2, 0xffffffc0, %o3
919 ld [%o0 - 7], %o4
9204:
921 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
922 SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
923 SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
924 SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
925 subcc %o3, 64, %o3
926 add %o1, 64, %o1
927 bne 4b
928 add %o0, 64, %o0
929
930 andcc %o2, 0x30, %o3
931 be,a 1f
932 srl %g1, 16, %g2
9334:
934 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
935 subcc %o3, 16, %o3
936 add %o1, 16, %o1
937 bne 4b
938 add %o0, 16, %o0
939
940 srl %g1, 16, %g2
9411:
942 st %o4, [%o0 - 7]
943 sth %g2, [%o0 - 3]
944 srl %g1, 8, %g4
945 b 88f
946 stb %g4, [%o0 - 1]
94732:
948 ld [%o1], %g2
949 add %o1, 4, %o1
950 srl %g2, 16, %g3
951 and %o0, 7, %g5
952 sth %g3, [%o0]
953 cmp %g5, 6
954 sll %g2, 16, %g1
955 add %o0, 4, %o0
956 be 42f
957 and %o2, 0xffffffc0, %o3
958 ld [%o0 - 6], %o4
9594:
960 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
961 SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
962 SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
963 SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
964 subcc %o3, 64, %o3
965 add %o1, 64, %o1
966 bne 4b
967 add %o0, 64, %o0
968
969 andcc %o2, 0x30, %o3
970 be,a 1f
971 srl %g1, 16, %g2
9724:
973 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
974 subcc %o3, 16, %o3
975 add %o1, 16, %o1
976 bne 4b
977 add %o0, 16, %o0
978
979 srl %g1, 16, %g2
9801:
981 st %o4, [%o0 - 6]
982 b 88f
983 sth %g2, [%o0 - 2]
98433:
985 ld [%o1], %g2
986 sub %o2, 4, %o2
987 srl %g2, 24, %g3
988 and %o0, 7, %g5
989 stb %g3, [%o0]
990 cmp %g5, 5
991 srl %g2, 8, %g4
992 sll %g2, 24, %g1
993 sth %g4, [%o0 + 1]
994 add %o1, 4, %o1
995 be 43f
996 and %o2, 0xffffffc0, %o3
997
998 ld [%o0 - 1], %o4
999 add %o0, 4, %o0
10004:
1001 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
1002 SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
1003 SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
1004 SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
1005 subcc %o3, 64, %o3
1006 add %o1, 64, %o1
1007 bne 4b
1008 add %o0, 64, %o0
1009
1010 andcc %o2, 0x30, %o3
1011 be,a 1f
1012 srl %g1, 24, %g2
10134:
1014 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
1015 subcc %o3, 16, %o3
1016 add %o1, 16, %o1
1017 bne 4b
1018 add %o0, 16, %o0
1019
1020 srl %g1, 24, %g2
10211:
1022 st %o4, [%o0 - 5]
1023 b 88f
1024 stb %g2, [%o0 - 1]
102541:
1026 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
1027 SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
1028 SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
1029 SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
1030 subcc %o3, 64, %o3
1031 add %o1, 64, %o1
1032 bne 41b
1033 add %o0, 64, %o0
1034
1035 andcc %o2, 0x30, %o3
1036 be,a 1f
1037 srl %g1, 16, %g2
10384:
1039 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
1040 subcc %o3, 16, %o3
1041 add %o1, 16, %o1
1042 bne 4b
1043 add %o0, 16, %o0
1044
1045 srl %g1, 16, %g2
10461:
1047 sth %g2, [%o0 - 3]
1048 srl %g1, 8, %g4
1049 b 88f
1050 stb %g4, [%o0 - 1]
105143:
1052 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
1053 SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
1054 SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
1055 SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
1056 subcc %o3, 64, %o3
1057 add %o1, 64, %o1
1058 bne 43b
1059 add %o0, 64, %o0
1060
1061 andcc %o2, 0x30, %o3
1062 be,a 1f
1063 srl %g1, 24, %g2
10644:
1065 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
1066 subcc %o3, 16, %o3
1067 add %o1, 16, %o1
1068 bne 4b
1069 add %o0, 16, %o0
1070
1071 srl %g1, 24, %g2
10721:
1073 stb %g2, [%o0 + 3]
1074 b 88f
1075 add %o0, 4, %o0
107642:
1077 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
1078 SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
1079 SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
1080 SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
1081 subcc %o3, 64, %o3
1082 add %o1, 64, %o1
1083 bne 42b
1084 add %o0, 64, %o0
1085
1086 andcc %o2, 0x30, %o3
1087 be,a 1f
1088 srl %g1, 16, %g2
10894:
1090 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
1091 subcc %o3, 16, %o3
1092 add %o1, 16, %o1
1093 bne 4b
1094 add %o0, 16, %o0
1095
1096 srl %g1, 16, %g2
10971:
1098 sth %g2, [%o0 - 2]
1099
1100 /* Fall through */
1101
1102#endif /* FASTER_NONALIGNED */
1103
110488: /* short_end */
1105
1106 and %o2, 0xe, %o3
110720:
1108 sethi %hi(89f), %o5
1109 sll %o3, 3, %o4
1110 add %o0, %o3, %o0
1111 sub %o5, %o4, %o5
1112 add %o1, %o3, %o1
1113 jmpl %o5 + %lo(89f), %g0
1114 andcc %o2, 1, %g0
1115
1116 MOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
1117 MOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
1118 MOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
1119 MOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
1120 MOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
1121 MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
1122 MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
1123
112489: /* short_table_end */
1125
1126 be 1f
1127 nop
1128
1129 ldub [%o1], %g2
1130 stb %g2, [%o0]
11311:
1132 retl
1133 RETL_INSN
1134
113590: /* short_aligned_end */
1136 bne 88b
1137 andcc %o2, 8, %g0
1138
1139 be 1f
1140 andcc %o2, 4, %g0
1141
1142 ld [%o1 + 0x00], %g2
1143 ld [%o1 + 0x04], %g3
1144 add %o1, 8, %o1
1145 st %g2, [%o0 + 0x00]
1146 st %g3, [%o0 + 0x04]
1147 add %o0, 8, %o0
11481:
1149 b 81b
1150 mov %o2, %g1