Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kern
[linux-2.6-microblaze.git] / arch / riscv / lib / memmove.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2
3 #include <linux/linkage.h>
4 #include <asm/asm.h>
5
6 ENTRY(__memmove)
7 WEAK(memmove)
8         move    t0, a0
9         move    t1, a1
10
11         beq     a0, a1, exit_memcpy
12         beqz    a2, exit_memcpy
13         srli    t2, a2, 0x2
14
15         slt     t3, a0, a1
16         beqz    t3, do_reverse
17
18         andi    a2, a2, 0x3
19         li      t4, 1
20         beqz    t2, byte_copy
21
22 word_copy:
23         lw      t3, 0(a1)
24         addi    t2, t2, -1
25         addi    a1, a1, 4
26         sw      t3, 0(a0)
27         addi    a0, a0, 4
28         bnez    t2, word_copy
29         beqz    a2, exit_memcpy
30         j       byte_copy
31
32 do_reverse:
33         add     a0, a0, a2
34         add     a1, a1, a2
35         andi    a2, a2, 0x3
36         li      t4, -1
37         beqz    t2, reverse_byte_copy
38
39 reverse_word_copy:
40         addi    a1, a1, -4
41         addi    t2, t2, -1
42         lw      t3, 0(a1)
43         addi    a0, a0, -4
44         sw      t3, 0(a0)
45         bnez    t2, reverse_word_copy
46         beqz    a2, exit_memcpy
47
48 reverse_byte_copy:
49         addi    a0, a0, -1
50         addi    a1, a1, -1
51
52 byte_copy:
53         lb      t3, 0(a1)
54         addi    a2, a2, -1
55         sb      t3, 0(a0)
56         add     a1, a1, t4
57         add     a0, a0, t4
58         bnez    a2, byte_copy
59
60 exit_memcpy:
61         move a0, t0
62         move a1, t1
63         ret
64 END(__memmove)