• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* -----------------------------------------------------------------------
2   linux.S - (c) 2003-2004 Randolph Chung <tausq@debian.org>
3	     (c) 2008 Red Hat, Inc.
4
5   HPPA Foreign Function Interface
6
7   Permission is hereby granted, free of charge, to any person obtaining
8   a copy of this software and associated documentation files (the
9   ``Software''), to deal in the Software without restriction, including
10   without limitation the rights to use, copy, modify, merge, publish,
11   distribute, sublicense, and/or sell copies of the Software, and to
12   permit persons to whom the Software is furnished to do so, subject to
13   the following conditions:
14
15   The above copyright notice and this permission notice shall be included
16   in all copies or substantial portions of the Software.
17
18   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
19   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21   IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
22   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24   OTHER DEALINGS IN THE SOFTWARE.
25   ----------------------------------------------------------------------- */
26
27#define LIBFFI_ASM
28#include <fficonfig.h>
29#include <ffi.h>
30
31	.text
32	.level 1.1
33	.align 4
34
35	/* void ffi_call_pa32(void (*)(char *, extended_cif *),
36			       extended_cif *ecif,
37			       unsigned bytes,
38			       unsigned flags,
39			       unsigned *rvalue,
40			       void (*fn)(void));
41	 */
42
43	.export ffi_call_pa32,code
44	.import ffi_prep_args_pa32,code
45
46	.type ffi_call_pa32, @function
47.LFB1:
48ffi_call_pa32:
49	.proc
50	.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4
51	.entry
52	stw %rp, -20(%sp)
53	copy %r3, %r1
54.LCFI11:
55
56	copy %sp, %r3
57.LCFI12:
58
59	/* Setup the stack for calling prep_args...
60	   We want the stack to look like this:
61
62	   [ Previous stack                            ] <- %r3
63
64	   [ 64-bytes register save area               ] <- %r4
65
66	   [ Stack space for actual call, passed as    ] <- %arg0
67	   [     arg0 to ffi_prep_args_pa32           ]
68
69	   [ Stack for calling prep_args               ] <- %sp
70	 */
71
72	stwm %r1, 64(%sp)
73	stw %r4, 12(%r3)
74.LCFI13:
75	copy %sp, %r4
76
77	addl %arg2, %r4, %arg0      /* arg stack */
78	stw %arg3, -48(%r3)         /* save flags; we need it later */
79
80	/* Call prep_args:
81	   %arg0(stack) -- set up above
82	   %arg1(ecif) -- same as incoming param
83	   %arg2(bytes) -- same as incoming param */
84	bl ffi_prep_args_pa32,%r2
85	ldo 64(%arg0), %sp
86	ldo -64(%sp), %sp
87
88	/* now %sp should point where %arg0 was pointing.  */
89
90	/* Load the arguments that should be passed in registers
91	   The fp args were loaded by the prep_args function.  */
92	ldw -36(%sp), %arg0
93	ldw -40(%sp), %arg1
94	ldw -44(%sp), %arg2
95	ldw -48(%sp), %arg3
96
97	/* in case the function is going to return a structure
98	   we need to give it a place to put the result.  */
99	ldw -52(%r3), %ret0                     /* %ret0 <- rvalue */
100	ldw -56(%r3), %r22                      /* %r22 <- function to call */
101	bl $$dyncall, %r31                      /* Call the user function */
102	copy %r31, %rp
103
104	/* Prepare to store the result; we need to recover flags and rvalue.  */
105	ldw -48(%r3), %r21                      /* r21 <- flags */
106	ldw -52(%r3), %r20                      /* r20 <- rvalue */
107
108	/* Store the result according to the return type.  */
109
110.Lcheckint:
111	comib,<>,n FFI_TYPE_INT, %r21, .Lcheckint8
112	b	.Ldone
113	stw	%ret0, 0(%r20)
114
115.Lcheckint8:
116	comib,<>,n FFI_TYPE_UINT8, %r21, .Lcheckint16
117	b	.Ldone
118	stb	%ret0, 0(%r20)
119
120.Lcheckint16:
121	comib,<>,n FFI_TYPE_UINT16, %r21, .Lcheckdbl
122	b	.Ldone
123	sth	%ret0, 0(%r20)
124
125.Lcheckdbl:
126	comib,<>,n FFI_TYPE_DOUBLE, %r21, .Lcheckfloat
127	b	.Ldone
128	fstd	%fr4,0(%r20)
129
130.Lcheckfloat:
131	comib,<>,n FFI_TYPE_FLOAT, %r21, .Lcheckll
132	b	.Ldone
133	fstw	%fr4L,0(%r20)
134
135.Lcheckll:
136	comib,<>,n FFI_TYPE_UINT64, %r21, .Lchecksmst2
137	stw	%ret0, 0(%r20)
138	b	.Ldone
139	stw	%ret1, 4(%r20)
140
141.Lchecksmst2:
142	comib,<>,n FFI_TYPE_SMALL_STRUCT2, %r21, .Lchecksmst3
143	/* 2-byte structs are returned in ret0 as ????xxyy.  */
144	extru	%ret0, 23, 8, %r22
145	stbs,ma	%r22, 1(%r20)
146	b	.Ldone
147	stb	%ret0, 0(%r20)
148
149.Lchecksmst3:
150	comib,<>,n FFI_TYPE_SMALL_STRUCT3, %r21, .Lchecksmst4
151	/* 3-byte structs are returned in ret0 as ??xxyyzz.  */
152	extru	%ret0, 15, 8, %r22
153	stbs,ma	%r22, 1(%r20)
154	extru	%ret0, 23, 8, %r22
155	stbs,ma	%r22, 1(%r20)
156	b	.Ldone
157	stb	%ret0, 0(%r20)
158
159.Lchecksmst4:
160	comib,<>,n FFI_TYPE_SMALL_STRUCT4, %r21, .Lchecksmst5
161	/* 4-byte structs are returned in ret0 as wwxxyyzz.  */
162	extru	%ret0, 7, 8, %r22
163	stbs,ma	%r22, 1(%r20)
164	extru	%ret0, 15, 8, %r22
165	stbs,ma	%r22, 1(%r20)
166	extru	%ret0, 23, 8, %r22
167	stbs,ma	%r22, 1(%r20)
168	b	.Ldone
169	stb	%ret0, 0(%r20)
170
171.Lchecksmst5:
172	comib,<>,n FFI_TYPE_SMALL_STRUCT5, %r21, .Lchecksmst6
173	/* 5 byte values are returned right justified:
174	      ret0     ret1
175	   5: ??????aa bbccddee */
176	stbs,ma	%ret0, 1(%r20)
177	extru	%ret1, 7, 8, %r22
178	stbs,ma	%r22, 1(%r20)
179	extru	%ret1, 15, 8, %r22
180	stbs,ma	%r22, 1(%r20)
181	extru	%ret1, 23, 8, %r22
182	stbs,ma	%r22, 1(%r20)
183	b	.Ldone
184	stb	%ret1, 0(%r20)
185
186.Lchecksmst6:
187	comib,<>,n FFI_TYPE_SMALL_STRUCT6, %r21, .Lchecksmst7
188	/* 6 byte values are returned right justified:
189	      ret0     ret1
190	   6: ????aabb ccddeeff */
191	extru	%ret0, 23, 8, %r22
192	stbs,ma	%r22, 1(%r20)
193	stbs,ma	%ret0, 1(%r20)
194	extru	%ret1, 7, 8, %r22
195	stbs,ma	%r22, 1(%r20)
196	extru	%ret1, 15, 8, %r22
197	stbs,ma	%r22, 1(%r20)
198	extru	%ret1, 23, 8, %r22
199	stbs,ma	%r22, 1(%r20)
200	b	.Ldone
201	stb	%ret1, 0(%r20)
202
203.Lchecksmst7:
204	comib,<>,n FFI_TYPE_SMALL_STRUCT7, %r21, .Lchecksmst8
205	/* 7 byte values are returned right justified:
206	      ret0     ret1
207	   7: ??aabbcc ddeeffgg */
208	extru	%ret0, 15, 8, %r22
209	stbs,ma	%r22, 1(%r20)
210	extru	%ret0, 23, 8, %r22
211	stbs,ma	%r22, 1(%r20)
212	stbs,ma	%ret0, 1(%r20)
213	extru	%ret1, 7, 8, %r22
214	stbs,ma	%r22, 1(%r20)
215	extru	%ret1, 15, 8, %r22
216	stbs,ma	%r22, 1(%r20)
217	extru	%ret1, 23, 8, %r22
218	stbs,ma	%r22, 1(%r20)
219	b	.Ldone
220	stb	%ret1, 0(%r20)
221
222.Lchecksmst8:
223	comib,<>,n FFI_TYPE_SMALL_STRUCT8, %r21, .Ldone
224	/* 8 byte values are returned right justified:
225	      ret0     ret1
226	   8: aabbccdd eeffgghh */
227	extru	%ret0, 7, 8, %r22
228	stbs,ma	%r22, 1(%r20)
229	extru	%ret0, 15, 8, %r22
230	stbs,ma	%r22, 1(%r20)
231	extru	%ret0, 23, 8, %r22
232	stbs,ma	%r22, 1(%r20)
233	stbs,ma	%ret0, 1(%r20)
234	extru	%ret1, 7, 8, %r22
235	stbs,ma	%r22, 1(%r20)
236	extru	%ret1, 15, 8, %r22
237	stbs,ma	%r22, 1(%r20)
238	extru	%ret1, 23, 8, %r22
239	stbs,ma	%r22, 1(%r20)
240	stb	%ret1, 0(%r20)
241
242.Ldone:
243	/* all done, return */
244	copy %r4, %sp                           /* pop arg stack */
245	ldw 12(%r3), %r4
246	ldwm -64(%sp), %r3                      /* .. and pop stack */
247	ldw -20(%sp), %rp
248	bv %r0(%rp)
249	nop
250	.exit
251	.procend
252.LFE1:
253
254	/* void ffi_closure_pa32(void);
255	   Called with closure argument in %r21 */
256	.export ffi_closure_pa32,code
257	.import ffi_closure_inner_pa32,code
258
259	.type ffi_closure_pa32, @function
260.LFB2:
261ffi_closure_pa32:
262	.proc
263	.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
264	.entry
265
266	stw %rp, -20(%sp)
267.LCFI20:
268	copy %r3, %r1
269.LCFI21:
270	copy %sp, %r3
271.LCFI22:
272	stwm %r1, 64(%sp)
273
274	/* Put arguments onto the stack and call ffi_closure_inner.  */
275	stw %arg0, -36(%r3)
276	stw %arg1, -40(%r3)
277	stw %arg2, -44(%r3)
278	stw %arg3, -48(%r3)
279
280	copy %r21, %arg0
281	bl ffi_closure_inner_pa32, %r2
282	copy %r3, %arg1
283
284	ldwm -64(%sp), %r3
285	ldw -20(%sp), %rp
286	ldw -36(%sp), %ret0
287	bv %r0(%r2)
288	ldw -40(%sp), %ret1
289
290	.exit
291	.procend
292.LFE2:
293
294	.section        ".eh_frame",EH_FRAME_FLAGS,@progbits
295.Lframe1:
296	.word   .LECIE1-.LSCIE1 ;# Length of Common Information Entry
297.LSCIE1:
298	.word   0x0     ;# CIE Identifier Tag
299	.byte   0x1     ;# CIE Version
300#ifdef __PIC__
301	.ascii  "zR\0"  ;# CIE Augmentation: 'z' - data, 'R' - DW_EH_PE_... data
302#else
303	.ascii "\0"     ;# CIE Augmentation
304#endif
305	.uleb128 0x1    ;# CIE Code Alignment Factor
306	.sleb128 4      ;# CIE Data Alignment Factor
307	.byte   0x2     ;# CIE RA Column
308#ifdef __PIC__
309	.uleb128 0x1    ;# Augmentation size
310	.byte	0x1b    ;# FDE Encoding (DW_EH_PE_pcrel|DW_EH_PE_sdata4)
311#endif
312	.byte   0xc     ;# DW_CFA_def_cfa
313	.uleb128 0x1e
314	.uleb128 0x0
315	.align 4
316.LECIE1:
317.LSFDE1:
318	.word   .LEFDE1-.LASFDE1        ;# FDE Length
319.LASFDE1:
320	.word   .LASFDE1-.Lframe1       ;# FDE CIE offset
321#ifdef __PIC__
322	.word	.LFB1-. ;# FDE initial location
323#else
324	.word	.LFB1   ;# FDE initial location
325#endif
326	.word   .LFE1-.LFB1     ;# FDE address range
327#ifdef __PIC__
328	.uleb128 0x0	;# Augmentation size: no data
329#endif
330	.byte   0x4     ;# DW_CFA_advance_loc4
331	.word   .LCFI11-.LFB1
332	.byte	0x83	;# DW_CFA_offset, column 0x3
333	.uleb128 0x0
334	.byte   0x11    ;# DW_CFA_offset_extended_sf; save r2 at [r30-20]
335	.uleb128 0x2
336	.sleb128 -5
337
338	.byte   0x4     ;# DW_CFA_advance_loc4
339	.word   .LCFI12-.LCFI11
340	.byte   0xd     ;# DW_CFA_def_cfa_register = r3
341	.uleb128 0x3
342
343	.byte   0x4     ;# DW_CFA_advance_loc4
344	.word   .LCFI13-.LCFI12
345	.byte	0x84	;# DW_CFA_offset, column 0x4
346	.uleb128 0x3
347
348	.align 4
349.LEFDE1:
350
351.LSFDE2:
352	.word   .LEFDE2-.LASFDE2        ;# FDE Length
353.LASFDE2:
354	.word   .LASFDE2-.Lframe1       ;# FDE CIE offset
355#ifdef __PIC__
356	.word   .LFB2-. ;# FDE initial location
357#else
358	.word   .LFB2   ;# FDE initial location
359#endif
360	.word   .LFE2-.LFB2     ;# FDE address range
361#ifdef __PIC__
362	.uleb128 0x0	;# Augmentation size: no data
363#endif
364	.byte   0x4     ;# DW_CFA_advance_loc4
365	.word   .LCFI21-.LFB2
366	.byte   0x83    ;# DW_CFA_offset, column 0x3
367	.uleb128 0x0
368	.byte   0x11    ;# DW_CFA_offset_extended_sf
369	.uleb128 0x2
370	.sleb128 -5
371
372	.byte   0x4     ;# DW_CFA_advance_loc4
373	.word   .LCFI22-.LCFI21
374	.byte   0xd     ;# DW_CFA_def_cfa_register = r3
375	.uleb128 0x3
376
377	.align 4
378.LEFDE2:
379