1/* SPDX-License-Identifier: GPL-2.0 */
2/* una_asm.S: Kernel unaligned trap assembler helpers.
3 *
4 * Copyright (C) 1996,2005,2008 David S. Miller (davem@davemloft.net)
5 * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
6 */
7
8#include <linux/errno.h>
9
10	.text
11
12retl_efault:
13	retl
14	 mov	-EFAULT, %o0
15
16	/* int __do_int_store(unsigned long *dst_addr, int size,
17	 *                    unsigned long *src_val)
18	 *
19	 * %o0 = dest_addr
20	 * %o1 = size
21	 * %o2 = src_val
22	 *
23	 * Return '0' on success, -EFAULT on failure.
24	 */
25	.globl	__do_int_store
26__do_int_store:
27	ld	[%o2], %g1
28	cmp	%o1, 2
29	be	2f
30	 cmp	%o1, 4
31	be	1f
32	 srl	%g1, 24, %g2
33	srl	%g1, 16, %g7
344:	stb	%g2, [%o0]
35	srl	%g1, 8, %g2
365:	stb	%g7, [%o0 + 1]
37	ld	[%o2 + 4], %g7
386:	stb	%g2, [%o0 + 2]
39	srl	%g7, 24, %g2
407:	stb	%g1, [%o0 + 3]
41	srl	%g7, 16, %g1
428:	stb	%g2, [%o0 + 4]
43	srl	%g7, 8, %g2
449:	stb	%g1, [%o0 + 5]
4510:	stb	%g2, [%o0 + 6]
46	b	0f
4711:	 stb	%g7, [%o0 + 7]
481:	srl	%g1, 16, %g7
4912:	stb	%g2, [%o0]
50	srl	%g1, 8, %g2
5113:	stb	%g7, [%o0 + 1]
5214:	stb	%g2, [%o0 + 2]
53	b	0f
5415:	 stb	%g1, [%o0 + 3]
552:	srl	%g1, 8, %g2
5616:	stb	%g2, [%o0]
5717:	stb	%g1, [%o0 + 1]
580:	retl
59	 mov	0, %o0
60
61	.section __ex_table,#alloc
62	.word	4b, retl_efault
63	.word	5b, retl_efault
64	.word	6b, retl_efault
65	.word	7b, retl_efault
66	.word	8b, retl_efault
67	.word	9b, retl_efault
68	.word	10b, retl_efault
69	.word	11b, retl_efault
70	.word	12b, retl_efault
71	.word	13b, retl_efault
72	.word	14b, retl_efault
73	.word	15b, retl_efault
74	.word	16b, retl_efault
75	.word	17b, retl_efault
76	.previous
77
78	/* int do_int_load(unsigned long *dest_reg, int size,
79	 *                 unsigned long *saddr, int is_signed)
80	 *
81	 * %o0 = dest_reg
82	 * %o1 = size
83	 * %o2 = saddr
84	 * %o3 = is_signed
85	 *
86	 * Return '0' on success, -EFAULT on failure.
87	 */
88	.globl	do_int_load
89do_int_load:
90	cmp	%o1, 8
91	be	9f
92	 cmp	%o1, 4
93	be	6f
944:	 ldub	[%o2], %g1
955:	ldub	[%o2 + 1], %g2
96	sll	%g1, 8, %g1
97	tst	%o3
98	be	3f
99	 or	%g1, %g2, %g1
100	sll	%g1, 16, %g1
101	sra	%g1, 16, %g1
1023:	b	0f
103	 st	%g1, [%o0]
1046:	ldub	[%o2 + 1], %g2
105	sll	%g1, 24, %g1
1067:	ldub	[%o2 + 2], %g7
107	sll	%g2, 16, %g2
1088:	ldub	[%o2 + 3], %g3
109	sll	%g7, 8, %g7
110	or	%g3, %g2, %g3
111	or	%g7, %g3, %g7
112	or	%g1, %g7, %g1
113	b	0f
114	 st	%g1, [%o0]
1159:	ldub	[%o2], %g1
11610:	ldub	[%o2 + 1], %g2
117	sll	%g1, 24, %g1
11811:	ldub	[%o2 + 2], %g7
119	sll	%g2, 16, %g2
12012:	ldub	[%o2 + 3], %g3
121	sll	%g7, 8, %g7
122	or	%g1, %g2, %g1
123	or	%g7, %g3, %g7
124	or	%g1, %g7, %g7
12513:	ldub	[%o2 + 4], %g1
126	st	%g7, [%o0]
12714:	ldub	[%o2 + 5], %g2
128	sll	%g1, 24, %g1
12915:	ldub	[%o2 + 6], %g7
130	sll	%g2, 16, %g2
13116:	ldub	[%o2 + 7], %g3
132	sll	%g7, 8, %g7
133	or	%g1, %g2, %g1
134	or	%g7, %g3, %g7
135	or	%g1, %g7, %g7
136	st	%g7, [%o0 + 4]
1370:	retl
138	 mov	0, %o0
139
140	.section __ex_table,#alloc
141	.word	4b, retl_efault
142	.word	5b, retl_efault
143	.word	6b, retl_efault
144	.word	7b, retl_efault
145	.word	8b, retl_efault
146	.word	9b, retl_efault
147	.word	10b, retl_efault
148	.word	11b, retl_efault
149	.word	12b, retl_efault
150	.word	13b, retl_efault
151	.word	14b, retl_efault
152	.word	15b, retl_efault
153	.word	16b, retl_efault
154	.previous
155