1#if defined(__ppc__) 2 3/* ----------------------------------------------------------------------- 4 ppc-darwin_closure.S - Copyright (c) 2002, 2003, 2004, Free Software Foundation, 5 Inc. based on ppc_closure.S 6 7 PowerPC Assembly glue. 8 9 Permission is hereby granted, free of charge, to any person obtaining 10 a copy of this software and associated documentation files (the 11 ``Software''), to deal in the Software without restriction, including 12 without limitation the rights to use, copy, modify, merge, publish, 13 distribute, sublicense, and/or sell copies of the Software, and to 14 permit persons to whom the Software is furnished to do so, subject to 15 the following conditions: 16 17 The above copyright notice and this permission notice shall be included 18 in all copies or substantial portions of the Software. 19 20 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 21 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR 24 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 25 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 OTHER DEALINGS IN THE SOFTWARE. 27 ----------------------------------------------------------------------- */ 28 29#define LIBFFI_ASM 30 31#include <ffi.h> 32#include <ppc-ffitarget.h> // for FFI_TRAMPOLINE_SIZE 33#include <ppc-darwin.h> 34#include <architecture/ppc/mode_independent_asm.h> 35 36 .file "ppc-darwin_closure.S" 37.text 38 .align LOG2_GPR_BYTES 39 .globl _ffi_closure_ASM 40 41.text 42 .align LOG2_GPR_BYTES 43 44_ffi_closure_ASM: 45LFB1: 46 mflr r0 // Save return address 47 stg r0,SF_RETURN(r1) 48 49LCFI0: 50 /* 24/48 bytes (Linkage Area) 51 32/64 bytes (outgoing parameter area, always reserved) 52 104 bytes (13*8 from FPR) 53 16/32 bytes (result) 54 176/232 total bytes */ 55 56 /* skip over caller save area and keep stack aligned to 16/32. */ 57 stgu r1,-SF_ROUND(176)(r1) 58 59LCFI1: 60 /* We want to build up an area for the parameters passed 61 in registers. (both floating point and integer) */ 62 63 /* 176/256 bytes (callee stack frame aligned to 16/32) 64 24/48 bytes (caller linkage area) 65 200/304 (start of caller parameter area aligned to 4/8) 66 */ 67 68 /* Save GPRs 3 - 10 (aligned to 4/8) 69 in the parents outgoing area. */ 70 stg r3,200(r1) 71 stg r4,204(r1) 72 stg r5,208(r1) 73 stg r6,212(r1) 74 stg r7,216(r1) 75 stg r8,220(r1) 76 stg r9,224(r1) 77 stg r10,228(r1) 78 79 /* Save FPRs 1 - 13. (aligned to 8) */ 80 stfd f1,56(r1) 81 stfd f2,64(r1) 82 stfd f3,72(r1) 83 stfd f4,80(r1) 84 stfd f5,88(r1) 85 stfd f6,96(r1) 86 stfd f7,104(r1) 87 stfd f8,112(r1) 88 stfd f9,120(r1) 89 stfd f10,128(r1) 90 stfd f11,136(r1) 91 stfd f12,144(r1) 92 stfd f13,152(r1) 93 94 // Set up registers for the routine that actually does the work. 95 mr r3,r11 // context pointer from the trampoline 96 addi r4,r1,160 // result storage 97 addi r5,r1,200 // saved GPRs 98 addi r6,r1,56 // saved FPRs 99 bl Lffi_closure_helper_DARWIN$stub 100 101 /* Now r3 contains the return type. Use it to look up in a table 102 so we know how to deal with each type. */ 103 addi r5,r1,160 // Copy result storage pointer. 104 bl Lget_ret_type0_addr // Get pointer to Lret_type0 into LR. 105 mflr r4 // Move to r4. 106 slwi r3,r3,4 // Multiply return type by 16. 107 add r3,r3,r4 // Add contents of table to table address. 108 mtctr r3 109 bctr 110 111LFE1: 112/* Each of the ret_typeX code fragments has to be exactly 16 bytes long 113 (4 instructions). For cache effectiveness we align to a 16 byte boundary 114 first. */ 115 .align 4 116 nop 117 nop 118 nop 119 120Lget_ret_type0_addr: 121 blrl 122 123/* case FFI_TYPE_VOID */ 124Lret_type0: 125 b Lfinish 126 nop 127 nop 128 nop 129 130/* case FFI_TYPE_INT */ 131Lret_type1: 132 lwz r3,0(r5) 133 b Lfinish 134 nop 135 nop 136 137/* case FFI_TYPE_FLOAT */ 138Lret_type2: 139 lfs f1,0(r5) 140 b Lfinish 141 nop 142 nop 143 144/* case FFI_TYPE_DOUBLE */ 145Lret_type3: 146 lfd f1,0(r5) 147 b Lfinish 148 nop 149 nop 150 151/* case FFI_TYPE_LONGDOUBLE */ 152Lret_type4: 153 lfd f1,0(r5) 154 lfd f2,8(r5) 155 b Lfinish 156 nop 157 158/* case FFI_TYPE_UINT8 */ 159Lret_type5: 160 lbz r3,3(r5) 161 b Lfinish 162 nop 163 nop 164 165/* case FFI_TYPE_SINT8 */ 166Lret_type6: 167 lbz r3,3(r5) 168 extsb r3,r3 169 b Lfinish 170 nop 171 172/* case FFI_TYPE_UINT16 */ 173Lret_type7: 174 lhz r3,2(r5) 175 b Lfinish 176 nop 177 nop 178 179/* case FFI_TYPE_SINT16 */ 180Lret_type8: 181 lha r3,2(r5) 182 b Lfinish 183 nop 184 nop 185 186/* case FFI_TYPE_UINT32 */ 187Lret_type9: // same as Lret_type1 188 lwz r3,0(r5) 189 b Lfinish 190 nop 191 nop 192 193/* case FFI_TYPE_SINT32 */ 194Lret_type10: // same as Lret_type1 195 lwz r3,0(r5) 196 b Lfinish 197 nop 198 nop 199 200/* case FFI_TYPE_UINT64 */ 201Lret_type11: 202 lwz r3,0(r5) 203 lwz r4,4(r5) 204 b Lfinish 205 nop 206 207/* case FFI_TYPE_SINT64 */ 208Lret_type12: // same as Lret_type11 209 lwz r3,0(r5) 210 lwz r4,4(r5) 211 b Lfinish 212 nop 213 214/* case FFI_TYPE_STRUCT */ 215Lret_type13: 216 b Lfinish 217 nop 218 nop 219 nop 220 221/* End 16-byte aligned cases */ 222/* case FFI_TYPE_POINTER */ 223// This case assumes that FFI_TYPE_POINTER == FFI_TYPE_LAST. If more types 224// are added in future, the following code will need to be updated and 225// padded to 16 bytes. 226Lret_type14: 227 lg r3,0(r5) 228 // fall through 229 230/* case done */ 231Lfinish: 232 addi r1,r1,SF_ROUND(176) // Restore stack pointer. 233 lg r0,SF_RETURN(r1) // Restore return address. 234 mtlr r0 // Restore link register. 235 blr 236 237/* END(ffi_closure_ASM) */ 238 239.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support 240EH_frame1: 241 .set L$set$0,LECIE1-LSCIE1 242 .long L$set$0 ; Length of Common Information Entry 243LSCIE1: 244 .long 0x0 ; CIE Identifier Tag 245 .byte 0x1 ; CIE Version 246 .ascii "zR\0" ; CIE Augmentation 247 .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor 248 .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor 249 .byte 0x41 ; CIE RA Column 250 .byte 0x1 ; uleb128 0x1; Augmentation size 251 .byte 0x10 ; FDE Encoding (pcrel) 252 .byte 0xc ; DW_CFA_def_cfa 253 .byte 0x1 ; uleb128 0x1 254 .byte 0x0 ; uleb128 0x0 255 .align LOG2_GPR_BYTES 256LECIE1: 257.globl _ffi_closure_ASM.eh 258_ffi_closure_ASM.eh: 259LSFDE1: 260 .set L$set$1,LEFDE1-LASFDE1 261 .long L$set$1 ; FDE Length 262 263LASFDE1: 264 .long LASFDE1-EH_frame1 ; FDE CIE offset 265 .g_long LFB1-. ; FDE initial location 266 .set L$set$3,LFE1-LFB1 267 .g_long L$set$3 ; FDE address range 268 .byte 0x0 ; uleb128 0x0; Augmentation size 269 .byte 0x4 ; DW_CFA_advance_loc4 270 .set L$set$3,LCFI1-LCFI0 271 .long L$set$3 272 .byte 0xe ; DW_CFA_def_cfa_offset 273 .byte 176,1 ; uleb128 176 274 .byte 0x4 ; DW_CFA_advance_loc4 275 .set L$set$4,LCFI0-LFB1 276 .long L$set$4 277 .byte 0x11 ; DW_CFA_offset_extended_sf 278 .byte 0x41 ; uleb128 0x41 279 .byte 0x7e ; sleb128 -2 280 .align LOG2_GPR_BYTES 281 282LEFDE1: 283.data 284 .align LOG2_GPR_BYTES 285LDFCM0: 286.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 287 .align LOG2_GPR_BYTES 288 289Lffi_closure_helper_DARWIN$stub: 290 .indirect_symbol _ffi_closure_helper_DARWIN 291 mflr r0 292 bcl 20,31,LO$ffi_closure_helper_DARWIN 293 294LO$ffi_closure_helper_DARWIN: 295 mflr r11 296 addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN) 297 mtlr r0 298 lgu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)(r11) 299 mtctr r12 300 bctr 301 302.lazy_symbol_pointer 303L_ffi_closure_helper_DARWIN$lazy_ptr: 304 .indirect_symbol _ffi_closure_helper_DARWIN 305 .g_long dyld_stub_binding_helper 306 307 308#endif // __ppc__ 309