Re: Bug in memcpy() for m68k

Corinna Vinschen <[email protected]> Mon, 30 Mar 2026 10:47:05 +0200
Newsgroups gmane.comp.lib.newlib
Message-ID <[email protected]>
Hi Yuichi,

unfortunately your patch doesn't apply cleanly due to whitespace issues.

Can you please create a patch with `git format-patch' and send it via
`git send-email' to this list?  Alternatively, append the patch created
with git format-patch as attachment to your mail.  This should avoid 
whitespace issue entirely.


Thanks,
Corinna


On Mar 28 10:35, Yuichi Nakamura via Newlib wrote:
> Hi all,
> 
> I found the following issues in the m68k version of memcpy(). In particular,
> issue #1 is critical because it causes incorrect behavior on the 68000.
> 
> 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.
> 
> The following patch fixes these issues.
> 
> Best regards,
> Yuichi Nakamura
> 
> 
> diff --git a/newlib/libc/machine/m68k/memcpy.S
> b/newlib/libc/machine/m68k/memcpy.S
> index 464da95ef..ecf1da611 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