1/* una_asm.S: Kernel unaligned trap assembler helpers.
2 *
3 * Copyright (C) 1996,2005,2008 David S. Miller (davem@davemloft.net)
4 * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 */
6
7#include <linux/errno.h>
8
9	.text
10
11retl_efault:
12	retl
13	 mov	-EFAULT, %o0
14
15	/* int __do_int_store(unsigned long *dst_addr, int size,
16	 *                    unsigned long *src_val)
17	 *
18	 * %o0 = dest_addr
19	 * %o1 = size
20	 * %o2 = src_val
21	 *
22	 * Return '0' on success, -EFAULT on failure.
23	 */
24	.globl	__do_int_store
25__do_int_store:
26	ld	[%o2], %g1
27	cmp	%o1, 2
28	be	2f
29	 cmp	%o1, 4
30	be	1f
31	 srl	%g1, 24, %g2
32	srl	%g1, 16, %g7
334:	stb	%g2, [%o0]
34	srl	%g1, 8, %g2
355:	stb	%g7, [%o0 + 1]
36	ld	[%o2 + 4], %g7
376:	stb	%g2, [%o0 + 2]
38	srl	%g7, 24, %g2
397:	stb	%g1, [%o0 + 3]
40	srl	%g7, 16, %g1
418:	stb	%g2, [%o0 + 4]
42	srl	%g7, 8, %g2
439:	stb	%g1, [%o0 + 5]
4410:	stb	%g2, [%o0 + 6]
45	b	0f
4611:	 stb	%g7, [%o0 + 7]
471:	srl	%g1, 16, %g7
4812:	stb	%g2, [%o0]
49	srl	%g1, 8, %g2
5013:	stb	%g7, [%o0 + 1]
5114:	stb	%g2, [%o0 + 2]
52	b	0f
5315:	 stb	%g1, [%o0 + 3]
542:	srl	%g1, 8, %g2
5516:	stb	%g2, [%o0]
5617:	stb	%g1, [%o0 + 1]
570:	retl
58	 mov	0, %o0
59
60	.section __ex_table,#alloc
61	.word	4b, retl_efault
62	.word	5b, retl_efault
63	.word	6b, retl_efault
64	.word	7b, retl_efault
65	.word	8b, retl_efault
66	.word	9b, retl_efault
67	.word	10b, retl_efault
68	.word	11b, retl_efault
69	.word	12b, retl_efault
70	.word	13b, retl_efault
71	.word	14b, retl_efault
72	.word	15b, retl_efault
73	.word	16b, retl_efault
74	.word	17b, retl_efault
75	.previous
76
77	/* int do_int_load(unsigned long *dest_reg, int size,
78	 *                 unsigned long *saddr, int is_signed)
79	 *
80	 * %o0 = dest_reg
81	 * %o1 = size
82	 * %o2 = saddr
83	 * %o3 = is_signed
84	 *
85	 * Return '0' on success, -EFAULT on failure.
86	 */
87	.globl	do_int_load
88do_int_load:
89	cmp	%o1, 8
90	be	9f
91	 cmp	%o1, 4
92	be	6f
934:	 ldub	[%o2], %g1
945:	ldub	[%o2 + 1], %g2
95	sll	%g1, 8, %g1
96	tst	%o3
97	be	3f
98	 or	%g1, %g2, %g1
99	sll	%g1, 16, %g1
100	sra	%g1, 16, %g1
1013:	b	0f
102	 st	%g1, [%o0]
1036:	ldub	[%o2 + 1], %g2
104	sll	%g1, 24, %g1
1057:	ldub	[%o2 + 2], %g7
106	sll	%g2, 16, %g2
1078:	ldub	[%o2 + 3], %g3
108	sll	%g7, 8, %g7
109	or	%g3, %g2, %g3
110	or	%g7, %g3, %g7
111	or	%g1, %g7, %g1
112	b	0f
113	 st	%g1, [%o0]
1149:	ldub	[%o2], %g1
11510:	ldub	[%o2 + 1], %g2
116	sll	%g1, 24, %g1
11711:	ldub	[%o2 + 2], %g7
118	sll	%g2, 16, %g2
11912:	ldub	[%o2 + 3], %g3
120	sll	%g7, 8, %g7
121	or	%g1, %g2, %g1
122	or	%g7, %g3, %g7
123	or	%g1, %g7, %g7
12413:	ldub	[%o2 + 4], %g1
125	st	%g7, [%o0]
12614:	ldub	[%o2 + 5], %g2
127	sll	%g1, 24, %g1
12815:	ldub	[%o2 + 6], %g7
129	sll	%g2, 16, %g2
13016:	ldub	[%o2 + 7], %g3
131	sll	%g7, 8, %g7
132	or	%g1, %g2, %g1
133	or	%g7, %g3, %g7
134	or	%g1, %g7, %g7
135	st	%g7, [%o0 + 4]
1360:	retl
137	 mov	0, %o0
138
139	.section __ex_table,#alloc
140	.word	4b, retl_efault
141	.word	5b, retl_efault
142	.word	6b, retl_efault
143	.word	7b, retl_efault
144	.word	8b, retl_efault
145	.word	9b, retl_efault
146	.word	10b, retl_efault
147	.word	11b, retl_efault
148	.word	12b, retl_efault
149	.word	13b, retl_efault
150	.word	14b, retl_efault
151	.word	15b, retl_efault
152	.word	16b, retl_efault
153	.previous
154