xref: /openbmc/linux/arch/loongarch/lib/unaligned.S (revision 6db6b729)
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