OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [sh/] [lib/] [memmove.S] - Rev 1765

Compare with Previous | Blame | View Log

/* $Id: memmove.S,v 1.1.1.1 2004-04-15 01:17:17 phoenix Exp $
 *
 * "memmove" implementation of SuperH
 *
 * Copyright (C) 1999  Niibe Yutaka
 *
 */

/*
 * void *memmove(void *dst, const void *src, size_t n);
 * The memory areas may overlap.
 */

#include <linux/linkage.h>
ENTRY(memmove)
        ! if dest > src, call memcpy (it copies in decreasing order)
        cmp/hi  r5,r4
        bf      1f
        mov.l   2f,r0
        jmp     @r0
         nop
        .balign 4
2:      .long   SYMBOL_NAME(memcpy)
1:
        sub     r5,r4           ! From here, r4 has the distance to r0
        tst     r6,r6
        bt/s    9f              ! if n=0, do nothing
         mov    r5,r0
        add     r6,r5
        mov     #12,r1
        cmp/gt  r6,r1
        bt/s    8f              ! if it's too small, copy a byte at once
         add    #-1,r4
        add     #1,r4
        !
        !                [ ...  ] DST             [ ...  ] SRC
        !                [ ...  ]                 [ ...  ]
        !                  :                        :
        !      r0+r4-->  [ ...  ]       r0    --> [ ...  ]
        !                  :                        :
        !                [ ...  ]                 [ ...  ]
        !                               r5    -->
        !
        mov     r4,r1
        mov     #3,r2
        and     r2,r1
        shll2   r1
        mov     r0,r3           ! Save the value on R0 to R3
        mova    jmptable,r0
        add     r1,r0
        mov.l   @r0,r1
        jmp     @r1
         mov    r3,r0           ! and back to R0
        .balign 4
jmptable:
        .long   case0
        .long   case1
        .long   case2
        .long   case3

        ! copy a byte at once
8:      mov.b   @r0+,r1
        cmp/hs  r5,r0
        bf/s    8b                      ! while (r0<r5)
         mov.b  r1,@(r0,r4)
        add     #1,r4
9:
        add     r4,r0
        rts
         sub    r6,r0

case_none:
        bra     8b
         add    #-1,r4

case0:
        !
        !       GHIJ KLMN OPQR -->  GHIJ KLMN OPQR
        !
        ! First, align to long word boundary
        mov     r0,r3
        and     r2,r3
        tst     r3,r3
        bt/s    2f
         add    #-1,r4
        mov     #4,r2
        sub     r3,r2
1:      dt      r2
        mov.b   @r0+,r1
        bf/s    1b
         mov.b  r1,@(r0,r4)
        !
2:      ! Second, copy a long word at once
        add     #-3,r4
        add     #-3,r5
3:      mov.l   @r0+,r1
        cmp/hs  r5,r0
        bf/s    3b
         mov.l  r1,@(r0,r4)
        add     #3,r5
        !
        ! Third, copy a byte at once, if necessary
        cmp/eq  r5,r0
        bt/s    9b
         add    #4,r4
        bra     8b
         add    #-1,r4

case3:
        !
        !       GHIJ KLMN OPQR -->  ...G HIJK LMNO PQR.
        !
        ! First, align to long word boundary
        mov     r0,r3
        and     r2,r3
        tst     r3,r3
        bt/s    2f
         add    #-1,r4
        mov     #4,r2
        sub     r3,r2
1:      dt      r2
        mov.b   @r0+,r1
        bf/s    1b
         mov.b  r1,@(r0,r4)
        !
2:      ! Second, read a long word and write a long word at once
        add     #-2,r4
        mov.l   @(r0,r4),r1
        add     #-7,r5
        add     #-4,r4
        !
#ifdef __LITTLE_ENDIAN__
        shll8   r1
3:      mov     r1,r3           ! JIHG
        shlr8   r3              ! xJIH
        mov.l   @r0+,r1         ! NMLK
        mov     r1,r2
        shll16  r2
        shll8   r2              ! Kxxx
        or      r2,r3           ! KJIH
        cmp/hs  r5,r0
        bf/s    3b
         mov.l  r3,@(r0,r4)
#else
        shlr8   r1
3:      mov     r1,r3           ! GHIJ
        shll8   r3              ! HIJx
        mov.l   @r0+,r1         ! KLMN
        mov     r1,r2
        shlr16  r2
        shlr8   r2              ! xxxK
        or      r2,r3           ! HIJK
        cmp/hs  r5,r0
        bf/s    3b
         mov.l  r3,@(r0,r4)
#endif
        add     #7,r5
        !
        ! Third, copy a byte at once, if necessary
        cmp/eq  r5,r0
        bt/s    9b
         add    #7,r4
        add     #-3,r0
        bra     8b
         add    #-1,r4

case2:
        !
        !       GHIJ KLMN OPQR -->  ..GH IJKL MNOP QR..
        !
        ! First, align to word boundary
        tst     #1,r0
        bt/s    2f
         add    #-1,r4
        mov.b   @r0+,r1
        mov.b   r1,@(r0,r4)
        !
2:      ! Second, read a word and write a word at once
        add     #-1,r4
        add     #-1,r5
        !
3:      mov.w   @r0+,r1
        cmp/hs  r5,r0
        bf/s    3b
         mov.w  r1,@(r0,r4)
        add     #1,r5
        !
        ! Third, copy a byte at once, if necessary
        cmp/eq  r5,r0
        bt/s    9b
         add    #2,r4
        mov.b   @r0,r1
        mov.b   r1,@(r0,r4)
        bra     9b
         add    #1,r0

case1:
        !
        !       GHIJ KLMN OPQR -->  .GHI JKLM NOPQ R...
        !
        ! First, align to long word boundary
        mov     r0,r3
        and     r2,r3
        tst     r3,r3
        bt/s    2f
         add    #-1,r4
        mov     #4,r2
        sub     r3,r2
1:      dt      r2
        mov.b   @r0+,r1
        bf/s    1b
         mov.b  r1,@(r0,r4)
        !
2:      ! Second, read a long word and write a long word at once
        mov.l   @(r0,r4),r1
        add     #-7,r5
        add     #-4,r4
        !
#ifdef __LITTLE_ENDIAN__
        shll16  r1
        shll8   r1
3:      mov     r1,r3           ! JIHG
        shlr16  r3
        shlr8   r3              ! xxxJ
        mov.l   @r0+,r1         ! NMLK
        mov     r1,r2
        shll8   r2              ! MLKx
        or      r2,r3           ! MLKJ
        cmp/hs  r5,r0
        bf/s    3b
         mov.l  r3,@(r0,r4)
#else
        shlr16  r1
        shlr8   r1
3:      mov     r1,r3           ! GHIJ
        shll16  r3
        shll8   r3              ! Jxxx
        mov.l   @r0+,r1         ! KLMN
        mov     r1,r2
        shlr8   r2              ! xKLM
        or      r2,r3           ! JKLM
        cmp/hs  r5,r0
        bf/s    3b              ! while(r0<r5)
         mov.l  r3,@(r0,r4)
#endif
        add     #7,r5
        !
        ! Third, copy a byte at once, if necessary
        cmp/eq  r5,r0
        bt/s    9b
         add    #5,r4
        add     #-3,r0
        bra     8b
         add    #-1,r4

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.