1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Copyright (C) 2020-2022 Loongson Technology Corporation Limited |
4 | */ |
5 | |
6 | #include <linux/linkage.h> |
7 | |
8 | #include <asm/asm.h> |
9 | #include <asm/asmmacro.h> |
10 | #include <asm/asm-extable.h> |
11 | #include <asm/errno.h> |
12 | #include <asm/regdef.h> |
13 | |
14 | .L_fixup_handle_unaligned: |
15 | li.w a0, -EFAULT |
16 | jr ra |
17 | |
18 | /* |
19 | * unsigned long unaligned_read(void *addr, void *value, unsigned long n, bool sign) |
20 | * |
21 | * a0: addr |
22 | * a1: value |
23 | * a2: n |
24 | * a3: sign |
25 | */ |
26 | SYM_FUNC_START(unaligned_read) |
27 | beqz a2, 5f |
28 | |
29 | li.w t2, 0 |
30 | addi.d t0, a2, -1 |
31 | slli.d t1, t0, 3 |
32 | add.d a0, a0, t0 |
33 | |
34 | beqz a3, 2f |
35 | 1: ld.b t3, a0, 0 |
36 | b 3f |
37 | |
38 | 2: ld.bu t3, a0, 0 |
39 | 3: sll.d t3, t3, t1 |
40 | or t2, t2, t3 |
41 | addi.d t1, t1, -8 |
42 | addi.d a0, a0, -1 |
43 | addi.d a2, a2, -1 |
44 | bgtz a2, 2b |
45 | 4: st.d t2, a1, 0 |
46 | |
47 | move a0, a2 |
48 | jr ra |
49 | |
50 | 5: li.w a0, -EFAULT |
51 | jr ra |
52 | |
53 | _asm_extable 1b, .L_fixup_handle_unaligned |
54 | _asm_extable 2b, .L_fixup_handle_unaligned |
55 | _asm_extable 4b, .L_fixup_handle_unaligned |
56 | SYM_FUNC_END(unaligned_read) |
57 | |
58 | /* |
59 | * unsigned long unaligned_write(void *addr, unsigned long value, unsigned long n) |
60 | * |
61 | * a0: addr |
62 | * a1: value |
63 | * a2: n |
64 | */ |
65 | SYM_FUNC_START(unaligned_write) |
66 | beqz a2, 3f |
67 | |
68 | li.w t0, 0 |
69 | 1: srl.d t1, a1, t0 |
70 | 2: st.b t1, a0, 0 |
71 | addi.d t0, t0, 8 |
72 | addi.d a2, a2, -1 |
73 | addi.d a0, a0, 1 |
74 | bgtz a2, 1b |
75 | |
76 | move a0, a2 |
77 | jr ra |
78 | |
79 | 3: li.w a0, -EFAULT |
80 | jr ra |
81 | |
82 | _asm_extable 2b, .L_fixup_handle_unaligned |
83 | SYM_FUNC_END(unaligned_write) |
84 | |