162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* $Id: memmove.S,v 1.2 2001/07/27 11:51:09 gniibe Exp $ 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * "memmove" implementation of SuperH 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 1999 Niibe Yutaka 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci/* 1162306a36Sopenharmony_ci * void *memmove(void *dst, const void *src, size_t n); 1262306a36Sopenharmony_ci * The memory areas may overlap. 1362306a36Sopenharmony_ci */ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/linkage.h> 1662306a36Sopenharmony_ciENTRY(memmove) 1762306a36Sopenharmony_ci ! if dest > src, call memcpy (it copies in decreasing order) 1862306a36Sopenharmony_ci cmp/hi r5,r4 1962306a36Sopenharmony_ci bf 1f 2062306a36Sopenharmony_ci mov.l 2f,r0 2162306a36Sopenharmony_ci jmp @r0 2262306a36Sopenharmony_ci nop 2362306a36Sopenharmony_ci .balign 4 2462306a36Sopenharmony_ci2: .long memcpy 2562306a36Sopenharmony_ci1: 2662306a36Sopenharmony_ci sub r5,r4 ! From here, r4 has the distance to r0 2762306a36Sopenharmony_ci tst r6,r6 2862306a36Sopenharmony_ci bt/s 9f ! if n=0, do nothing 2962306a36Sopenharmony_ci mov r5,r0 3062306a36Sopenharmony_ci add r6,r5 3162306a36Sopenharmony_ci mov #12,r1 3262306a36Sopenharmony_ci cmp/gt r6,r1 3362306a36Sopenharmony_ci bt/s 8f ! if it's too small, copy a byte at once 3462306a36Sopenharmony_ci add #-1,r4 3562306a36Sopenharmony_ci add #1,r4 3662306a36Sopenharmony_ci ! 3762306a36Sopenharmony_ci ! [ ... ] DST [ ... ] SRC 3862306a36Sopenharmony_ci ! [ ... ] [ ... ] 3962306a36Sopenharmony_ci ! : : 4062306a36Sopenharmony_ci ! r0+r4--> [ ... ] r0 --> [ ... ] 4162306a36Sopenharmony_ci ! : : 4262306a36Sopenharmony_ci ! [ ... ] [ ... ] 4362306a36Sopenharmony_ci ! r5 --> 4462306a36Sopenharmony_ci ! 4562306a36Sopenharmony_ci mov r4,r1 4662306a36Sopenharmony_ci mov #3,r2 4762306a36Sopenharmony_ci and r2,r1 4862306a36Sopenharmony_ci shll2 r1 4962306a36Sopenharmony_ci mov r0,r3 ! Save the value on R0 to R3 5062306a36Sopenharmony_ci mova jmptable,r0 5162306a36Sopenharmony_ci add r1,r0 5262306a36Sopenharmony_ci mov.l @r0,r1 5362306a36Sopenharmony_ci jmp @r1 5462306a36Sopenharmony_ci mov r3,r0 ! and back to R0 5562306a36Sopenharmony_ci .balign 4 5662306a36Sopenharmony_cijmptable: 5762306a36Sopenharmony_ci .long case0 5862306a36Sopenharmony_ci .long case1 5962306a36Sopenharmony_ci .long case2 6062306a36Sopenharmony_ci .long case3 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci ! copy a byte at once 6362306a36Sopenharmony_ci8: mov.b @r0+,r1 6462306a36Sopenharmony_ci cmp/hs r5,r0 6562306a36Sopenharmony_ci bf/s 8b ! while (r0<r5) 6662306a36Sopenharmony_ci mov.b r1,@(r0,r4) 6762306a36Sopenharmony_ci add #1,r4 6862306a36Sopenharmony_ci9: 6962306a36Sopenharmony_ci add r4,r0 7062306a36Sopenharmony_ci rts 7162306a36Sopenharmony_ci sub r6,r0 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_cicase_none: 7462306a36Sopenharmony_ci bra 8b 7562306a36Sopenharmony_ci add #-1,r4 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cicase0: 7862306a36Sopenharmony_ci ! 7962306a36Sopenharmony_ci ! GHIJ KLMN OPQR --> GHIJ KLMN OPQR 8062306a36Sopenharmony_ci ! 8162306a36Sopenharmony_ci ! First, align to long word boundary 8262306a36Sopenharmony_ci mov r0,r3 8362306a36Sopenharmony_ci and r2,r3 8462306a36Sopenharmony_ci tst r3,r3 8562306a36Sopenharmony_ci bt/s 2f 8662306a36Sopenharmony_ci add #-1,r4 8762306a36Sopenharmony_ci mov #4,r2 8862306a36Sopenharmony_ci sub r3,r2 8962306a36Sopenharmony_ci1: dt r2 9062306a36Sopenharmony_ci mov.b @r0+,r1 9162306a36Sopenharmony_ci bf/s 1b 9262306a36Sopenharmony_ci mov.b r1,@(r0,r4) 9362306a36Sopenharmony_ci ! 9462306a36Sopenharmony_ci2: ! Second, copy a long word at once 9562306a36Sopenharmony_ci add #-3,r4 9662306a36Sopenharmony_ci add #-3,r5 9762306a36Sopenharmony_ci3: mov.l @r0+,r1 9862306a36Sopenharmony_ci cmp/hs r5,r0 9962306a36Sopenharmony_ci bf/s 3b 10062306a36Sopenharmony_ci mov.l r1,@(r0,r4) 10162306a36Sopenharmony_ci add #3,r5 10262306a36Sopenharmony_ci ! 10362306a36Sopenharmony_ci ! Third, copy a byte at once, if necessary 10462306a36Sopenharmony_ci cmp/eq r5,r0 10562306a36Sopenharmony_ci bt/s 9b 10662306a36Sopenharmony_ci add #4,r4 10762306a36Sopenharmony_ci bra 8b 10862306a36Sopenharmony_ci add #-1,r4 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_cicase3: 11162306a36Sopenharmony_ci ! 11262306a36Sopenharmony_ci ! GHIJ KLMN OPQR --> ...G HIJK LMNO PQR. 11362306a36Sopenharmony_ci ! 11462306a36Sopenharmony_ci ! First, align to long word boundary 11562306a36Sopenharmony_ci mov r0,r3 11662306a36Sopenharmony_ci and r2,r3 11762306a36Sopenharmony_ci tst r3,r3 11862306a36Sopenharmony_ci bt/s 2f 11962306a36Sopenharmony_ci add #-1,r4 12062306a36Sopenharmony_ci mov #4,r2 12162306a36Sopenharmony_ci sub r3,r2 12262306a36Sopenharmony_ci1: dt r2 12362306a36Sopenharmony_ci mov.b @r0+,r1 12462306a36Sopenharmony_ci bf/s 1b 12562306a36Sopenharmony_ci mov.b r1,@(r0,r4) 12662306a36Sopenharmony_ci ! 12762306a36Sopenharmony_ci2: ! Second, read a long word and write a long word at once 12862306a36Sopenharmony_ci add #-2,r4 12962306a36Sopenharmony_ci mov.l @(r0,r4),r1 13062306a36Sopenharmony_ci add #-7,r5 13162306a36Sopenharmony_ci add #-4,r4 13262306a36Sopenharmony_ci ! 13362306a36Sopenharmony_ci#ifdef __LITTLE_ENDIAN__ 13462306a36Sopenharmony_ci shll8 r1 13562306a36Sopenharmony_ci3: mov r1,r3 ! JIHG 13662306a36Sopenharmony_ci shlr8 r3 ! xJIH 13762306a36Sopenharmony_ci mov.l @r0+,r1 ! NMLK 13862306a36Sopenharmony_ci mov r1,r2 13962306a36Sopenharmony_ci shll16 r2 14062306a36Sopenharmony_ci shll8 r2 ! Kxxx 14162306a36Sopenharmony_ci or r2,r3 ! KJIH 14262306a36Sopenharmony_ci cmp/hs r5,r0 14362306a36Sopenharmony_ci bf/s 3b 14462306a36Sopenharmony_ci mov.l r3,@(r0,r4) 14562306a36Sopenharmony_ci#else 14662306a36Sopenharmony_ci shlr8 r1 14762306a36Sopenharmony_ci3: mov r1,r3 ! GHIJ 14862306a36Sopenharmony_ci shll8 r3 ! HIJx 14962306a36Sopenharmony_ci mov.l @r0+,r1 ! KLMN 15062306a36Sopenharmony_ci mov r1,r2 15162306a36Sopenharmony_ci shlr16 r2 15262306a36Sopenharmony_ci shlr8 r2 ! xxxK 15362306a36Sopenharmony_ci or r2,r3 ! HIJK 15462306a36Sopenharmony_ci cmp/hs r5,r0 15562306a36Sopenharmony_ci bf/s 3b 15662306a36Sopenharmony_ci mov.l r3,@(r0,r4) 15762306a36Sopenharmony_ci#endif 15862306a36Sopenharmony_ci add #7,r5 15962306a36Sopenharmony_ci ! 16062306a36Sopenharmony_ci ! Third, copy a byte at once, if necessary 16162306a36Sopenharmony_ci cmp/eq r5,r0 16262306a36Sopenharmony_ci bt/s 9b 16362306a36Sopenharmony_ci add #7,r4 16462306a36Sopenharmony_ci add #-3,r0 16562306a36Sopenharmony_ci bra 8b 16662306a36Sopenharmony_ci add #-1,r4 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_cicase2: 16962306a36Sopenharmony_ci ! 17062306a36Sopenharmony_ci ! GHIJ KLMN OPQR --> ..GH IJKL MNOP QR.. 17162306a36Sopenharmony_ci ! 17262306a36Sopenharmony_ci ! First, align to word boundary 17362306a36Sopenharmony_ci tst #1,r0 17462306a36Sopenharmony_ci bt/s 2f 17562306a36Sopenharmony_ci add #-1,r4 17662306a36Sopenharmony_ci mov.b @r0+,r1 17762306a36Sopenharmony_ci mov.b r1,@(r0,r4) 17862306a36Sopenharmony_ci ! 17962306a36Sopenharmony_ci2: ! Second, read a word and write a word at once 18062306a36Sopenharmony_ci add #-1,r4 18162306a36Sopenharmony_ci add #-1,r5 18262306a36Sopenharmony_ci ! 18362306a36Sopenharmony_ci3: mov.w @r0+,r1 18462306a36Sopenharmony_ci cmp/hs r5,r0 18562306a36Sopenharmony_ci bf/s 3b 18662306a36Sopenharmony_ci mov.w r1,@(r0,r4) 18762306a36Sopenharmony_ci add #1,r5 18862306a36Sopenharmony_ci ! 18962306a36Sopenharmony_ci ! Third, copy a byte at once, if necessary 19062306a36Sopenharmony_ci cmp/eq r5,r0 19162306a36Sopenharmony_ci bt/s 9b 19262306a36Sopenharmony_ci add #2,r4 19362306a36Sopenharmony_ci mov.b @r0,r1 19462306a36Sopenharmony_ci mov.b r1,@(r0,r4) 19562306a36Sopenharmony_ci bra 9b 19662306a36Sopenharmony_ci add #1,r0 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_cicase1: 19962306a36Sopenharmony_ci ! 20062306a36Sopenharmony_ci ! GHIJ KLMN OPQR --> .GHI JKLM NOPQ R... 20162306a36Sopenharmony_ci ! 20262306a36Sopenharmony_ci ! First, align to long word boundary 20362306a36Sopenharmony_ci mov r0,r3 20462306a36Sopenharmony_ci and r2,r3 20562306a36Sopenharmony_ci tst r3,r3 20662306a36Sopenharmony_ci bt/s 2f 20762306a36Sopenharmony_ci add #-1,r4 20862306a36Sopenharmony_ci mov #4,r2 20962306a36Sopenharmony_ci sub r3,r2 21062306a36Sopenharmony_ci1: dt r2 21162306a36Sopenharmony_ci mov.b @r0+,r1 21262306a36Sopenharmony_ci bf/s 1b 21362306a36Sopenharmony_ci mov.b r1,@(r0,r4) 21462306a36Sopenharmony_ci ! 21562306a36Sopenharmony_ci2: ! Second, read a long word and write a long word at once 21662306a36Sopenharmony_ci mov.l @(r0,r4),r1 21762306a36Sopenharmony_ci add #-7,r5 21862306a36Sopenharmony_ci add #-4,r4 21962306a36Sopenharmony_ci ! 22062306a36Sopenharmony_ci#ifdef __LITTLE_ENDIAN__ 22162306a36Sopenharmony_ci shll16 r1 22262306a36Sopenharmony_ci shll8 r1 22362306a36Sopenharmony_ci3: mov r1,r3 ! JIHG 22462306a36Sopenharmony_ci shlr16 r3 22562306a36Sopenharmony_ci shlr8 r3 ! xxxJ 22662306a36Sopenharmony_ci mov.l @r0+,r1 ! NMLK 22762306a36Sopenharmony_ci mov r1,r2 22862306a36Sopenharmony_ci shll8 r2 ! MLKx 22962306a36Sopenharmony_ci or r2,r3 ! MLKJ 23062306a36Sopenharmony_ci cmp/hs r5,r0 23162306a36Sopenharmony_ci bf/s 3b 23262306a36Sopenharmony_ci mov.l r3,@(r0,r4) 23362306a36Sopenharmony_ci#else 23462306a36Sopenharmony_ci shlr16 r1 23562306a36Sopenharmony_ci shlr8 r1 23662306a36Sopenharmony_ci3: mov r1,r3 ! GHIJ 23762306a36Sopenharmony_ci shll16 r3 23862306a36Sopenharmony_ci shll8 r3 ! Jxxx 23962306a36Sopenharmony_ci mov.l @r0+,r1 ! KLMN 24062306a36Sopenharmony_ci mov r1,r2 24162306a36Sopenharmony_ci shlr8 r2 ! xKLM 24262306a36Sopenharmony_ci or r2,r3 ! JKLM 24362306a36Sopenharmony_ci cmp/hs r5,r0 24462306a36Sopenharmony_ci bf/s 3b ! while(r0<r5) 24562306a36Sopenharmony_ci mov.l r3,@(r0,r4) 24662306a36Sopenharmony_ci#endif 24762306a36Sopenharmony_ci add #7,r5 24862306a36Sopenharmony_ci ! 24962306a36Sopenharmony_ci ! Third, copy a byte at once, if necessary 25062306a36Sopenharmony_ci cmp/eq r5,r0 25162306a36Sopenharmony_ci bt/s 9b 25262306a36Sopenharmony_ci add #5,r4 25362306a36Sopenharmony_ci add #-3,r0 25462306a36Sopenharmony_ci bra 8b 25562306a36Sopenharmony_ci add #-1,r4 256