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