summaryrefslogtreecommitdiffstats
path: root/newlib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc')
-rw-r--r--newlib/libc/machine/arc/memcpy-archs.S59
1 files changed, 59 insertions, 0 deletions
diff --git a/newlib/libc/machine/arc/memcpy-archs.S b/newlib/libc/machine/arc/memcpy-archs.S
index 2673cee98..84e766ad8 100644
--- a/newlib/libc/machine/arc/memcpy-archs.S
+++ b/newlib/libc/machine/arc/memcpy-archs.S
@@ -69,6 +69,7 @@
# define ZOLAND 0xF
#endif
+#ifdef __ARC_ALIGNED_ACCESS__
ENTRY (memcpy)
prefetch [r1] ; Prefetch the read location
prefetchw [r0] ; Prefetch the write location
@@ -263,6 +264,64 @@ ENTRY (memcpy)
j [blink]
ENDFUNC (memcpy)
+
+#else
+
+ENTRY(memcpy)
+ prefetch [r1] ; Prefetch the read location
+ prefetchw [r0] ; Prefetch the write location
+ mov.f 0, r2
+;;; if size is zero
+ jz.d [blink]
+ mov r3, r0 ; don't clobber ret val
+
+;;; if size <= 8
+ cmp r2, 8
+ bls.d @.Lsmallchunk
+ mov.f lp_count, r2
+
+;;; Convert len to Dwords, unfold x4
+ lsr.f lp_count, r2, ZOLSHFT
+ lpnz @.Lcopyfast
+ ;; LOOP START
+ LOADX (r6, r1)
+ PREFETCH_READ (r1)
+ PREFETCH_WRITE (r3)
+ LOADX (r8, r1)
+ LOADX (r10, r1)
+ LOADX (r4, r1)
+ STOREX (r6, r3)
+ STOREX (r8, r3)
+ STOREX (r10, r3)
+ STOREX (r4, r3)
+.Lcopyfast:
+
+#ifdef __ARC_LL64__
+ and r2, r2, ZOLAND ;Remaining 31 bytes
+ lsr.f lp_count, r2, 3 ;Convert to 64-bit words.
+ lpnz @.Lcopy64b
+ ;; LOOP START
+ ldd.ab r6,[r1,8]
+ std.ab r6,[r3,8]
+.Lcopy64b:
+
+ and.f lp_count, r2, 0x07 ; Last 7 bytes
+#else
+ and.f lp_count, r2, ZOLAND
+#endif
+
+.Lsmallchunk:
+ lpnz @.Lcopyremainingbytes
+ ;; LOOP START
+ ldb.ab r5, [r1,1]
+ stb.ab r5, [r3,1]
+.Lcopyremainingbytes:
+
+ j [blink]
+
+ENDFUNC(memcpy)
+#endif
+
#endif /* __ARCHS__ */
#endif /* !__OPTIMIZE_SIZE__ && !PREFER_SIZE_OVER_SPEED */