xref: /linux/arch/loongarch/lib/unaligned.S (revision c31f4aa8fed048fa70e742c4bb49bb48dc489ab3)
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	LONG_ADDI	t0, a2, -1
31	PTR_SLLI	t1, t0, LONGLOG
32	PTR_ADD		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:	LONG_SLLV	t3, t3, t1
40	or		t2, t2, t3
41	LONG_ADDI	t1, t1, -8
42	PTR_ADDI	a0, a0, -1
43	PTR_ADDI	a2, a2, -1
44	bgtz		a2, 2b
454:	LONG_S		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:	LONG_SRLV	t1, a1, t0
702:	st.b		t1, a0, 0
71	LONG_ADDI	t0, t0, 8
72	PTR_ADDI	a2, a2, -1
73	PTR_ADDI	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