linux/arch/sh/lib/memcpy.S
<<
>>
Prefs
   1/* $Id: memcpy.S,v 1.3 2001/07/27 11:50:52 gniibe Exp $
   2 *
   3 * "memcpy" implementation of SuperH
   4 *
   5 * Copyright (C) 1999  Niibe Yutaka
   6 *
   7 */
   8
   9/*
  10 * void *memcpy(void *dst, const void *src, size_t n);
  11 * No overlap between the memory of DST and of SRC are assumed.
  12 */
  13
  14#include <linux/linkage.h>
  15ENTRY(memcpy)
  16        tst     r6,r6
  17        bt/s    9f              ! if n=0, do nothing
  18         mov    r4,r0
  19        sub     r4,r5           ! From here, r5 has the distance to r0
  20        add     r6,r0           ! From here, r0 points the end of copying point
  21        mov     #12,r1
  22        cmp/gt  r6,r1
  23        bt/s    7f              ! if it's too small, copy a byte at once
  24         add    #-1,r5
  25        add     #1,r5
  26        !                       From here, r6 is free
  27        !
  28        !      r4   -->  [ ...  ] DST             [ ...  ] SRC
  29        !                [ ...  ]                 [ ...  ]
  30        !                  :                        :
  31        !      r0   -->  [ ...  ]       r0+r5 --> [ ...  ]
  32        !
  33        !
  34        mov     r5,r1
  35        mov     #3,r2
  36        and     r2,r1
  37        shll2   r1
  38        mov     r0,r3           ! Save the value on R0 to R3
  39        mova    jmptable,r0
  40        add     r1,r0
  41        mov.l   @r0,r1
  42        jmp     @r1
  43         mov    r3,r0           ! and back to R0
  44        .balign 4
  45jmptable:
  46        .long   case0
  47        .long   case1
  48        .long   case2
  49        .long   case3
  50
  51        ! copy a byte at once
  527:      mov     r4,r2
  53        add     #1,r2
  548:
  55        cmp/hi  r2,r0
  56        mov.b   @(r0,r5),r1
  57        bt/s    8b                      ! while (r0>r2)
  58         mov.b  r1,@-r0
  599:
  60        rts
  61         nop
  62
  63case0:
  64        !
  65        !       GHIJ KLMN OPQR -->  GHIJ KLMN OPQR
  66        !
  67        ! First, align to long word boundary
  68        mov     r0,r3
  69        and     r2,r3
  70        tst     r3,r3
  71        bt/s    2f
  72         add    #-4,r5
  73        add     #3,r5
  741:      dt      r3
  75        mov.b   @(r0,r5),r1
  76        bf/s    1b
  77         mov.b  r1,@-r0
  78        !
  79        add     #-3,r5
  802:      ! Second, copy a long word at once
  81        mov     r4,r2
  82        add     #7,r2
  833:      mov.l   @(r0,r5),r1
  84        cmp/hi  r2,r0
  85        bt/s    3b
  86         mov.l  r1,@-r0
  87        !
  88        ! Third, copy a byte at once, if necessary
  89        cmp/eq  r4,r0
  90        bt/s    9b
  91         add    #3,r5
  92        bra     8b
  93         add    #-6,r2
  94
  95case1:
  96        !
  97        !       GHIJ KLMN OPQR -->  ...G HIJK LMNO PQR.
  98        !
  99        ! First, align to long word boundary
 100        mov     r0,r3
 101        and     r2,r3
 102        tst     r3,r3
 103        bt/s    2f
 104         add    #-1,r5
 1051:      dt      r3
 106        mov.b   @(r0,r5),r1
 107        bf/s    1b
 108         mov.b  r1,@-r0
 109        !
 1102:      ! Second, read a long word and write a long word at once
 111        mov.l   @(r0,r5),r1
 112        add     #-4,r5
 113        mov     r4,r2
 114        add     #7,r2
 115        !
 116#ifdef __LITTLE_ENDIAN__
 1173:      mov     r1,r3           ! RQPO
 118        shll16  r3
 119        shll8   r3              ! Oxxx
 120        mov.l   @(r0,r5),r1     ! NMLK
 121        mov     r1,r6
 122        shlr8   r6              ! xNML
 123        or      r6,r3           ! ONML
 124        cmp/hi  r2,r0
 125        bt/s    3b
 126         mov.l  r3,@-r0
 127#else
 1283:      mov     r1,r3           ! OPQR
 129        shlr16  r3
 130        shlr8   r3              ! xxxO
 131        mov.l   @(r0,r5),r1     ! KLMN
 132        mov     r1,r6
 133        shll8   r6              ! LMNx
 134        or      r6,r3           ! LMNO
 135        cmp/hi  r2,r0
 136        bt/s    3b
 137         mov.l  r3,@-r0
 138#endif
 139        !
 140        ! Third, copy a byte at once, if necessary
 141        cmp/eq  r4,r0
 142        bt/s    9b
 143         add    #4,r5
 144        bra     8b
 145         add    #-6,r2
 146
 147case2:
 148        !
 149        !       GHIJ KLMN OPQR -->  ..GH IJKL MNOP QR..
 150        !
 151        ! First, align to word boundary
 152        tst     #1,r0
 153        bt/s    2f
 154         add    #-1,r5
 155        mov.b   @(r0,r5),r1
 156        mov.b   r1,@-r0
 157        !
 1582:      ! Second, read a word and write a word at once
 159        add     #-1,r5
 160        mov     r4,r2
 161        add     #3,r2
 162        !
 1633:      mov.w   @(r0,r5),r1
 164        cmp/hi  r2,r0
 165        bt/s    3b
 166         mov.w  r1,@-r0
 167        !
 168        ! Third, copy a byte at once, if necessary
 169        cmp/eq  r4,r0
 170        bt/s    9b
 171         add    #1,r5
 172        mov.b   @(r0,r5),r1
 173        rts
 174         mov.b  r1,@-r0
 175
 176case3:
 177        !
 178        !       GHIJ KLMN OPQR -->  .GHI JKLM NOPQ R...
 179        !
 180        ! First, align to long word boundary
 181        mov     r0,r3
 182        and     r2,r3
 183        tst     r3,r3
 184        bt/s    2f
 185         add    #-1,r5
 1861:      dt      r3
 187        mov.b   @(r0,r5),r1
 188        bf/s    1b
 189         mov.b  r1,@-r0
 190        !
 1912:      ! Second, read a long word and write a long word at once
 192        add     #-2,r5
 193        mov.l   @(r0,r5),r1
 194        add     #-4,r5
 195        mov     r4,r2
 196        add     #7,r2
 197        !
 198#ifdef __LITTLE_ENDIAN__
 1993:      mov     r1,r3           ! RQPO
 200        shll8   r3              ! QPOx
 201        mov.l   @(r0,r5),r1     ! NMLK
 202        mov     r1,r6
 203        shlr16  r6
 204        shlr8   r6              ! xxxN
 205        or      r6,r3           ! QPON
 206        cmp/hi  r2,r0
 207        bt/s    3b
 208         mov.l  r3,@-r0
 209#else
 2103:      mov     r1,r3           ! OPQR
 211        shlr8   r3              ! xOPQ
 212        mov.l   @(r0,r5),r1     ! KLMN
 213        mov     r1,r6
 214        shll16  r6
 215        shll8   r6              ! Nxxx
 216        or      r6,r3           ! NOPQ
 217        cmp/hi  r2,r0
 218        bt/s    3b
 219         mov.l  r3,@-r0
 220#endif
 221        !
 222        ! Third, copy a byte at once, if necessary
 223        cmp/eq  r4,r0
 224        bt/s    9b
 225         add    #6,r5
 226        bra     8b
 227         add    #-6,r2
 228