[newlib-cygwin/main] Fix memcpy alignment problems for m68k architecture

Corinna Vinschen corinna@sourceware.org
Mon Mar 30 14:39:04 GMT 2026


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=588c19ecdbcca1e70030688c1b08c342ada01b84

commit 588c19ecdbcca1e70030688c1b08c342ada01b84
Author:     Yuichi Nakamura <y.512.nakamura@gmail.com>
AuthorDate: Mon Mar 30 22:55:33 2026 +0900
Commit:     Corinna Vinschen <corinna@vinschen.de>
CommitDate: Mon Mar 30 16:29:48 2026 +0200

    Fix memcpy alignment problems for m68k architecture
    
    1. On CPUs that do not support misaligned access (MISALIGNED_OK=0), such
       as the 68000, memcpy() does not correctly copy regions larger than 64
       KB when the destination is not long-word aligned.
    2. The 68020 supports misaligned access, but this is not currently
       implemented.
    3. The 68000 can access long-word data at even addresses, but alignment
       is checked as if the address must be a multiple of 4.
    4. Because the loop count is checked using signed comparison, memcpy()
       fails for data sizes larger than 2 GB.
    
    This patch fixes these issues.

Diff:
---
 newlib/libc/machine/m68k/memcpy.S | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/newlib/libc/machine/m68k/memcpy.S b/newlib/libc/machine/m68k/memcpy.S
index 464da95efc16..ecf1da611565 100644
--- a/newlib/libc/machine/m68k/memcpy.S
+++ b/newlib/libc/machine/m68k/memcpy.S
@@ -15,7 +15,7 @@
 
 #include "m68kasm.h"
 
-#if defined (__mcoldfire__) || defined (__mc68030__) || defined (__mc68040__) || defined (__mc68060__)
+#if defined (__mcoldfire__) || defined (__mc68020__) || defined (__mc68030__) || defined (__mc68040__) || defined (__mc68060__)
 # define MISALIGNED_OK 1
 #else
 # define MISALIGNED_OK 0
@@ -49,10 +49,10 @@ SYM(memcpy):
 #if !MISALIGNED_OK
 	/* Goto .Lresidue if either dest or src is not 4-byte aligned */
 	move.l	a0,d0
-	and.l	#3,d0
+	and.l	#1,d0
 	bne	.Lresidue
 	move.l	a1,d0
-	and.l	#3,d0
+	and.l	#1,d0
 	bne	.Lresidue
 #else /* MISALIGNED_OK */
 	/* align dest */
@@ -95,7 +95,7 @@ SYM(memcpy):
 #else
 	subq.l	#1,d0
 #endif
-	bpl	1b
+	bcc	1b
 	bra	.Lresidue
 
 1:
@@ -104,9 +104,13 @@ SYM(memcpy):
 .Lresidue:
 #if !defined (__mcoldfire__)
 	dbra	d1,1b		| loop until done
+#if !MISALIGNED_OK
+	sub.l	#0x10000,d1
+	bcc	1b
+#endif /* !MISALIGNED_OK */
 #else
 	subq.l	#1,d1
-	bpl	1b
+	bcc	1b
 #endif
 	move.l	4(sp),d0	| return value
 	rts


More information about the Newlib-cvs mailing list