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 */
26SYM_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
351: ld.b t3, a0, 0
36 b 3f
37
382: ld.bu t3, a0, 0
393: 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
454: st.d t2, a1, 0
46
47 move a0, a2
48 jr ra
49
505: 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
56SYM_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 */
65SYM_FUNC_START(unaligned_write)
66 beqz a2, 3f
67
68 li.w t0, 0
691: srl.d t1, a1, t0
702: 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
793: li.w a0, -EFAULT
80 jr ra
81
82 _asm_extable 2b, .L_fixup_handle_unaligned
83SYM_FUNC_END(unaligned_write)
84

source code of linux/arch/loongarch/lib/unaligned.S