root/arch/sh/lib/memmove.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 /* $Id: memmove.S,v 1.2 2001/07/27 11:51:09 gniibe Exp $
   3  *
   4  * "memmove" implementation of SuperH
   5  *
   6  * Copyright (C) 1999  Niibe Yutaka
   7  *
   8  */
   9 
  10 /*
  11  * void *memmove(void *dst, const void *src, size_t n);
  12  * The memory areas may overlap.
  13  */
  14 
  15 #include <linux/linkage.h>
  16 ENTRY(memmove)
  17         ! if dest > src, call memcpy (it copies in decreasing order)
  18         cmp/hi  r5,r4
  19         bf      1f
  20         mov.l   2f,r0
  21         jmp     @r0
  22          nop
  23         .balign 4
  24 2:      .long   memcpy
  25 1:
  26         sub     r5,r4           ! From here, r4 has the distance to r0
  27         tst     r6,r6
  28         bt/s    9f              ! if n=0, do nothing
  29          mov    r5,r0
  30         add     r6,r5
  31         mov     #12,r1
  32         cmp/gt  r6,r1
  33         bt/s    8f              ! if it's too small, copy a byte at once
  34          add    #-1,r4
  35         add     #1,r4
  36         !
  37         !                [ ...  ] DST             [ ...  ] SRC
  38         !                [ ...  ]                 [ ...  ]
  39         !                  :                        :
  40         !      r0+r4-->  [ ...  ]       r0    --> [ ...  ]
  41         !                  :                        :
  42         !                [ ...  ]                 [ ...  ]
  43         !                               r5    -->
  44         !
  45         mov     r4,r1
  46         mov     #3,r2
  47         and     r2,r1
  48         shll2   r1
  49         mov     r0,r3           ! Save the value on R0 to R3
  50         mova    jmptable,r0
  51         add     r1,r0
  52         mov.l   @r0,r1
  53         jmp     @r1
  54          mov    r3,r0           ! and back to R0
  55         .balign 4
  56 jmptable:
  57         .long   case0
  58         .long   case1
  59         .long   case2
  60         .long   case3
  61 
  62         ! copy a byte at once
  63 8:      mov.b   @r0+,r1
  64         cmp/hs  r5,r0
  65         bf/s    8b                      ! while (r0<r5)
  66          mov.b  r1,@(r0,r4)
  67         add     #1,r4
  68 9:
  69         add     r4,r0
  70         rts
  71          sub    r6,r0
  72 
  73 case_none:
  74         bra     8b
  75          add    #-1,r4
  76 
  77 case0:
  78         !
  79         !       GHIJ KLMN OPQR -->  GHIJ KLMN OPQR
  80         !
  81         ! First, align to long word boundary
  82         mov     r0,r3
  83         and     r2,r3
  84         tst     r3,r3
  85         bt/s    2f
  86          add    #-1,r4
  87         mov     #4,r2
  88         sub     r3,r2
  89 1:      dt      r2
  90         mov.b   @r0+,r1
  91         bf/s    1b
  92          mov.b  r1,@(r0,r4)
  93         !
  94 2:      ! Second, copy a long word at once
  95         add     #-3,r4
  96         add     #-3,r5
  97 3:      mov.l   @r0+,r1
  98         cmp/hs  r5,r0
  99         bf/s    3b
 100          mov.l  r1,@(r0,r4)
 101         add     #3,r5
 102         !
 103         ! Third, copy a byte at once, if necessary
 104         cmp/eq  r5,r0
 105         bt/s    9b
 106          add    #4,r4
 107         bra     8b
 108          add    #-1,r4
 109 
 110 case3:
 111         !
 112         !       GHIJ KLMN OPQR -->  ...G HIJK LMNO PQR.
 113         !
 114         ! First, align to long word boundary
 115         mov     r0,r3
 116         and     r2,r3
 117         tst     r3,r3
 118         bt/s    2f
 119          add    #-1,r4
 120         mov     #4,r2
 121         sub     r3,r2
 122 1:      dt      r2
 123         mov.b   @r0+,r1
 124         bf/s    1b
 125          mov.b  r1,@(r0,r4)
 126         !
 127 2:      ! Second, read a long word and write a long word at once
 128         add     #-2,r4
 129         mov.l   @(r0,r4),r1
 130         add     #-7,r5
 131         add     #-4,r4
 132         !
 133 #ifdef __LITTLE_ENDIAN__
 134         shll8   r1
 135 3:      mov     r1,r3           ! JIHG
 136         shlr8   r3              ! xJIH
 137         mov.l   @r0+,r1         ! NMLK
 138         mov     r1,r2
 139         shll16  r2
 140         shll8   r2              ! Kxxx
 141         or      r2,r3           ! KJIH
 142         cmp/hs  r5,r0
 143         bf/s    3b
 144          mov.l  r3,@(r0,r4)
 145 #else
 146         shlr8   r1
 147 3:      mov     r1,r3           ! GHIJ
 148         shll8   r3              ! HIJx
 149         mov.l   @r0+,r1         ! KLMN
 150         mov     r1,r2
 151         shlr16  r2
 152         shlr8   r2              ! xxxK
 153         or      r2,r3           ! HIJK
 154         cmp/hs  r5,r0
 155         bf/s    3b
 156          mov.l  r3,@(r0,r4)
 157 #endif
 158         add     #7,r5
 159         !
 160         ! Third, copy a byte at once, if necessary
 161         cmp/eq  r5,r0
 162         bt/s    9b
 163          add    #7,r4
 164         add     #-3,r0
 165         bra     8b
 166          add    #-1,r4
 167 
 168 case2:
 169         !
 170         !       GHIJ KLMN OPQR -->  ..GH IJKL MNOP QR..
 171         !
 172         ! First, align to word boundary
 173         tst     #1,r0
 174         bt/s    2f
 175          add    #-1,r4
 176         mov.b   @r0+,r1
 177         mov.b   r1,@(r0,r4)
 178         !
 179 2:      ! Second, read a word and write a word at once
 180         add     #-1,r4
 181         add     #-1,r5
 182         !
 183 3:      mov.w   @r0+,r1
 184         cmp/hs  r5,r0
 185         bf/s    3b
 186          mov.w  r1,@(r0,r4)
 187         add     #1,r5
 188         !
 189         ! Third, copy a byte at once, if necessary
 190         cmp/eq  r5,r0
 191         bt/s    9b
 192          add    #2,r4
 193         mov.b   @r0,r1
 194         mov.b   r1,@(r0,r4)
 195         bra     9b
 196          add    #1,r0
 197 
 198 case1:
 199         !
 200         !       GHIJ KLMN OPQR -->  .GHI JKLM NOPQ R...
 201         !
 202         ! First, align to long word boundary
 203         mov     r0,r3
 204         and     r2,r3
 205         tst     r3,r3
 206         bt/s    2f
 207          add    #-1,r4
 208         mov     #4,r2
 209         sub     r3,r2
 210 1:      dt      r2
 211         mov.b   @r0+,r1
 212         bf/s    1b
 213          mov.b  r1,@(r0,r4)
 214         !
 215 2:      ! Second, read a long word and write a long word at once
 216         mov.l   @(r0,r4),r1
 217         add     #-7,r5
 218         add     #-4,r4
 219         !
 220 #ifdef __LITTLE_ENDIAN__
 221         shll16  r1
 222         shll8   r1
 223 3:      mov     r1,r3           ! JIHG
 224         shlr16  r3
 225         shlr8   r3              ! xxxJ
 226         mov.l   @r0+,r1         ! NMLK
 227         mov     r1,r2
 228         shll8   r2              ! MLKx
 229         or      r2,r3           ! MLKJ
 230         cmp/hs  r5,r0
 231         bf/s    3b
 232          mov.l  r3,@(r0,r4)
 233 #else
 234         shlr16  r1
 235         shlr8   r1
 236 3:      mov     r1,r3           ! GHIJ
 237         shll16  r3
 238         shll8   r3              ! Jxxx
 239         mov.l   @r0+,r1         ! KLMN
 240         mov     r1,r2
 241         shlr8   r2              ! xKLM
 242         or      r2,r3           ! JKLM
 243         cmp/hs  r5,r0
 244         bf/s    3b              ! while(r0<r5)
 245          mov.l  r3,@(r0,r4)
 246 #endif
 247         add     #7,r5
 248         !
 249         ! Third, copy a byte at once, if necessary
 250         cmp/eq  r5,r0
 251         bt/s    9b
 252          add    #5,r4
 253         add     #-3,r0
 254         bra     8b
 255          add    #-1,r4

/* [<][>][^][v][top][bottom][index][help] */