1/* ----------------------------------------------------------------------- 2 darwin.S - Copyright (c) 2000 John Hornkvist 3 Copyright (c) 2004 Free Software Foundation, Inc. 4 5 PowerPC Assembly glue. 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#if defined(__ppc64__) 28#define MODE_CHOICE(x, y) y 29#else 30#define MODE_CHOICE(x, y) x 31#endif 32 33#define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */ 34 35#define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */ 36 37#define LIBFFI_ASM 38#include <fficonfig.h> 39#include <ffi.h> 40#define JUMPTARGET(name) name 41#define L(x) x 42.text 43 .align 2 44.globl _ffi_prep_args 45 46.text 47 .align 2 48.globl _ffi_call_DARWIN 49.text 50 .align 2 51_ffi_call_DARWIN: 52LFB0: 53 mr r12,r8 /* We only need r12 until the call, 54 so it doesn't have to be saved. */ 55LFB1: 56 /* Save the old stack pointer as AP. */ 57 mr r8,r1 58LCFI0: 59 /* Allocate the stack space we need. */ 60 stwux r1,r1,r4 61 62 /* Save registers we use. */ 63 mflr r9 64 65 stw r28,-16(r8) 66 stw r29,-12(r8) 67 stw r30,-8(r8) 68 stw r31,-4(r8) 69 70 stw r9,8(r8) 71 stw r2,20(r1) 72LCFI1: 73 74 /* Save arguments over call. */ 75 mr r31,r5 /* flags, */ 76 mr r30,r6 /* rvalue, */ 77 mr r29,r7 /* function address, */ 78 mr r28,r8 /* our AP. */ 79LCFI2: 80 /* Call ffi_prep_args. */ 81 mr r4,r1 82// ANDROID: these changes were necessary in 2.x; not yet tested in 3.x 83// subi r1,r1,32 /* Android: adjust stack for parameter / scratch area */ 84 li r9,0 85 86 mtctr r12 /* r12 holds address of _ffi_prep_args. */ 87 bctrl 88// addi r1,r1,32 /* Android: readjust stack (see subi above) */ 89 lwz r2,20(r1) 90 91 /* Now do the call. 92 Set up cr1 with bits 4-7 of the flags. */ 93 mtcrf 0x40,r31 94 /* Get the address to call into CTR. */ 95 mtctr r29 96 /* Load all those argument registers. 97 We have set up a nice stack frame, just load it into registers. */ 98 lwz r3,20+(1*4)(r1) 99 lwz r4,20+(2*4)(r1) 100 lwz r5,20+(3*4)(r1) 101 lwz r6,20+(4*4)(r1) 102 nop 103 lwz r7,20+(5*4)(r1) 104 lwz r8,20+(6*4)(r1) 105 lwz r9,20+(7*4)(r1) 106 lwz r10,20+(8*4)(r1) 107 108L1: 109 /* Load all the FP registers. */ 110 bf 6,L2 /* No floats to load. */ 111 lfd f1,-16-(13*8)(r28) 112 lfd f2,-16-(12*8)(r28) 113 lfd f3,-16-(11*8)(r28) 114 lfd f4,-16-(10*8)(r28) 115 nop 116 lfd f5,-16-(9*8)(r28) 117 lfd f6,-16-(8*8)(r28) 118 lfd f7,-16-(7*8)(r28) 119 lfd f8,-16-(6*8)(r28) 120 nop 121 lfd f9,-16-(5*8)(r28) 122 lfd f10,-16-(4*8)(r28) 123 lfd f11,-16-(3*8)(r28) 124 lfd f12,-16-(2*8)(r28) 125 nop 126 lfd f13,-16-(1*8)(r28) 127 128L2: 129 mr r12,r29 /* Put the target address in r12 as specified. */ 130 mtctr r12 131 nop 132 nop 133 /* Make the call. */ 134 bctrl 135 136 /* Now, deal with the return value. */ 137 mtcrf 0x01,r31 138 139 bt 30,L(done_return_value) 140 bt 29,L(fp_return_value) 141 stw r3,0(r30) 142 bf 28,L(done_return_value) 143 stw r4,4(r30) 144 145 /* Fall through. */ 146 147L(done_return_value): 148 /* Restore the registers we used and return. */ 149 lwz r9,8(r28) 150 lwz r31,-4(r28) 151 mtlr r9 152 lwz r30,-8(r28) 153 lwz r29,-12(r28) 154 lwz r28,-16(r28) 155 lwz r1,0(r1) 156 blr 157 158L(fp_return_value): 159 /* Do we have long double to store? */ 160 bf 31,L(fd_return_value) 161 stfd f1,0(r30) 162 stfd f2,8(r30) 163 b L(done_return_value) 164 165L(fd_return_value): 166 /* Do we have double to store? */ 167 bf 28,L(float_return_value) 168 stfd f1,0(r30) 169 b L(done_return_value) 170 171L(float_return_value): 172 /* We only have a float to store. */ 173 stfs f1,0(r30) 174 b L(done_return_value) 175 176LFE1: 177/* END(_ffi_call_DARWIN) */ 178 179/* Provide a null definition of _ffi_call_AIX. */ 180.text 181 .align 2 182.globl _ffi_call_AIX 183.text 184 .align 2 185_ffi_call_AIX: 186 blr 187/* END(_ffi_call_AIX) */ 188 189.data 190.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms 191EH_frame1: 192 .set L$set$0,LECIE1-LSCIE1 193 .long L$set$0 ; Length of Common Information Entry 194LSCIE1: 195 .long 0x0 ; CIE Identifier Tag 196 .byte 0x1 ; CIE Version 197 .ascii "zR\0" ; CIE Augmentation 198 .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor 199 .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor 200 .byte 0x41 ; CIE RA Column 201 .byte 0x1 ; uleb128 0x1; Augmentation size 202 .byte 0x90 ; FDE Encoding (indirect pcrel) 203 .byte 0xc ; DW_CFA_def_cfa 204 .byte 0x1 ; uleb128 0x1 205 .byte 0x0 ; uleb128 0x0 206 .align LOG2_GPR_BYTES 207LECIE1: 208.globl _ffi_call_DARWIN.eh 209_ffi_call_DARWIN.eh: 210LSFDE1: 211 .set L$set$1,LEFDE1-LASFDE1 212 .long L$set$1 ; FDE Length 213LASFDE1: 214 .long LASFDE1-EH_frame1 ; FDE CIE offset 215 .g_long LLFB0$non_lazy_ptr-. ; FDE initial location 216 .set L$set$3,LFE1-LFB0 217 .g_long L$set$3 ; FDE address range 218 .byte 0x0 ; uleb128 0x0; Augmentation size 219 .byte 0x4 ; DW_CFA_advance_loc4 220 .set L$set$4,LCFI0-LFB1 221 .long L$set$4 222 .byte 0xd ; DW_CFA_def_cfa_register 223 .byte 0x08 ; uleb128 0x08 224 .byte 0x4 ; DW_CFA_advance_loc4 225 .set L$set$5,LCFI1-LCFI0 226 .long L$set$5 227 .byte 0x11 ; DW_CFA_offset_extended_sf 228 .byte 0x41 ; uleb128 0x41 229 .byte 0x7e ; sleb128 -2 230 .byte 0x9f ; DW_CFA_offset, column 0x1f 231 .byte 0x1 ; uleb128 0x1 232 .byte 0x9e ; DW_CFA_offset, column 0x1e 233 .byte 0x2 ; uleb128 0x2 234 .byte 0x9d ; DW_CFA_offset, column 0x1d 235 .byte 0x3 ; uleb128 0x3 236 .byte 0x9c ; DW_CFA_offset, column 0x1c 237 .byte 0x4 ; uleb128 0x4 238 .byte 0x4 ; DW_CFA_advance_loc4 239 .set L$set$6,LCFI2-LCFI1 240 .long L$set$6 241 .byte 0xd ; DW_CFA_def_cfa_register 242 .byte 0x1c ; uleb128 0x1c 243 .align LOG2_GPR_BYTES 244LEFDE1: 245.data 246 .align LOG2_GPR_BYTES 247LLFB0$non_lazy_ptr: 248 .g_long LFB0 249