1 /* -----------------------------------------------------------------------
2 hpux32.S - Copyright (c) 2006 Free Software Foundation, Inc.
4 based on src/pa/linux.S
6 HP-UX PA Foreign Function Interface
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:
16 The above copyright notice and this permission notice shall be included
17 in all copies or substantial portions of the Software.
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 ----------------------------------------------------------------------- */
29 #include <fficonfig.h>
35 .IMPORT $$dyncall,MILLICODE
39 /* void ffi_call_pa32(void (*)(char *, extended_cif *),
47 .export ffi_call_pa32,ENTRY,PRIV_LEV=3
48 .import ffi_prep_args_pa32,CODE
57 .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4
65 /* Setup the stack for calling prep_args...
66 We want the stack to look like this:
68 [ Previous stack ] <- %r3
70 [ 64-bytes register save area ] <- %r4
72 [ Stack space for actual call, passed as ] <- %arg0
73 [ arg0 to ffi_prep_args_pa32 ]
75 [ Stack for calling prep_args ] <- %sp
83 addl %arg2, %r4, %arg0 ; arg stack
84 stw %arg3, -48(%r3) ; save flags we need it later
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
94 /* now %sp should point where %arg0 was pointing. */
96 /* Load the arguments that should be passed in registers
97 The fp args are loaded by the prep_args function. */
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
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
114 /* Store the result according to the return type. The most
115 likely types should come first. */
118 comib,<>,n FFI_TYPE_INT, %r21, L$checkint8
123 comib,<>,n FFI_TYPE_UINT8, %r21, L$checkint16
128 comib,<>,n FFI_TYPE_UINT16, %r21, L$checkdbl
133 comib,<>,n FFI_TYPE_DOUBLE, %r21, L$checkfloat
138 comib,<>,n FFI_TYPE_FLOAT, %r21, L$checkll
143 comib,<>,n FFI_TYPE_UINT64, %r21, 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)
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)
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)
179 comib,<>,n FFI_TYPE_SMALL_STRUCT5, %r21, L$checksmst6
180 /* 5 byte values are returned right justified:
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)
194 comib,<>,n FFI_TYPE_SMALL_STRUCT6, %r21, L$checksmst7
195 /* 6 byte values are returned right justified:
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)
211 comib,<>,n FFI_TYPE_SMALL_STRUCT7, %r21, L$checksmst8
212 /* 7 byte values are returned right justified:
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)
230 comib,<>,n FFI_TYPE_SMALL_STRUCT8, %r21, L$done
231 /* 8 byte values are returned right justified:
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)
250 /* all done, return */
251 copy %r4, %sp ; pop arg stack
253 ldwm -64(%sp), %r3 ; .. and pop stack
261 /* void ffi_closure_pa32(void);
262 Called with closure argument in %r19 */
266 .export ffi_closure_pa32,ENTRY,PRIV_LEV=3,RTNVAL=GR
267 .import ffi_closure_inner_pa32,CODE
272 .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
282 /* Put arguments onto the stack and call ffi_closure_inner. */
288 /* Retrieve closure pointer and real gp. */
291 bl ffi_closure_inner_pa32, %r2
306 .EXPORT _GLOBAL__F_ffi_call_pa32,DATA
307 _GLOBAL__F_ffi_call_pa32
309 .word L$ECIE1-L$SCIE1 ;# Length of Common Information Entry
311 .word 0x0 ;# CIE Identifier Tag
312 .byte 0x1 ;# CIE Version
313 .ascii "\0" ;# CIE Augmentation
314 .uleb128 0x1 ;# CIE Code Alignment Factor
315 .sleb128 4 ;# CIE Data Alignment Factor
316 .byte 0x2 ;# CIE RA Column
317 .byte 0xc ;# DW_CFA_def_cfa
323 .word L$EFDE1-L$ASFDE1 ;# FDE Length
325 .word L$ASFDE1-L$frame1 ;# FDE CIE offset
326 .word L$FB1 ;# FDE initial location
327 .word L$FE1-L$FB1 ;# FDE address range
329 .byte 0x4 ;# DW_CFA_advance_loc4
331 .byte 0x83 ;# DW_CFA_offset, column 0x3
333 .byte 0x11 ;# DW_CFA_offset_extended_sf; save r2 at [r30-20]
337 .byte 0x4 ;# DW_CFA_advance_loc4
338 .word L$CFI12-L$CFI11
339 .byte 0xd ;# DW_CFA_def_cfa_register = r3
342 .byte 0x4 ;# DW_CFA_advance_loc4
343 .word L$CFI13-L$CFI12
344 .byte 0x84 ;# DW_CFA_offset, column 0x4
351 .word L$EFDE2-L$ASFDE2 ;# FDE Length
353 .word L$ASFDE2-L$frame1 ;# FDE CIE offset
354 .word L$FB2 ;# FDE initial location
355 .word L$FE2-L$FB2 ;# FDE address range
356 .byte 0x4 ;# DW_CFA_advance_loc4
358 .byte 0x83 ;# DW_CFA_offset, column 0x3
360 .byte 0x11 ;# DW_CFA_offset_extended_sf
364 .byte 0x4 ;# DW_CFA_advance_loc4
365 .word L$CFI22-L$CFI21
366 .byte 0xd ;# DW_CFA_def_cfa_register = r3