OSDN Git Service

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