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/export.h>
13#include <asm/regdef.h>
14
15.L_fixup_handle_unaligned:
16	li.w	a0, -EFAULT
17	jr	ra
18
19/*
20 * unsigned long unaligned_read(void *addr, void *value, unsigned long n, bool sign)
21 *
22 * a0: addr
23 * a1: value
24 * a2: n
25 * a3: sign
26 */
27SYM_FUNC_START(unaligned_read)
28	beqz	a2, 5f
29
30	li.w	t2, 0
31	addi.d	t0, a2, -1
32	slli.d	t1, t0, 3
33	add.d 	a0, a0, t0
34
35	beqz	a3, 2f
361:	ld.b	t3, a0, 0
37	b	3f
38
392:	ld.bu	t3, a0, 0
403:	sll.d	t3, t3, t1
41	or	t2, t2, t3
42	addi.d	t1, t1, -8
43	addi.d	a0, a0, -1
44	addi.d	a2, a2, -1
45	bgtz	a2, 2b
464:	st.d	t2, a1, 0
47
48	move	a0, a2
49	jr	ra
50
515:	li.w    a0, -EFAULT
52	jr	ra
53
54	_asm_extable 1b, .L_fixup_handle_unaligned
55	_asm_extable 2b, .L_fixup_handle_unaligned
56	_asm_extable 4b, .L_fixup_handle_unaligned
57SYM_FUNC_END(unaligned_read)
58
59/*
60 * unsigned long unaligned_write(void *addr, unsigned long value, unsigned long n)
61 *
62 * a0: addr
63 * a1: value
64 * a2: n
65 */
66SYM_FUNC_START(unaligned_write)
67	beqz	a2, 3f
68
69	li.w	t0, 0
701:	srl.d	t1, a1, t0
712:	st.b	t1, a0, 0
72	addi.d	t0, t0, 8
73	addi.d	a2, a2, -1
74	addi.d	a0, a0, 1
75	bgtz	a2, 1b
76
77	move	a0, a2
78	jr	ra
79
803:	li.w    a0, -EFAULT
81	jr	ra
82
83	_asm_extable 2b, .L_fixup_handle_unaligned
84SYM_FUNC_END(unaligned_write)
85