1/* $Id: sys32.S,v 1.12 2000/03/24 04:17:37 davem Exp $
2 * sys32.S: I-cache tricks for 32-bit compatability layer simple
3 *          conversions.
4 *
5 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
6 * Copyright (C) 1998 Jakub Jelinek   (jj@ultra.linux.cz)
7 */
8
9#include <asm/errno.h>
10
11/* NOTE: call as jump breaks return stack, we have to avoid that */
12
13	.text
14
15	.align		32
16	.globl		sys32_mmap
17sys32_mmap:
18	srl		%o4, 0, %o4
19	sethi		%hi(sys_mmap), %g1
20	jmpl		%g1 + %lo(sys_mmap), %g0
21	 srl		%o5, 0, %o5
22
23	.align		32
24	.globl		sys32_lseek
25	.globl		sys32_chmod, sys32_mknod
26sys32_lseek:
27	sra		%o1, 0, %o1
28	sethi		%hi(sys_lseek), %g1
29	jmpl		%g1 + %lo(sys_lseek), %g0
30	 nop
31sys32_chmod:
32	sethi		%hi(0xffff), %g2
33	sethi		%hi(sys_chmod), %g1
34	orcc		%g2, %lo(0xffff), %g2
35	jmpl		%g1 + %lo(sys_chmod), %g0
36	 and		%o1, %g2, %o1
37sys32_mknod:
38	sethi		%hi(0xffff), %g2
39	sethi		%hi(sys_mknod), %g1
40	orcc		%g2, %lo(0xffff), %g2
41	jmpl		%g1 + %lo(sys_mknod), %g0
42	 and		%o2, %g2, %o2
43
44	.align		32
45	.globl		sys32_sendto, sys32_recvfrom
46sys32_sendto:
47	sethi		%hi(sys_sendto), %g1
48	jmpl		%g1 + %lo(sys_sendto), %g0
49	 srl		%o4, 0, %o4
50sys32_recvfrom:
51	srl		%o4, 0, %o4
52	sethi		%hi(sys_recvfrom), %g1
53	jmpl		%g1 + %lo(sys_recvfrom), %g0
54	 srl		%o5, 0, %o5
55
56	.globl		sys32_bdflush
57sys32_bdflush:
58	sethi		%hi(sys_bdflush), %g1
59	jmpl		%g1 + %lo(sys_bdflush), %g0
60	 sra		%o1, 0, %o1
61
62	.align		32
63	.globl		sys32_mmap2
64sys32_mmap2:
65	srl		%o4, 0, %o4
66	sethi		%hi(sys_mmap), %g1
67	srl		%o5, 0, %o5
68	jmpl		%g1 + %lo(sys_mmap), %g0
69	 sllx		%o5, 12, %o5
70
71	.align		32
72	.globl		sys32_socketcall
73sys32_socketcall:	/* %o0=call, %o1=args */
74	cmp		%o0, 1
75	bl,pn		%xcc, do_einval
76	 cmp		%o0, 17
77	bg,pn		%xcc, do_einval
78	 sub		%o0, 1, %o0
79	sllx		%o0, 5, %o0
80	sethi		%hi(__socketcall_table_begin), %g2
81	or		%g2, %lo(__socketcall_table_begin), %g2
82	jmpl		%g2 + %o0, %g0
83	 nop
84
85	/* Each entry is exactly 32 bytes. */
86	.align		32
87__socketcall_table_begin:
88do_sys_socket: /* sys_socket(int, int, int) */
89	ldswa		[%o1 + 0x0] %asi, %o0
90	sethi		%hi(sys_socket), %g1
91	ldswa		[%o1 + 0x8] %asi, %o2
92	jmpl		%g1 + %lo(sys_socket), %g0
93	 ldswa		[%o1 + 0x4] %asi, %o1
94	nop
95	nop
96	nop
97do_sys_bind: /* sys_bind(int fd, struct sockaddr *, int) */
98	ldswa		[%o1 + 0x0] %asi, %o0
99	sethi		%hi(sys_bind), %g1
100	ldswa		[%o1 + 0x8] %asi, %o2
101	jmpl		%g1 + %lo(sys_bind), %g0
102	 lduwa		[%o1 + 0x4] %asi, %o1
103	nop
104	nop
105	nop
106do_sys_connect: /* sys_connect(int, struct sockaddr *, int) */
107	ldswa		[%o1 + 0x0] %asi, %o0
108	sethi		%hi(sys_connect), %g1
109	ldswa		[%o1 + 0x8] %asi, %o2
110	jmpl		%g1 + %lo(sys_connect), %g0
111	 lduwa		[%o1 + 0x4] %asi, %o1
112	nop
113	nop
114	nop
115do_sys_listen: /* sys_listen(int, int) */
116	ldswa		[%o1 + 0x0] %asi, %o0
117	sethi		%hi(sys_listen), %g1
118	jmpl		%g1 + %lo(sys_listen), %g0
119	 ldswa		[%o1 + 0x4] %asi, %o1
120	nop
121	nop
122	nop
123	nop
124do_sys_accept: /* sys_accept(int, struct sockaddr *, int *) */
125	ldswa		[%o1 + 0x0] %asi, %o0
126	sethi		%hi(sys_accept), %g1
127	lduwa		[%o1 + 0x8] %asi, %o2
128	jmpl		%g1 + %lo(sys_accept), %g0
129	 lduwa		[%o1 + 0x4] %asi, %o1
130	nop
131	nop
132	nop
133do_sys_getsockname: /* sys_getsockname(int, struct sockaddr *, int *) */
134	ldswa		[%o1 + 0x0] %asi, %o0
135	sethi		%hi(sys_getsockname), %g1
136	lduwa		[%o1 + 0x8] %asi, %o2
137	jmpl		%g1 + %lo(sys_getsockname), %g0
138	 lduwa		[%o1 + 0x4] %asi, %o1
139	nop
140	nop
141	nop
142do_sys_getpeername: /* sys_getpeername(int, struct sockaddr *, int *) */
143	ldswa		[%o1 + 0x0] %asi, %o0
144	sethi		%hi(sys_getpeername), %g1
145	lduwa		[%o1 + 0x8] %asi, %o2
146	jmpl		%g1 + %lo(sys_getpeername), %g0
147	 lduwa		[%o1 + 0x4] %asi, %o1
148	nop
149	nop
150	nop
151do_sys_socketpair: /* sys_socketpair(int, int, int, int *) */
152	ldswa		[%o1 + 0x0] %asi, %o0
153	sethi		%hi(sys_socketpair), %g1
154	ldswa		[%o1 + 0x8] %asi, %o2
155	lduwa		[%o1 + 0xc] %asi, %o3
156	jmpl		%g1 + %lo(sys_socketpair), %g0
157	 ldswa		[%o1 + 0x4] %asi, %o1
158	nop
159	nop
160do_sys_send: /* sys_send(int, void *, size_t, unsigned int) */
161	ldswa		[%o1 + 0x0] %asi, %o0
162	sethi		%hi(sys_send), %g1
163	lduwa		[%o1 + 0x8] %asi, %o2
164	lduwa		[%o1 + 0xc] %asi, %o3
165	jmpl		%g1 + %lo(sys_send), %g0
166	 lduwa		[%o1 + 0x4] %asi, %o1
167	nop
168	nop
169do_sys_recv: /* sys_recv(int, void *, size_t, unsigned int) */
170	ldswa		[%o1 + 0x0] %asi, %o0
171	sethi		%hi(sys_recv), %g1
172	lduwa		[%o1 + 0x8] %asi, %o2
173	lduwa		[%o1 + 0xc] %asi, %o3
174	jmpl		%g1 + %lo(sys_recv), %g0
175	 lduwa		[%o1 + 0x4] %asi, %o1
176	nop
177	nop
178do_sys_sendto: /* sys32_sendto(int, u32, __kernel_size_t32, unsigned int, u32, int) */
179	ldswa		[%o1 + 0x0] %asi, %o0
180	sethi		%hi(sys32_sendto), %g1
181	lduwa		[%o1 + 0x8] %asi, %o2
182	lduwa		[%o1 + 0xc] %asi, %o3
183	lduwa		[%o1 + 0x10] %asi, %o4
184	ldswa		[%o1 + 0x14] %asi, %o5
185	jmpl		%g1 + %lo(sys32_sendto), %g0
186	 lduwa		[%o1 + 0x4] %asi, %o1
187do_sys_recvfrom: /* sys32_recvfrom(int, u32, __kernel_size_t32, unsigned int, u32, u32) */
188	ldswa		[%o1 + 0x0] %asi, %o0
189	sethi		%hi(sys32_recvfrom), %g1
190	lduwa		[%o1 + 0x8] %asi, %o2
191	lduwa		[%o1 + 0xc] %asi, %o3
192	lduwa		[%o1 + 0x10] %asi, %o4
193	lduwa		[%o1 + 0x14] %asi, %o5
194	jmpl		%g1 + %lo(sys32_recvfrom), %g0
195	 lduwa		[%o1 + 0x4] %asi, %o1
196do_sys_shutdown: /* sys_shutdown(int, int) */
197	ldswa		[%o1 + 0x0] %asi, %o0
198	sethi		%hi(sys_shutdown), %g1
199	jmpl		%g1 + %lo(sys_shutdown), %g0
200	 ldswa		[%o1 + 0x4] %asi, %o1
201	nop
202	nop
203	nop
204	nop
205do_sys_setsockopt: /* sys32_setsockopt(int, int, int, char *, int) */
206	ldswa		[%o1 + 0x0] %asi, %o0
207	sethi		%hi(sys32_setsockopt), %g1
208	ldswa		[%o1 + 0x8] %asi, %o2
209	lduwa		[%o1 + 0xc] %asi, %o3
210	ldswa		[%o1 + 0x10] %asi, %o4
211	jmpl		%g1 + %lo(sys32_setsockopt), %g0
212	 ldswa		[%o1 + 0x4] %asi, %o1
213	nop
214do_sys_getsockopt: /* sys32_getsockopt(int, int, int, u32, u32) */
215	ldswa		[%o1 + 0x0] %asi, %o0
216	sethi		%hi(sys32_getsockopt), %g1
217	ldswa		[%o1 + 0x8] %asi, %o2
218	lduwa		[%o1 + 0xc] %asi, %o3
219	lduwa		[%o1 + 0x10] %asi, %o4
220	jmpl		%g1 + %lo(sys32_getsockopt), %g0
221	 ldswa		[%o1 + 0x4] %asi, %o1
222	nop
223do_sys_sendmsg: /* sys32_sendmsg(int, struct msghdr32 *, unsigned int) */
224	ldswa		[%o1 + 0x0] %asi, %o0
225	sethi		%hi(sys32_sendmsg), %g1
226	lduwa		[%o1 + 0x8] %asi, %o2
227	jmpl		%g1 + %lo(sys32_sendmsg), %g0
228	 lduwa		[%o1 + 0x4] %asi, %o1
229	nop
230	nop
231	nop
232do_sys_recvmsg: /* sys32_recvmsg(int, struct msghdr32 *, unsigned int) */
233	ldswa		[%o1 + 0x0] %asi, %o0
234	sethi		%hi(sys32_recvmsg), %g1
235	lduwa		[%o1 + 0x8] %asi, %o2
236	jmpl		%g1 + %lo(sys32_recvmsg), %g0
237	 lduwa		[%o1 + 0x4] %asi, %o1
238	nop
239	nop
240	nop
241__socketcall_table_end:
242
243do_einval:
244	retl
245	 mov		-EINVAL, %o0
246do_efault:
247	retl
248	 mov		-EFAULT, %o0
249
250	.section	__ex_table
251	.align		4
252	.word		__socketcall_table_begin, 0, __socketcall_table_end, do_efault
253	.previous
254