summaryrefslogtreecommitdiffstats
path: root/arch/sparc/lib/memcpy.S
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-04-29 21:13:14 +0000
committer <ralf@linux-mips.org>1997-04-29 21:13:14 +0000
commit19c9bba94152148523ba0f7ef7cffe3d45656b11 (patch)
tree40b1cb534496a7f1ca0f5c314a523c69f1fee464 /arch/sparc/lib/memcpy.S
parent7206675c40394c78a90e74812bbdbf8cf3cca1be (diff)
Import of Linux/MIPS 2.1.36
Diffstat (limited to 'arch/sparc/lib/memcpy.S')
-rw-r--r--arch/sparc/lib/memcpy.S1368
1 files changed, 1077 insertions, 291 deletions
diff --git a/arch/sparc/lib/memcpy.S b/arch/sparc/lib/memcpy.S
index c4f0394a4..54cc7b460 100644
--- a/arch/sparc/lib/memcpy.S
+++ b/arch/sparc/lib/memcpy.S
@@ -1,188 +1,606 @@
-/* memcpy.S: Sparc optimized memcpy code.
- *
- * Copyright(C) 1995 Linus Torvalds
- * Copyright(C) 1996 David S. Miller
- * Copyright(C) 1996 Eddie C. Dost
- * Copyright(C) 1996 Jakub Jelinek
- *
- * derived from:
- * e-mail between David and Eddie.
+/* memcpy.S: Sparc optimized memcpy, bcopy and memmove code
+ * Hand optimized from GNU libc's memcpy, bcopy and memmove
+ * Copyright (C) 1991,1996 Free Software Foundation
+ * Copyright (C) 1995 Linus Torvalds (Linus.Torvalds@helsinki.fi)
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
*/
+#ifdef __KERNEL__
+
#include <asm/cprefix.h>
-#include <asm/ptrace.h>
+
+#define FUNC(x) \
+ .globl C_LABEL(x); \
+ .type C_LABEL(x),@function; \
+ .align 4; \
+C_LABEL(x):
+
+#undef FASTER_REVERSE
+#undef FASTER_NONALIGNED
+#define FASTER_ALIGNED
+
+/* In kernel these functions don't return a value.
+ * One should use macros in asm/string.h for that purpose.
+ * We return 0, so that bugs are more apparent.
+ */
+#define SETUP_RETL
+#define RETL_INSN clr %o0
+
+#else
+
+/* libc */
+
+#include "DEFS.h"
+
+#define FASTER_REVERSE
+#define FASTER_NONALIGNED
+#define FASTER_ALIGNED
+
+#define SETUP_RETL mov %o0, %g6
+#define RETL_INSN mov %g6, %o0
+
+#endif
/* Both these macros have to start with exactly the same insn */
-#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
- ldd [%src + offset + 0x00], %t0; \
- ldd [%src + offset + 0x08], %t2; \
- ldd [%src + offset + 0x10], %t4; \
- ldd [%src + offset + 0x18], %t6; \
- st %t0, [%dst + offset + 0x00]; \
- st %t1, [%dst + offset + 0x04]; \
- st %t2, [%dst + offset + 0x08]; \
- st %t3, [%dst + offset + 0x0c]; \
- st %t4, [%dst + offset + 0x10]; \
- st %t5, [%dst + offset + 0x14]; \
- st %t6, [%dst + offset + 0x18]; \
+#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
+ ldd [%src + offset + 0x00], %t0; \
+ ldd [%src + offset + 0x08], %t2; \
+ ldd [%src + offset + 0x10], %t4; \
+ ldd [%src + offset + 0x18], %t6; \
+ st %t0, [%dst + offset + 0x00]; \
+ st %t1, [%dst + offset + 0x04]; \
+ st %t2, [%dst + offset + 0x08]; \
+ st %t3, [%dst + offset + 0x0c]; \
+ st %t4, [%dst + offset + 0x10]; \
+ st %t5, [%dst + offset + 0x14]; \
+ st %t6, [%dst + offset + 0x18]; \
st %t7, [%dst + offset + 0x1c];
-#define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
- ldd [%src + offset + 0x00], %t0; \
- ldd [%src + offset + 0x08], %t2; \
- ldd [%src + offset + 0x10], %t4; \
- ldd [%src + offset + 0x18], %t6; \
- std %t0, [%dst + offset + 0x00]; \
- std %t2, [%dst + offset + 0x08]; \
- std %t4, [%dst + offset + 0x10]; \
+#define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
+ ldd [%src + offset + 0x00], %t0; \
+ ldd [%src + offset + 0x08], %t2; \
+ ldd [%src + offset + 0x10], %t4; \
+ ldd [%src + offset + 0x18], %t6; \
+ std %t0, [%dst + offset + 0x00]; \
+ std %t2, [%dst + offset + 0x08]; \
+ std %t4, [%dst + offset + 0x10]; \
std %t6, [%dst + offset + 0x18];
-#define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
- ldd [%src - offset - 0x10], %t0; \
- ldd [%src - offset - 0x08], %t2; \
- st %t0, [%dst - offset - 0x10]; \
- st %t1, [%dst - offset - 0x0c]; \
- st %t2, [%dst - offset - 0x08]; \
+#define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldd [%src - offset - 0x10], %t0; \
+ ldd [%src - offset - 0x08], %t2; \
+ st %t0, [%dst - offset - 0x10]; \
+ st %t1, [%dst - offset - 0x0c]; \
+ st %t2, [%dst - offset - 0x08]; \
st %t3, [%dst - offset - 0x04];
-#define MOVE_HALFCHUNK(src, dst, offset, t0, t1, t2, t3) \
- lduh [%src + offset + 0x00], %t0; \
- lduh [%src + offset + 0x02], %t1; \
- lduh [%src + offset + 0x04], %t2; \
- lduh [%src + offset + 0x06], %t3; \
- sth %t0, [%dst + offset + 0x00]; \
- sth %t1, [%dst + offset + 0x02]; \
- sth %t2, [%dst + offset + 0x04]; \
- sth %t3, [%dst + offset + 0x06];
-
-#define MOVE_SHORTCHUNK(src, dst, offset, t0, t1) \
- ldub [%src - offset - 0x02], %t0; \
- ldub [%src - offset - 0x01], %t1; \
- stb %t0, [%dst - offset - 0x02]; \
+#define MOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldd [%src - offset - 0x10], %t0; \
+ ldd [%src - offset - 0x08], %t2; \
+ std %t0, [%dst - offset - 0x10]; \
+ std %t2, [%dst - offset - 0x08];
+
+#define MOVE_SHORTCHUNK(src, dst, offset, t0, t1) \
+ ldub [%src - offset - 0x02], %t0; \
+ ldub [%src - offset - 0x01], %t1; \
+ stb %t0, [%dst - offset - 0x02]; \
stb %t1, [%dst - offset - 0x01];
+/* Both these macros have to start with exactly the same insn */
+#define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
+ ldd [%src - offset - 0x20], %t0; \
+ ldd [%src - offset - 0x18], %t2; \
+ ldd [%src - offset - 0x10], %t4; \
+ ldd [%src - offset - 0x08], %t6; \
+ st %t0, [%dst - offset - 0x20]; \
+ st %t1, [%dst - offset - 0x1c]; \
+ st %t2, [%dst - offset - 0x18]; \
+ st %t3, [%dst - offset - 0x14]; \
+ st %t4, [%dst - offset - 0x10]; \
+ st %t5, [%dst - offset - 0x0c]; \
+ st %t6, [%dst - offset - 0x08]; \
+ st %t7, [%dst - offset - 0x04];
+
+#define RMOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
+ ldd [%src - offset - 0x20], %t0; \
+ ldd [%src - offset - 0x18], %t2; \
+ ldd [%src - offset - 0x10], %t4; \
+ ldd [%src - offset - 0x08], %t6; \
+ std %t0, [%dst - offset - 0x20]; \
+ std %t2, [%dst - offset - 0x18]; \
+ std %t4, [%dst - offset - 0x10]; \
+ std %t6, [%dst - offset - 0x08];
+
+#define RMOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
+ ldd [%src + offset + 0x00], %t0; \
+ ldd [%src + offset + 0x08], %t2; \
+ st %t0, [%dst + offset + 0x00]; \
+ st %t1, [%dst + offset + 0x04]; \
+ st %t2, [%dst + offset + 0x08]; \
+ st %t3, [%dst + offset + 0x0c];
+
+#define RMOVE_SHORTCHUNK(src, dst, offset, t0, t1) \
+ ldub [%src + offset + 0x00], %t0; \
+ ldub [%src + offset + 0x01], %t1; \
+ stb %t0, [%dst + offset + 0x00]; \
+ stb %t1, [%dst + offset + 0x01];
+
+#define SMOVE_CHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2) \
+ ldd [%src + offset + 0x00], %t0; \
+ ldd [%src + offset + 0x08], %t2; \
+ srl %t0, shir, %t5; \
+ srl %t1, shir, %t6; \
+ sll %t0, shil, %t0; \
+ or %t5, %prev, %t5; \
+ sll %t1, shil, %prev; \
+ or %t6, %t0, %t0; \
+ srl %t2, shir, %t1; \
+ srl %t3, shir, %t6; \
+ sll %t2, shil, %t2; \
+ or %t1, %prev, %t1; \
+ std %t4, [%dst + offset + offset2 - 0x04]; \
+ std %t0, [%dst + offset + offset2 + 0x04]; \
+ sll %t3, shil, %prev; \
+ or %t6, %t2, %t4;
+
+#define SMOVE_ALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2) \
+ ldd [%src + offset + 0x00], %t0; \
+ ldd [%src + offset + 0x08], %t2; \
+ srl %t0, shir, %t4; \
+ srl %t1, shir, %t5; \
+ sll %t0, shil, %t6; \
+ or %t4, %prev, %t0; \
+ sll %t1, shil, %prev; \
+ or %t5, %t6, %t1; \
+ srl %t2, shir, %t4; \
+ srl %t3, shir, %t5; \
+ sll %t2, shil, %t6; \
+ or %t4, %prev, %t2; \
+ sll %t3, shil, %prev; \
+ or %t5, %t6, %t3; \
+ std %t0, [%dst + offset + offset2 + 0x00]; \
+ std %t2, [%dst + offset + offset2 + 0x08];
+
.text
.align 4
- .globl C_LABEL(__memcpy), C_LABEL(memcpy), C_LABEL(bcopy)
- .globl C_LABEL(amemmove), C_LABEL(memmove)
-C_LABEL(bcopy):
- mov %o0, %o3
- mov %o1, %o0
- mov %o3, %o1
-C_LABEL(amemmove):
-C_LABEL(memmove):
-/* This should be kept as optimized as possible */
- cmp %o0, %o1
- bleu 1f
- xor %o0, %o1, %o4
-
- add %o1, %o2, %o3
- cmp %o3, %o0
- bleu 2f
- andcc %o4, 3, %g0
-
-/* But I think from now on, we can hold on. Or tell me, is memmoving
- * overlapping regions such a nice game? */
-
- mov %o0, %g1
- add %o1, %o2, %o1
- add %o0, %o2, %o0
- sub %o1, 1, %o1
- sub %o0, 1, %o0
+#ifdef FASTER_REVERSE
+
+70: /* rdword_align */
+
+ andcc %o1, 1, %g0
+ be 4f
+ andcc %o1, 2, %g0
+
+ ldub [%o1 - 1], %g2
+ sub %o1, 1, %o1
+ stb %g2, [%o0 - 1]
+ sub %o2, 1, %o2
+ be 3f
+ sub %o0, 1, %o0
+4:
+ lduh [%o1 - 2], %g2
+ sub %o1, 2, %o1
+ sth %g2, [%o0 - 2]
+ sub %o2, 2, %o2
+ b 3f
+ sub %o0, 2, %o0
+
+#endif /* FASTER_REVERSE */
+
+0:
+ retl
+ nop ! Only bcopy returns here and it retuns void...
+
+FUNC(bcopy)
+ mov %o0, %o3
+ mov %o1, %o0
+ mov %o3, %o1
+ tst %o2
+ bcs 0b
+ /* Do the cmp in the delay slot */
+#ifdef __KERNEL__
+FUNC(amemmove)
+FUNC(__memmove)
+#endif
+FUNC(memmove)
+ cmp %o0, %o1
+ SETUP_RETL
+ bleu 9f
+ sub %o0, %o1, %o4
+
+ add %o1, %o2, %o3
+ cmp %o3, %o0
+ bleu 0f
+ andcc %o4, 3, %o5
+
+#ifndef FASTER_REVERSE
+
+ add %o1, %o2, %o1
+ add %o0, %o2, %o0
+ sub %o1, 1, %o1
+ sub %o0, 1, %o0
-reverse_bytes:
- ldub [%o1], %o4
- subcc %o2, 1, %o2
- stb %o4, [%o0]
- sub %o1, 1, %o1
- bne reverse_bytes
- sub %o0, 1, %o0
+1: /* reverse_bytes */
+
+ ldub [%o1], %o4
+ subcc %o2, 1, %o2
+ stb %o4, [%o0]
+ sub %o1, 1, %o1
+ bne 1b
+ sub %o0, 1, %o0
retl
- mov %g1, %o0
-
-/* And here start optimizing again... */
-
-dword_align:
- andcc %o1, 1, %g0
- be 4f
- andcc %o1, 2, %g0
-
- ldub [%o1], %g2
- add %o1, 1, %o1
- stb %g2, [%o0]
- sub %o2, 1, %o2
- bne 3f
- add %o0, 1, %o0
-
- lduh [%o1], %g2
- add %o1, 2, %o1
- sth %g2, [%o0]
- sub %o2, 2, %o2
- b 3f
- add %o0, 2, %o0
-4:
- lduh [%o1], %g2
- add %o1, 2, %o1
- sth %g2, [%o0]
- sub %o2, 2, %o2
- b 3f
- add %o0, 2, %o0
-
-C_LABEL(__memcpy):
-C_LABEL(memcpy): /* %o0=dst %o1=src %o2=len */
- xor %o0, %o1, %o4
+ RETL_INSN
+
+#else /* FASTER_REVERSE */
+
+ add %o1, %o2, %o1
+ add %o0, %o2, %o0
+ bne 77f
+ cmp %o2, 15
+ bleu 91f
+ andcc %o1, 3, %g0
+ bne 70b
+3:
+ andcc %o1, 4, %g0
+
+ be 2f
+ mov %o2, %g1
+
+ ld [%o1 - 4], %o4
+ sub %g1, 4, %g1
+ st %o4, [%o0 - 4]
+ sub %o1, 4, %o1
+ sub %o0, 4, %o0
+2:
+ andcc %g1, 0xffffff80, %g7
+ be 3f
+ andcc %o0, 4, %g0
+
+ be 74f + 4
+5:
+ RMOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
+ RMOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
+ RMOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
+ RMOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
+ subcc %g7, 128, %g7
+ sub %o1, 128, %o1
+ bne 5b
+ sub %o0, 128, %o0
+3:
+ andcc %g1, 0x70, %g7
+ be 72f
+ andcc %g1, 8, %g0
+
+ sethi %hi(72f), %o5
+ srl %g7, 1, %o4
+ add %g7, %o4, %o4
+ sub %o1, %g7, %o1
+ sub %o5, %o4, %o5
+ jmpl %o5 + %lo(72f), %g0
+ sub %o0, %g7, %o0
+
+71: /* rmemcpy_table */
+ RMOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
+ RMOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
+ RMOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
+ RMOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
+ RMOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
+ RMOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
+ RMOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
+
+72: /* rmemcpy_table_end */
+
+ be 73f
+ andcc %g1, 4, %g0
+
+ ldd [%o1 - 0x08], %g2
+ sub %o0, 8, %o0
+ sub %o1, 8, %o1
+ st %g2, [%o0]
+ st %g3, [%o0 + 0x04]
+
+73: /* rmemcpy_last7 */
+
+ be 1f
+ andcc %g1, 2, %g0
+
+ ld [%o1 - 4], %g2
+ sub %o1, 4, %o1
+ st %g2, [%o0 - 4]
+ sub %o0, 4, %o0
+1:
+ be 1f
+ andcc %g1, 1, %g0
+
+ lduh [%o1 - 2], %g2
+ sub %o1, 2, %o1
+ sth %g2, [%o0 - 2]
+ sub %o0, 2, %o0
1:
- andcc %o4, 3, %o5
+ be 1f
+ nop
+
+ ldub [%o1 - 1], %g2
+ stb %g2, [%o0 - 1]
+1:
+ retl
+ RETL_INSN
+
+74: /* rldd_std */
+ RMOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
+ RMOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
+ RMOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
+ RMOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
+ subcc %g7, 128, %g7
+ sub %o1, 128, %o1
+ bne 74b
+ sub %o0, 128, %o0
+
+ andcc %g1, 0x70, %g7
+ be 72b
+ andcc %g1, 8, %g0
+
+ sethi %hi(72b), %o5
+ srl %g7, 1, %o4
+ add %g7, %o4, %o4
+ sub %o1, %g7, %o1
+ sub %o5, %o4, %o5
+ jmpl %o5 + %lo(72b), %g0
+ sub %o0, %g7, %o0
+
+75: /* rshort_end */
+
+ and %o2, 0xe, %o3
2:
- bne cannot_optimize
- cmp %o2, 15
+ sethi %hi(76f), %o5
+ sll %o3, 3, %o4
+ sub %o0, %o3, %o0
+ sub %o5, %o4, %o5
+ sub %o1, %o3, %o1
+ jmpl %o5 + %lo(76f), %g0
+ andcc %o2, 1, %g0
+
+ RMOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
+ RMOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
+ RMOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
+ RMOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
+ RMOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
+ RMOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
+ RMOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
+
+76: /* rshort_table_end */
+
+ be 1f
+ nop
+ ldub [%o1 - 1], %g2
+ stb %g2, [%o0 - 1]
+1:
+ retl
+ RETL_INSN
+
+91: /* rshort_aligned_end */
+
+ bne 75b
+ andcc %o2, 8, %g0
- bleu short_aligned_end
- andcc %o1, 3, %g0
+ be 1f
+ andcc %o2, 4, %g0
- bne dword_align
+ ld [%o1 - 0x08], %g2
+ ld [%o1 - 0x04], %g3
+ sub %o1, 8, %o1
+ st %g2, [%o0 - 0x08]
+ st %g3, [%o0 - 0x04]
+ sub %o0, 8, %o0
+1:
+ b 73b
+ mov %o2, %g1
+
+77: /* rnon_aligned */
+ cmp %o2, 15
+ bleu 75b
+ andcc %o0, 3, %g0
+ be 64f
+ andcc %o0, 1, %g0
+ be 63f
+ andcc %o0, 2, %g0
+ ldub [%o1 - 1], %g5
+ sub %o1, 1, %o1
+ stb %g5, [%o0 - 1]
+ sub %o0, 1, %o0
+ be 64f
+ sub %o2, 1, %o2
+63:
+ ldub [%o1 - 1], %g5
+ sub %o1, 2, %o1
+ stb %g5, [%o0 - 1]
+ sub %o0, 2, %o0
+ ldub [%o1], %g5
+ sub %o2, 2, %o2
+ stb %g5, [%o0]
+64:
+ and %o1, 3, %g2
+ and %o1, -4, %o1
+ and %o2, 0xc, %g3
+ add %o1, 4, %o1
+ cmp %g3, 4
+ sll %g2, 3, %g4
+ mov 32, %g2
+ be 4f
+ sub %g2, %g4, %g7
+
+ blu 3f
+ cmp %g3, 8
+
+ be 2f
+ srl %o2, 2, %g3
+
+ ld [%o1 - 4], %o3
+ add %o0, -8, %o0
+ ld [%o1 - 8], %o4
+ add %o1, -16, %o1
+ b 7f
+ add %g3, 1, %g3
+2:
+ ld [%o1 - 4], %o4
+ add %o0, -4, %o0
+ ld [%o1 - 8], %g1
+ add %o1, -12, %o1
+ b 8f
+ add %g3, 2, %g3
3:
- andcc %o1, 4, %g0
+ ld [%o1 - 4], %o5
+ add %o0, -12, %o0
+ ld [%o1 - 8], %o3
+ add %o1, -20, %o1
+ b 6f
+ srl %o2, 2, %g3
+4:
+ ld [%o1 - 4], %g1
+ srl %o2, 2, %g3
+ ld [%o1 - 8], %o5
+ add %o1, -24, %o1
+ add %o0, -16, %o0
+ add %g3, -1, %g3
+
+ ld [%o1 + 12], %o3
+5:
+ sll %o5, %g4, %g2
+ srl %g1, %g7, %g5
+ or %g2, %g5, %g2
+ st %g2, [%o0 + 12]
+6:
+ ld [%o1 + 8], %o4
+ sll %o3, %g4, %g2
+ srl %o5, %g7, %g5
+ or %g2, %g5, %g2
+ st %g2, [%o0 + 8]
+7:
+ ld [%o1 + 4], %g1
+ sll %o4, %g4, %g2
+ srl %o3, %g7, %g5
+ or %g2, %g5, %g2
+ st %g2, [%o0 + 4]
+8:
+ ld [%o1], %o5
+ sll %g1, %g4, %g2
+ srl %o4, %g7, %g5
+ addcc %g3, -4, %g3
+ or %g2, %g5, %g2
+ add %o1, -16, %o1
+ st %g2, [%o0]
+ add %o0, -16, %o0
+ bne,a 5b
+ ld [%o1 + 12], %o3
+ sll %o5, %g4, %g2
+ srl %g1, %g7, %g5
+ srl %g4, 3, %g3
+ or %g2, %g5, %g2
+ add %o1, %g3, %o1
+ andcc %o2, 2, %g0
+ st %g2, [%o0 + 12]
+ be 1f
+ andcc %o2, 1, %g0
+
+ ldub [%o1 + 15], %g5
+ add %o1, -2, %o1
+ stb %g5, [%o0 + 11]
+ add %o0, -2, %o0
+ ldub [%o1 + 16], %g5
+ stb %g5, [%o0 + 12]
+1:
+ be 1f
+ nop
+ ldub [%o1 + 15], %g5
+ stb %g5, [%o0 + 11]
+1:
+ retl
+ RETL_INSN
- be 2f
- mov %o2, %g1
+#endif /* FASTER_REVERSE */
- ld [%o1], %o4
- sub %g1, 4, %g1
- st %o4, [%o0]
- add %o1, 4, %o1
- add %o0, 4, %o0
+78: /* dword_align */
+
+ andcc %o1, 1, %g0
+ be 4f
+ andcc %o1, 2, %g0
+
+ ldub [%o1], %g2
+ add %o1, 1, %o1
+ stb %g2, [%o0]
+ sub %o2, 1, %o2
+ bne 3f
+ add %o0, 1, %o0
+4:
+ lduh [%o1], %g2
+ add %o1, 2, %o1
+ sth %g2, [%o0]
+ sub %o2, 2, %o2
+ b 3f
+ add %o0, 2, %o0
+
+#ifdef __KERNEL__
+FUNC(__memcpy)
+#endif
+FUNC(memcpy) /* %o0=dst %o1=src %o2=len */
+
+ sub %o0, %o1, %o4
+ SETUP_RETL
+9:
+ andcc %o4, 3, %o5
+0:
+ bne 86f
+ cmp %o2, 15
+
+ bleu 90f
+ andcc %o1, 3, %g0
+
+ bne 78b
+3:
+ andcc %o1, 4, %g0
+
+ be 2f
+ mov %o2, %g1
+
+ ld [%o1], %o4
+ sub %g1, 4, %g1
+ st %o4, [%o0]
+ add %o1, 4, %o1
+ add %o0, 4, %o0
2:
- andcc %g1, 0xffffff80, %g7
- be 3f
- andcc %o0, 4, %g0
+ andcc %g1, 0xffffff80, %g7
+ be 3f
+ andcc %o0, 4, %g0
- be ldd_std + 4
+ be 82f + 4
5:
MOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
- subcc %g7, 128, %g7
- add %o1, 128, %o1
- bne 5b
- add %o0, 128, %o0
+ subcc %g7, 128, %g7
+ add %o1, 128, %o1
+ bne 5b
+ add %o0, 128, %o0
3:
- andcc %g1, 0x70, %g7
- be memcpy_table_end
- andcc %g1, 8, %g0
-
- sethi %hi(memcpy_table_end), %o5
- srl %g7, 1, %o4
- add %g7, %o4, %o4
- add %o1, %g7, %o1
- sub %o5, %o4, %o5
- jmpl %o5 + %lo(memcpy_table_end), %g0
- add %o0, %g7, %o0
-
-memcpy_table:
+ andcc %g1, 0x70, %g7
+ be 80f
+ andcc %g1, 8, %g0
+
+ sethi %hi(80f), %o5
+ srl %g7, 1, %o4
+ add %g7, %o4, %o4
+ add %o1, %g7, %o1
+ sub %o5, %o4, %o5
+ jmpl %o5 + %lo(80f), %g0
+ add %o0, %g7, %o0
+
+79: /* memcpy_table */
+
MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
@@ -191,144 +609,509 @@ memcpy_table:
MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
-memcpy_table_end:
- be memcpy_last7
- andcc %g1, 4, %g0
-
- ldd [%o1], %g2
- add %o0, 8, %o0
- add %o1, 8, %o1
- st %g2, [%o0 - 0x08]
- st %g3, [%o0 - 0x04]
-memcpy_last7:
- be 1f
- andcc %g1, 2, %g0
-
- ld [%o1], %g2
- add %o1, 4, %o1
- st %g2, [%o0]
- add %o0, 4, %o0
+80: /* memcpy_table_end */
+ be 81f
+ andcc %g1, 4, %g0
+
+ ldd [%o1], %g2
+ add %o0, 8, %o0
+ st %g2, [%o0 - 0x08]
+ add %o1, 8, %o1
+ st %g3, [%o0 - 0x04]
+
+81: /* memcpy_last7 */
+
+ be 1f
+ andcc %g1, 2, %g0
+
+ ld [%o1], %g2
+ add %o1, 4, %o1
+ st %g2, [%o0]
+ add %o0, 4, %o0
1:
- be 1f
- andcc %g1, 1, %g0
+ be 1f
+ andcc %g1, 1, %g0
- lduh [%o1], %g2
- add %o1, 2, %o1
- sth %g2, [%o0]
- add %o0, 2, %o0
+ lduh [%o1], %g2
+ add %o1, 2, %o1
+ sth %g2, [%o0]
+ add %o0, 2, %o0
1:
- be 1f
+ be 1f
nop
- ldub [%o1], %g2
- stb %g2, [%o0]
+ ldub [%o1], %g2
+ stb %g2, [%o0]
1:
retl
- nop
-
- /* Placed here for cache reasons. */
- .globl C_LABEL(__copy_to_user), C_LABEL(__copy_from_user)
-C_LABEL(__copy_to_user):
- b copy_user_common
- st %o0, [%g6 + THREAD_EX_ADDR]
-
-C_LABEL(__copy_from_user):
- st %o1, [%g6 + THREAD_EX_ADDR]
-
-copy_user_common:
- ld [%g6 + THREAD_EX_COUNT], %g1
- set copy_user_failure, %g2
- add %g1, 1, %g1
- st %o7, [%g6 + THREAD_EX_PC]
- st %g1, [%g6 + THREAD_EX_COUNT]
- call C_LABEL(__memcpy)
- st %g2, [%g6 + THREAD_EX_EXPC]
-
-copy_user_success:
- ldd [%g6 + THREAD_EX_COUNT], %g2
- mov 0, %o0
- sub %g2, 1, %g1
- jmpl %g3 + 0x8, %g0
- st %g1, [%g6 + THREAD_EX_COUNT]
-
-copy_user_failure:
- jmpl %g3 + 0x8, %g0
- mov %g2, %o0
-
-ldd_std:
+ RETL_INSN
+
+82: /* ldd_std */
MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
- subcc %g7, 128, %g7
- add %o1, 128, %o1
- bne ldd_std
- add %o0, 128, %o0
-
- andcc %g1, 0x70, %g7
- be memcpy_table_end
- andcc %g1, 8, %g0
-
- sethi %hi(memcpy_table_end), %o5
- srl %g7, 1, %o4
- add %g7, %o4, %o4
- add %o1, %g7, %o1
- sub %o5, %o4, %o5
- jmpl %o5 + %lo(memcpy_table_end), %g0
- add %o0, %g7, %o0
-
-cannot_optimize:
- bleu short_end
- cmp %o5, 2
-
- bne byte_chunk
- and %o2, 0xfffffff0, %o3
-
- andcc %o1, 1, %g0
- be 1f
+ subcc %g7, 128, %g7
+ add %o1, 128, %o1
+ bne 82b
+ add %o0, 128, %o0
+
+#ifndef FASTER_ALIGNED
+
+ andcc %g1, 0x70, %g7
+ be 80b
+ andcc %g1, 8, %g0
+
+ sethi %hi(80b), %o5
+ srl %g7, 1, %o4
+ add %g7, %o4, %o4
+ add %o1, %g7, %o1
+ sub %o5, %o4, %o5
+ jmpl %o5 + %lo(80b), %g0
+ add %o0, %g7, %o0
+
+#else /* FASTER_ALIGNED */
+
+ andcc %g1, 0x70, %g7
+ be 84f
+ andcc %g1, 8, %g0
+
+ sethi %hi(84f), %o5
+ add %o1, %g7, %o1
+ sub %o5, %g7, %o5
+ jmpl %o5 + %lo(84f), %g0
+ add %o0, %g7, %o0
+
+83: /* amemcpy_table */
+
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
+ MOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
+
+84: /* amemcpy_table_end */
+ be 85f
+ andcc %g1, 4, %g0
+
+ ldd [%o1], %g2
+ add %o0, 8, %o0
+ std %g2, [%o0 - 0x08]
+ add %o1, 8, %o1
+85: /* amemcpy_last7 */
+ be 1f
+ andcc %g1, 2, %g0
+
+ ld [%o1], %g2
+ add %o1, 4, %o1
+ st %g2, [%o0]
+ add %o0, 4, %o0
+1:
+ be 1f
+ andcc %g1, 1, %g0
+
+ lduh [%o1], %g2
+ add %o1, 2, %o1
+ sth %g2, [%o0]
+ add %o0, 2, %o0
+1:
+ be 1f
nop
- ldub [%o1], %g2
- add %o1, 1, %o1
- sub %o2, 1, %o2
- stb %g2, [%o0]
- andcc %o2, 0xfffffff0, %o3
- be short_end
- add %o0, 1, %o0
+ ldub [%o1], %g2
+ stb %g2, [%o0]
1:
- MOVE_HALFCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
- MOVE_HALFCHUNK(o1, o0, 0x08, g2, g3, g4, g5)
- subcc %o3, 0x10, %o3
- add %o1, 0x10, %o1
- bne 1b
- add %o0, 0x10, %o0
- b 2f
- and %o2, 0xe, %o3
+ retl
+ RETL_INSN
+
+#endif /* FASTER_ALIGNED */
+
+86: /* non_aligned */
+ cmp %o2, 6
+ bleu 88f
+
+#ifdef FASTER_NONALIGNED
+
+ cmp %o2, 256
+ bcc 87f
+
+#endif /* FASTER_NONALIGNED */
+
+ andcc %o0, 3, %g0
+ be 61f
+ andcc %o0, 1, %g0
+ be 60f
+ andcc %o0, 2, %g0
+
+ ldub [%o1], %g5
+ add %o1, 1, %o1
+ stb %g5, [%o0]
+ sub %o2, 1, %o2
+ bne 61f
+ add %o0, 1, %o0
+60:
+ ldub [%o1], %g3
+ add %o1, 2, %o1
+ stb %g3, [%o0]
+ sub %o2, 2, %o2
+ ldub [%o1 - 1], %g3
+ add %o0, 2, %o0
+ stb %g3, [%o0 - 1]
+61:
+ and %o1, 3, %g2
+ and %o2, 0xc, %g3
+ and %o1, -4, %o1
+ cmp %g3, 4
+ sll %g2, 3, %g4
+ mov 32, %g2
+ be 4f
+ sub %g2, %g4, %g7
-byte_chunk:
- MOVE_SHORTCHUNK(o1, o0, -0x02, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x04, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x06, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x08, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x0a, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x0c, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x0e, g2, g3)
- MOVE_SHORTCHUNK(o1, o0, -0x10, g2, g3)
- subcc %o3, 0x10, %o3
- add %o1, 0x10, %o1
- bne byte_chunk
- add %o0, 0x10, %o0
-
-short_end:
- and %o2, 0xe, %o3
+ blu 3f
+ cmp %g3, 0x8
+
+ be 2f
+ srl %o2, 2, %g3
+
+ ld [%o1], %o3
+ add %o0, -8, %o0
+ ld [%o1 + 4], %o4
+ b 8f
+ add %g3, 1, %g3
2:
- sethi %hi(short_table_end), %o5
- sll %o3, 3, %o4
- add %o0, %o3, %o0
- sub %o5, %o4, %o5
- add %o1, %o3, %o1
- jmpl %o5 + %lo(short_table_end), %g0
- andcc %o2, 1, %g0
+ ld [%o1], %o4
+ add %o0, -12, %o0
+ ld [%o1 + 4], %o5
+ add %g3, 2, %g3
+ b 9f
+ add %o1, -4, %o1
+3:
+ ld [%o1], %g1
+ add %o0, -4, %o0
+ ld [%o1 + 4], %o3
+ srl %o2, 2, %g3
+ b 7f
+ add %o1, 4, %o1
+4:
+ ld [%o1], %o5
+ cmp %o2, 7
+ ld [%o1 + 4], %g1
+ srl %o2, 2, %g3
+ bleu 10f
+ add %o1, 8, %o1
+
+ ld [%o1], %o3
+ add %g3, -1, %g3
+5:
+ sll %o5, %g4, %g2
+ srl %g1, %g7, %g5
+ or %g2, %g5, %g2
+ st %g2, [%o0]
+7:
+ ld [%o1 + 4], %o4
+ sll %g1, %g4, %g2
+ srl %o3, %g7, %g5
+ or %g2, %g5, %g2
+ st %g2, [%o0 + 4]
+8:
+ ld [%o1 + 8], %o5
+ sll %o3, %g4, %g2
+ srl %o4, %g7, %g5
+ or %g2, %g5, %g2
+ st %g2, [%o0 + 8]
+9:
+ ld [%o1 + 12], %g1
+ sll %o4, %g4, %g2
+ srl %o5, %g7, %g5
+ addcc %g3, -4, %g3
+ or %g2, %g5, %g2
+ add %o1, 16, %o1
+ st %g2, [%o0 + 12]
+ add %o0, 16, %o0
+ bne,a 5b
+ ld [%o1], %o3
+10:
+ sll %o5, %g4, %g2
+ srl %g1, %g7, %g5
+ srl %g7, 3, %g3
+ or %g2, %g5, %g2
+ sub %o1, %g3, %o1
+ andcc %o2, 2, %g0
+ st %g2, [%o0]
+ be 1f
+ andcc %o2, 1, %g0
+
+ ldub [%o1], %g2
+ add %o1, 2, %o1
+ stb %g2, [%o0 + 4]
+ add %o0, 2, %o0
+ ldub [%o1 - 1], %g2
+ stb %g2, [%o0 + 3]
+1:
+ be 1f
+ nop
+ ldub [%o1], %g2
+ stb %g2, [%o0 + 4]
+1:
+ retl
+ RETL_INSN
+
+#ifdef FASTER_NONALIGNED
+
+87: /* faster_nonaligned */
+
+ andcc %o1, 3, %g0
+ be 3f
+ andcc %o1, 1, %g0
+
+ be 4f
+ andcc %o1, 2, %g0
+
+ ldub [%o1], %g2
+ add %o1, 1, %o1
+ stb %g2, [%o0]
+ sub %o2, 1, %o2
+ bne 3f
+ add %o0, 1, %o0
+4:
+ lduh [%o1], %g2
+ add %o1, 2, %o1
+ srl %g2, 8, %g3
+ sub %o2, 2, %o2
+ stb %g3, [%o0]
+ add %o0, 2, %o0
+ stb %g2, [%o0 - 1]
+3:
+ andcc %o1, 4, %g0
+
+ bne 2f
+ cmp %o5, 1
+
+ ld [%o1], %o4
+ srl %o4, 24, %g2
+ stb %g2, [%o0]
+ srl %o4, 16, %g3
+ stb %g3, [%o0 + 1]
+ srl %o4, 8, %g2
+ stb %g2, [%o0 + 2]
+ sub %o2, 4, %o2
+ stb %o4, [%o0 + 3]
+ add %o1, 4, %o1
+ add %o0, 4, %o0
+2:
+ be 33f
+ cmp %o5, 2
+ be 32f
+ sub %o2, 4, %o2
+31:
+ ld [%o1], %g2
+ add %o1, 4, %o1
+ srl %g2, 24, %g3
+ and %o0, 7, %g5
+ stb %g3, [%o0]
+ cmp %g5, 7
+ sll %g2, 8, %g1
+ add %o0, 4, %o0
+ be 41f
+ and %o2, 0xffffffc0, %o3
+ ld [%o0 - 7], %o4
+4:
+ SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
+ SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
+ SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
+ SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
+ subcc %o3, 64, %o3
+ add %o1, 64, %o1
+ bne 4b
+ add %o0, 64, %o0
+
+ andcc %o2, 0x30, %o3
+ be,a 1f
+ srl %g1, 16, %g2
+4:
+ SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
+ subcc %o3, 16, %o3
+ add %o1, 16, %o1
+ bne 4b
+ add %o0, 16, %o0
+
+ srl %g1, 16, %g2
+1:
+ st %o4, [%o0 - 7]
+ sth %g2, [%o0 - 3]
+ srl %g1, 8, %g4
+ b 88f
+ stb %g4, [%o0 - 1]
+32:
+ ld [%o1], %g2
+ add %o1, 4, %o1
+ srl %g2, 16, %g3
+ and %o0, 7, %g5
+ sth %g3, [%o0]
+ cmp %g5, 6
+ sll %g2, 16, %g1
+ add %o0, 4, %o0
+ be 42f
+ and %o2, 0xffffffc0, %o3
+ ld [%o0 - 6], %o4
+4:
+ SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
+ SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
+ SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
+ SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
+ subcc %o3, 64, %o3
+ add %o1, 64, %o1
+ bne 4b
+ add %o0, 64, %o0
+
+ andcc %o2, 0x30, %o3
+ be,a 1f
+ srl %g1, 16, %g2
+4:
+ SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
+ subcc %o3, 16, %o3
+ add %o1, 16, %o1
+ bne 4b
+ add %o0, 16, %o0
+
+ srl %g1, 16, %g2
+1:
+ st %o4, [%o0 - 6]
+ b 88f
+ sth %g2, [%o0 - 2]
+33:
+ ld [%o1], %g2
+ sub %o2, 4, %o2
+ srl %g2, 24, %g3
+ and %o0, 7, %g5
+ stb %g3, [%o0]
+ cmp %g5, 5
+ srl %g2, 8, %g4
+ sll %g2, 24, %g1
+ sth %g4, [%o0 + 1]
+ add %o1, 4, %o1
+ be 43f
+ and %o2, 0xffffffc0, %o3
+
+ ld [%o0 - 1], %o4
+ add %o0, 4, %o0
+4:
+ SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
+ SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
+ SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
+ SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
+ subcc %o3, 64, %o3
+ add %o1, 64, %o1
+ bne 4b
+ add %o0, 64, %o0
+
+ andcc %o2, 0x30, %o3
+ be,a 1f
+ srl %g1, 24, %g2
+4:
+ SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
+ subcc %o3, 16, %o3
+ add %o1, 16, %o1
+ bne 4b
+ add %o0, 16, %o0
+
+ srl %g1, 24, %g2
+1:
+ st %o4, [%o0 - 5]
+ b 88f
+ stb %g2, [%o0 - 1]
+41:
+ SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
+ subcc %o3, 64, %o3
+ add %o1, 64, %o1
+ bne 41b
+ add %o0, 64, %o0
+
+ andcc %o2, 0x30, %o3
+ be,a 1f
+ srl %g1, 16, %g2
+4:
+ SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
+ subcc %o3, 16, %o3
+ add %o1, 16, %o1
+ bne 4b
+ add %o0, 16, %o0
+
+ srl %g1, 16, %g2
+1:
+ sth %g2, [%o0 - 3]
+ srl %g1, 8, %g4
+ b 88f
+ stb %g4, [%o0 - 1]
+43:
+ SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
+ subcc %o3, 64, %o3
+ add %o1, 64, %o1
+ bne 43b
+ add %o0, 64, %o0
+
+ andcc %o2, 0x30, %o3
+ be,a 1f
+ srl %g1, 24, %g2
+4:
+ SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
+ subcc %o3, 16, %o3
+ add %o1, 16, %o1
+ bne 4b
+ add %o0, 16, %o0
+
+ srl %g1, 24, %g2
+1:
+ stb %g2, [%o0 + 3]
+ b 88f
+ add %o0, 4, %o0
+42:
+ SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
+ SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
+ subcc %o3, 64, %o3
+ add %o1, 64, %o1
+ bne 42b
+ add %o0, 64, %o0
+
+ andcc %o2, 0x30, %o3
+ be,a 1f
+ srl %g1, 16, %g2
+4:
+ SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
+ subcc %o3, 16, %o3
+ add %o1, 16, %o1
+ bne 4b
+ add %o0, 16, %o0
+
+ srl %g1, 16, %g2
+1:
+ sth %g2, [%o0 - 2]
+
+ /* Fall through */
+
+#endif /* FASTER_NONALIGNED */
+
+88: /* short_end */
+
+ and %o2, 0xe, %o3
+20:
+ sethi %hi(89f), %o5
+ sll %o3, 3, %o4
+ add %o0, %o3, %o0
+ sub %o5, %o4, %o5
+ add %o1, %o3, %o1
+ jmpl %o5 + %lo(89f), %g0
+ andcc %o2, 1, %g0
MOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
MOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
@@ -337,28 +1120,31 @@ short_end:
MOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
-short_table_end:
- be 1f
+
+89: /* short_table_end */
+
+ be 1f
nop
- ldub [%o1], %g2
- stb %g2, [%o0]
+
+ ldub [%o1], %g2
+ stb %g2, [%o0]
1:
retl
- nop
+ RETL_INSN
-short_aligned_end:
- bne short_end
- andcc %o2, 8, %g0
+90: /* short_aligned_end */
+ bne 88b
+ andcc %o2, 8, %g0
- be 1f
- andcc %o2, 4, %g0
+ be 1f
+ andcc %o2, 4, %g0
- ld [%o1 + 0x00], %g2
- ld [%o1 + 0x04], %g3
- add %o1, 8, %o1
- st %g2, [%o0 + 0x00]
- st %g3, [%o0 + 0x04]
- add %o0, 8, %o0
+ ld [%o1 + 0x00], %g2
+ ld [%o1 + 0x04], %g3
+ add %o1, 8, %o1
+ st %g2, [%o0 + 0x00]
+ st %g3, [%o0 + 0x04]
+ add %o0, 8, %o0
1:
- b memcpy_last7
- mov %o2, %g1
+ b 81b
+ mov %o2, %g1