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