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