GNU Linux-libre 5.19-rc6-gnu
[releases.git] / arch / loongarch / lib / copy_user.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4  */
5
6 #include <asm/asm.h>
7 #include <asm/asmmacro.h>
8 #include <asm/export.h>
9 #include <asm/regdef.h>
10
11 .macro fixup_ex from, to, offset, fix
12 .if \fix
13         .section .fixup, "ax"
14 \to:    addi.d  a0, a2, \offset
15         jr      ra
16         .previous
17 .endif
18         .section __ex_table, "a"
19         PTR     \from\()b, \to\()b
20         .previous
21 .endm
22
23 /*
24  * unsigned long __copy_user(void *to, const void *from, size_t n)
25  *
26  * a0: to
27  * a1: from
28  * a2: n
29  */
30 SYM_FUNC_START(__copy_user)
31         beqz    a2, 3f
32
33 1:      ld.b    t0, a1, 0
34 2:      st.b    t0, a0, 0
35         addi.d  a0, a0, 1
36         addi.d  a1, a1, 1
37         addi.d  a2, a2, -1
38         bgt     a2, zero, 1b
39
40 3:      move    a0, a2
41         jr      ra
42
43         fixup_ex 1, 4, 0, 1
44         fixup_ex 2, 4, 0, 0
45 SYM_FUNC_END(__copy_user)
46
47 EXPORT_SYMBOL(__copy_user)