OSDN Git Service

Code drop from //branches/cupcake/...@124589
[android-x86/external-libffi.git] / src / pa / linux.S
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:
48 ffi_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:
261 ffi_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         .ascii "\0"     ;# CIE Augmentation
301         .uleb128 0x1    ;# CIE Code Alignment Factor
302         .sleb128 4      ;# CIE Data Alignment Factor
303         .byte   0x2     ;# CIE RA Column
304         .byte   0xc     ;# DW_CFA_def_cfa
305         .uleb128 0x1e
306         .uleb128 0x0
307         .align 4
308 .LECIE1:
309 .LSFDE1:
310         .word   .LEFDE1-.LASFDE1        ;# FDE Length
311 .LASFDE1:
312         .word   .LASFDE1-.Lframe1       ;# FDE CIE offset
313         .word   .LFB1   ;# FDE initial location
314         .word   .LFE1-.LFB1     ;# FDE address range
315
316         .byte   0x4     ;# DW_CFA_advance_loc4
317         .word   .LCFI11-.LFB1
318         .byte   0x83    ;# DW_CFA_offset, column 0x3
319         .uleb128 0x0
320         .byte   0x11    ;# DW_CFA_offset_extended_sf; save r2 at [r30-20]
321         .uleb128 0x2
322         .sleb128 -5
323
324         .byte   0x4     ;# DW_CFA_advance_loc4
325         .word   .LCFI12-.LCFI11
326         .byte   0xd     ;# DW_CFA_def_cfa_register = r3
327         .uleb128 0x3
328
329         .byte   0x4     ;# DW_CFA_advance_loc4
330         .word   .LCFI13-.LCFI12
331         .byte   0x84    ;# DW_CFA_offset, column 0x4
332         .uleb128 0x3
333
334         .align 4
335 .LEFDE1:
336
337 .LSFDE2:
338         .word   .LEFDE2-.LASFDE2        ;# FDE Length
339 .LASFDE2:
340         .word   .LASFDE2-.Lframe1       ;# FDE CIE offset
341         .word   .LFB2   ;# FDE initial location
342         .word   .LFE2-.LFB2     ;# FDE address range
343         .byte   0x4     ;# DW_CFA_advance_loc4
344         .word   .LCFI21-.LFB2
345         .byte   0x83    ;# DW_CFA_offset, column 0x3
346         .uleb128 0x0
347         .byte   0x11    ;# DW_CFA_offset_extended_sf
348         .uleb128 0x2
349         .sleb128 -5
350
351         .byte   0x4     ;# DW_CFA_advance_loc4
352         .word   .LCFI22-.LCFI21
353         .byte   0xd     ;# DW_CFA_def_cfa_register = r3
354         .uleb128 0x3
355
356         .align 4
357 .LEFDE2: