1*1fd5a2e1SPrashanth Swaminathan/* ----------------------------------------------------------------------- 2*1fd5a2e1SPrashanth Swaminathan darwin.S - Copyright (c) 2000 John Hornkvist 3*1fd5a2e1SPrashanth Swaminathan Copyright (c) 2004, 2010 Free Software Foundation, Inc. 4*1fd5a2e1SPrashanth Swaminathan 5*1fd5a2e1SPrashanth Swaminathan PowerPC Assembly glue. 6*1fd5a2e1SPrashanth Swaminathan 7*1fd5a2e1SPrashanth Swaminathan Permission is hereby granted, free of charge, to any person obtaining 8*1fd5a2e1SPrashanth Swaminathan a copy of this software and associated documentation files (the 9*1fd5a2e1SPrashanth Swaminathan ``Software''), to deal in the Software without restriction, including 10*1fd5a2e1SPrashanth Swaminathan without limitation the rights to use, copy, modify, merge, publish, 11*1fd5a2e1SPrashanth Swaminathan distribute, sublicense, and/or sell copies of the Software, and to 12*1fd5a2e1SPrashanth Swaminathan permit persons to whom the Software is furnished to do so, subject to 13*1fd5a2e1SPrashanth Swaminathan the following conditions: 14*1fd5a2e1SPrashanth Swaminathan 15*1fd5a2e1SPrashanth Swaminathan The above copyright notice and this permission notice shall be included 16*1fd5a2e1SPrashanth Swaminathan in all copies or substantial portions of the Software. 17*1fd5a2e1SPrashanth Swaminathan 18*1fd5a2e1SPrashanth Swaminathan THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 19*1fd5a2e1SPrashanth Swaminathan OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20*1fd5a2e1SPrashanth Swaminathan MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21*1fd5a2e1SPrashanth Swaminathan IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR 22*1fd5a2e1SPrashanth Swaminathan OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23*1fd5a2e1SPrashanth Swaminathan ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24*1fd5a2e1SPrashanth Swaminathan OTHER DEALINGS IN THE SOFTWARE. 25*1fd5a2e1SPrashanth Swaminathan ----------------------------------------------------------------------- */ 26*1fd5a2e1SPrashanth Swaminathan 27*1fd5a2e1SPrashanth Swaminathan#define LIBFFI_ASM 28*1fd5a2e1SPrashanth Swaminathan#if defined(__ppc64__) 29*1fd5a2e1SPrashanth Swaminathan#define MODE_CHOICE(x, y) y 30*1fd5a2e1SPrashanth Swaminathan#else 31*1fd5a2e1SPrashanth Swaminathan#define MODE_CHOICE(x, y) x 32*1fd5a2e1SPrashanth Swaminathan#endif 33*1fd5a2e1SPrashanth Swaminathan 34*1fd5a2e1SPrashanth Swaminathan#define machine_choice MODE_CHOICE(ppc7400,ppc64) 35*1fd5a2e1SPrashanth Swaminathan 36*1fd5a2e1SPrashanth Swaminathan; Define some pseudo-opcodes for size-independent load & store of GPRs ... 37*1fd5a2e1SPrashanth Swaminathan#define lgu MODE_CHOICE(lwzu, ldu) 38*1fd5a2e1SPrashanth Swaminathan#define lg MODE_CHOICE(lwz,ld) 39*1fd5a2e1SPrashanth Swaminathan#define sg MODE_CHOICE(stw,std) 40*1fd5a2e1SPrashanth Swaminathan#define sgu MODE_CHOICE(stwu,stdu) 41*1fd5a2e1SPrashanth Swaminathan#define sgux MODE_CHOICE(stwux,stdux) 42*1fd5a2e1SPrashanth Swaminathan 43*1fd5a2e1SPrashanth Swaminathan; ... and the size of GPRs and their storage indicator. 44*1fd5a2e1SPrashanth Swaminathan#define GPR_BYTES MODE_CHOICE(4,8) 45*1fd5a2e1SPrashanth Swaminathan#define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */ 46*1fd5a2e1SPrashanth Swaminathan#define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */ 47*1fd5a2e1SPrashanth Swaminathan 48*1fd5a2e1SPrashanth Swaminathan; From the ABI doc: "Mac OS X ABI Function Call Guide" Version 2009-02-04. 49*1fd5a2e1SPrashanth Swaminathan#define LINKAGE_SIZE MODE_CHOICE(24,48) 50*1fd5a2e1SPrashanth Swaminathan#define PARAM_AREA MODE_CHOICE(32,64) 51*1fd5a2e1SPrashanth Swaminathan#define SAVED_LR_OFFSET MODE_CHOICE(8,16) /* save position for lr */ 52*1fd5a2e1SPrashanth Swaminathan 53*1fd5a2e1SPrashanth Swaminathan/* If there is any FP stuff we make space for all of the regs. */ 54*1fd5a2e1SPrashanth Swaminathan#define SAVED_FPR_COUNT 13 55*1fd5a2e1SPrashanth Swaminathan#define FPR_SIZE 8 56*1fd5a2e1SPrashanth Swaminathan#define RESULT_BYTES 16 57*1fd5a2e1SPrashanth Swaminathan 58*1fd5a2e1SPrashanth Swaminathan/* This should be kept in step with the same value in ffi_darwin.c. */ 59*1fd5a2e1SPrashanth Swaminathan#define ASM_NEEDS_REGISTERS 4 60*1fd5a2e1SPrashanth Swaminathan#define SAVE_REGS_SIZE (ASM_NEEDS_REGISTERS * GPR_BYTES) 61*1fd5a2e1SPrashanth Swaminathan 62*1fd5a2e1SPrashanth Swaminathan#include <fficonfig.h> 63*1fd5a2e1SPrashanth Swaminathan#include <ffi.h> 64*1fd5a2e1SPrashanth Swaminathan 65*1fd5a2e1SPrashanth Swaminathan#define JUMPTARGET(name) name 66*1fd5a2e1SPrashanth Swaminathan#define L(x) x 67*1fd5a2e1SPrashanth Swaminathan 68*1fd5a2e1SPrashanth Swaminathan .text 69*1fd5a2e1SPrashanth Swaminathan .align 2 70*1fd5a2e1SPrashanth Swaminathan .globl _ffi_prep_args 71*1fd5a2e1SPrashanth Swaminathan 72*1fd5a2e1SPrashanth Swaminathan .align 2 73*1fd5a2e1SPrashanth Swaminathan .globl _ffi_call_DARWIN 74*1fd5a2e1SPrashanth Swaminathan 75*1fd5a2e1SPrashanth Swaminathan /* We arrive here with: 76*1fd5a2e1SPrashanth Swaminathan r3 = ptr to extended cif. 77*1fd5a2e1SPrashanth Swaminathan r4 = -bytes. 78*1fd5a2e1SPrashanth Swaminathan r5 = cif flags. 79*1fd5a2e1SPrashanth Swaminathan r6 = ptr to return value. 80*1fd5a2e1SPrashanth Swaminathan r7 = fn pointer (user func). 81*1fd5a2e1SPrashanth Swaminathan r8 = fn pointer (ffi_prep_args). 82*1fd5a2e1SPrashanth Swaminathan r9 = ffi_type* for the ret val. */ 83*1fd5a2e1SPrashanth Swaminathan 84*1fd5a2e1SPrashanth Swaminathan_ffi_call_DARWIN: 85*1fd5a2e1SPrashanth SwaminathanLstartcode: 86*1fd5a2e1SPrashanth Swaminathan mr r12,r8 /* We only need r12 until the call, 87*1fd5a2e1SPrashanth Swaminathan so it does not have to be saved. */ 88*1fd5a2e1SPrashanth SwaminathanLFB1: 89*1fd5a2e1SPrashanth Swaminathan /* Save the old stack pointer as AP. */ 90*1fd5a2e1SPrashanth Swaminathan mr r8,r1 91*1fd5a2e1SPrashanth SwaminathanLCFI0: 92*1fd5a2e1SPrashanth Swaminathan 93*1fd5a2e1SPrashanth Swaminathan /* Save the retval type in parents frame. */ 94*1fd5a2e1SPrashanth Swaminathan sg r9,(LINKAGE_SIZE+6*GPR_BYTES)(r8) 95*1fd5a2e1SPrashanth Swaminathan 96*1fd5a2e1SPrashanth Swaminathan /* Allocate the stack space we need. */ 97*1fd5a2e1SPrashanth Swaminathan sgux r1,r1,r4 98*1fd5a2e1SPrashanth Swaminathan 99*1fd5a2e1SPrashanth Swaminathan /* Save registers we use. */ 100*1fd5a2e1SPrashanth Swaminathan mflr r9 101*1fd5a2e1SPrashanth Swaminathan sg r9,SAVED_LR_OFFSET(r8) 102*1fd5a2e1SPrashanth Swaminathan 103*1fd5a2e1SPrashanth Swaminathan sg r28,-(4 * GPR_BYTES)(r8) 104*1fd5a2e1SPrashanth Swaminathan sg r29,-(3 * GPR_BYTES)(r8) 105*1fd5a2e1SPrashanth Swaminathan sg r30,-(2 * GPR_BYTES)(r8) 106*1fd5a2e1SPrashanth Swaminathan sg r31,-( GPR_BYTES)(r8) 107*1fd5a2e1SPrashanth Swaminathan 108*1fd5a2e1SPrashanth Swaminathan#if !defined(POWERPC_DARWIN) 109*1fd5a2e1SPrashanth Swaminathan /* The TOC slot is reserved in the Darwin ABI and r2 is volatile. */ 110*1fd5a2e1SPrashanth Swaminathan sg r2,(5 * GPR_BYTES)(r1) 111*1fd5a2e1SPrashanth Swaminathan#endif 112*1fd5a2e1SPrashanth Swaminathan 113*1fd5a2e1SPrashanth SwaminathanLCFI1: 114*1fd5a2e1SPrashanth Swaminathan 115*1fd5a2e1SPrashanth Swaminathan /* Save arguments over call. */ 116*1fd5a2e1SPrashanth Swaminathan mr r31,r5 /* flags, */ 117*1fd5a2e1SPrashanth Swaminathan mr r30,r6 /* rvalue, */ 118*1fd5a2e1SPrashanth Swaminathan mr r29,r7 /* function address, */ 119*1fd5a2e1SPrashanth Swaminathan mr r28,r8 /* our AP. */ 120*1fd5a2e1SPrashanth SwaminathanLCFI2: 121*1fd5a2e1SPrashanth Swaminathan /* Call ffi_prep_args. r3 = extended cif, r4 = stack ptr copy. */ 122*1fd5a2e1SPrashanth Swaminathan mr r4,r1 123*1fd5a2e1SPrashanth Swaminathan li r9,0 124*1fd5a2e1SPrashanth Swaminathan 125*1fd5a2e1SPrashanth Swaminathan mtctr r12 /* r12 holds address of _ffi_prep_args. */ 126*1fd5a2e1SPrashanth Swaminathan bctrl 127*1fd5a2e1SPrashanth Swaminathan 128*1fd5a2e1SPrashanth Swaminathan#if !defined(POWERPC_DARWIN) 129*1fd5a2e1SPrashanth Swaminathan /* The TOC slot is reserved in the Darwin ABI and r2 is volatile. */ 130*1fd5a2e1SPrashanth Swaminathan lg r2,(5 * GPR_BYTES)(r1) 131*1fd5a2e1SPrashanth Swaminathan#endif 132*1fd5a2e1SPrashanth Swaminathan /* Now do the call. 133*1fd5a2e1SPrashanth Swaminathan Set up cr1 with bits 4-7 of the flags. */ 134*1fd5a2e1SPrashanth Swaminathan mtcrf 0x40,r31 135*1fd5a2e1SPrashanth Swaminathan /* Get the address to call into CTR. */ 136*1fd5a2e1SPrashanth Swaminathan mtctr r29 137*1fd5a2e1SPrashanth Swaminathan /* Load all those argument registers. 138*1fd5a2e1SPrashanth Swaminathan We have set up a nice stack frame, just load it into registers. */ 139*1fd5a2e1SPrashanth Swaminathan lg r3, (LINKAGE_SIZE )(r1) 140*1fd5a2e1SPrashanth Swaminathan lg r4, (LINKAGE_SIZE + GPR_BYTES)(r1) 141*1fd5a2e1SPrashanth Swaminathan lg r5, (LINKAGE_SIZE + 2 * GPR_BYTES)(r1) 142*1fd5a2e1SPrashanth Swaminathan lg r6, (LINKAGE_SIZE + 3 * GPR_BYTES)(r1) 143*1fd5a2e1SPrashanth Swaminathan nop 144*1fd5a2e1SPrashanth Swaminathan lg r7, (LINKAGE_SIZE + 4 * GPR_BYTES)(r1) 145*1fd5a2e1SPrashanth Swaminathan lg r8, (LINKAGE_SIZE + 5 * GPR_BYTES)(r1) 146*1fd5a2e1SPrashanth Swaminathan lg r9, (LINKAGE_SIZE + 6 * GPR_BYTES)(r1) 147*1fd5a2e1SPrashanth Swaminathan lg r10,(LINKAGE_SIZE + 7 * GPR_BYTES)(r1) 148*1fd5a2e1SPrashanth Swaminathan 149*1fd5a2e1SPrashanth SwaminathanL1: 150*1fd5a2e1SPrashanth Swaminathan /* ... Load all the FP registers. */ 151*1fd5a2e1SPrashanth Swaminathan bf 6,L2 /* No floats to load. */ 152*1fd5a2e1SPrashanth Swaminathan lfd f1, -SAVE_REGS_SIZE-(13*FPR_SIZE)(r28) 153*1fd5a2e1SPrashanth Swaminathan lfd f2, -SAVE_REGS_SIZE-(12*FPR_SIZE)(r28) 154*1fd5a2e1SPrashanth Swaminathan lfd f3, -SAVE_REGS_SIZE-(11*FPR_SIZE)(r28) 155*1fd5a2e1SPrashanth Swaminathan lfd f4, -SAVE_REGS_SIZE-(10*FPR_SIZE)(r28) 156*1fd5a2e1SPrashanth Swaminathan nop 157*1fd5a2e1SPrashanth Swaminathan lfd f5, -SAVE_REGS_SIZE-( 9*FPR_SIZE)(r28) 158*1fd5a2e1SPrashanth Swaminathan lfd f6, -SAVE_REGS_SIZE-( 8*FPR_SIZE)(r28) 159*1fd5a2e1SPrashanth Swaminathan lfd f7, -SAVE_REGS_SIZE-( 7*FPR_SIZE)(r28) 160*1fd5a2e1SPrashanth Swaminathan lfd f8, -SAVE_REGS_SIZE-( 6*FPR_SIZE)(r28) 161*1fd5a2e1SPrashanth Swaminathan nop 162*1fd5a2e1SPrashanth Swaminathan lfd f9, -SAVE_REGS_SIZE-( 5*FPR_SIZE)(r28) 163*1fd5a2e1SPrashanth Swaminathan lfd f10,-SAVE_REGS_SIZE-( 4*FPR_SIZE)(r28) 164*1fd5a2e1SPrashanth Swaminathan lfd f11,-SAVE_REGS_SIZE-( 3*FPR_SIZE)(r28) 165*1fd5a2e1SPrashanth Swaminathan lfd f12,-SAVE_REGS_SIZE-( 2*FPR_SIZE)(r28) 166*1fd5a2e1SPrashanth Swaminathan nop 167*1fd5a2e1SPrashanth Swaminathan lfd f13,-SAVE_REGS_SIZE-( 1*FPR_SIZE)(r28) 168*1fd5a2e1SPrashanth Swaminathan 169*1fd5a2e1SPrashanth SwaminathanL2: 170*1fd5a2e1SPrashanth Swaminathan mr r12,r29 /* Put the target address in r12 as specified. */ 171*1fd5a2e1SPrashanth Swaminathan mtctr r12 172*1fd5a2e1SPrashanth Swaminathan nop 173*1fd5a2e1SPrashanth Swaminathan nop 174*1fd5a2e1SPrashanth Swaminathan 175*1fd5a2e1SPrashanth Swaminathan /* Make the call. */ 176*1fd5a2e1SPrashanth Swaminathan bctrl 177*1fd5a2e1SPrashanth Swaminathan 178*1fd5a2e1SPrashanth Swaminathan /* Now, deal with the return value. */ 179*1fd5a2e1SPrashanth Swaminathan 180*1fd5a2e1SPrashanth Swaminathan /* m64 structure returns can occupy the same set of registers as 181*1fd5a2e1SPrashanth Swaminathan would be used to pass such a structure as arg0 - so take care 182*1fd5a2e1SPrashanth Swaminathan not to step on any possibly hot regs. */ 183*1fd5a2e1SPrashanth Swaminathan 184*1fd5a2e1SPrashanth Swaminathan /* Get the flags.. */ 185*1fd5a2e1SPrashanth Swaminathan mtcrf 0x03,r31 ; we need c6 & cr7 now. 186*1fd5a2e1SPrashanth Swaminathan ; FLAG_RETURNS_NOTHING also covers struct ret-by-ref. 187*1fd5a2e1SPrashanth Swaminathan bt 30,L(done_return_value) ; FLAG_RETURNS_NOTHING 188*1fd5a2e1SPrashanth Swaminathan bf 27,L(scalar_return_value) ; not FLAG_RETURNS_STRUCT 189*1fd5a2e1SPrashanth Swaminathan 190*1fd5a2e1SPrashanth Swaminathan /* OK, so we have a struct. */ 191*1fd5a2e1SPrashanth Swaminathan#if defined(__ppc64__) 192*1fd5a2e1SPrashanth Swaminathan bt 31,L(maybe_return_128) ; FLAG_RETURNS_128BITS, special case 193*1fd5a2e1SPrashanth Swaminathan 194*1fd5a2e1SPrashanth Swaminathan /* OK, we have to map the return back to a mem struct. 195*1fd5a2e1SPrashanth Swaminathan We are about to trample the parents param area, so recover the 196*1fd5a2e1SPrashanth Swaminathan return type. r29 is free, since the call is done. */ 197*1fd5a2e1SPrashanth Swaminathan lg r29,(LINKAGE_SIZE + 6 * GPR_BYTES)(r28) 198*1fd5a2e1SPrashanth Swaminathan 199*1fd5a2e1SPrashanth Swaminathan sg r3, (LINKAGE_SIZE )(r28) 200*1fd5a2e1SPrashanth Swaminathan sg r4, (LINKAGE_SIZE + GPR_BYTES)(r28) 201*1fd5a2e1SPrashanth Swaminathan sg r5, (LINKAGE_SIZE + 2 * GPR_BYTES)(r28) 202*1fd5a2e1SPrashanth Swaminathan sg r6, (LINKAGE_SIZE + 3 * GPR_BYTES)(r28) 203*1fd5a2e1SPrashanth Swaminathan nop 204*1fd5a2e1SPrashanth Swaminathan sg r7, (LINKAGE_SIZE + 4 * GPR_BYTES)(r28) 205*1fd5a2e1SPrashanth Swaminathan sg r8, (LINKAGE_SIZE + 5 * GPR_BYTES)(r28) 206*1fd5a2e1SPrashanth Swaminathan sg r9, (LINKAGE_SIZE + 6 * GPR_BYTES)(r28) 207*1fd5a2e1SPrashanth Swaminathan sg r10,(LINKAGE_SIZE + 7 * GPR_BYTES)(r28) 208*1fd5a2e1SPrashanth Swaminathan /* OK, so do the block move - we trust that memcpy will not trample 209*1fd5a2e1SPrashanth Swaminathan the fprs... */ 210*1fd5a2e1SPrashanth Swaminathan mr r3,r30 ; dest 211*1fd5a2e1SPrashanth Swaminathan addi r4,r28,LINKAGE_SIZE ; source 212*1fd5a2e1SPrashanth Swaminathan /* The size is a size_t, should be long. */ 213*1fd5a2e1SPrashanth Swaminathan lg r5,0(r29) 214*1fd5a2e1SPrashanth Swaminathan /* Figure out small structs */ 215*1fd5a2e1SPrashanth Swaminathan cmpi 0,r5,4 216*1fd5a2e1SPrashanth Swaminathan bgt L3 ; 1, 2 and 4 bytes have special rules. 217*1fd5a2e1SPrashanth Swaminathan cmpi 0,r5,3 218*1fd5a2e1SPrashanth Swaminathan beq L3 ; not 3 219*1fd5a2e1SPrashanth Swaminathan addi r4,r4,8 220*1fd5a2e1SPrashanth Swaminathan subf r4,r5,r4 221*1fd5a2e1SPrashanth SwaminathanL3: 222*1fd5a2e1SPrashanth Swaminathan bl _memcpy 223*1fd5a2e1SPrashanth Swaminathan 224*1fd5a2e1SPrashanth Swaminathan /* ... do we need the FP registers? - recover the flags.. */ 225*1fd5a2e1SPrashanth Swaminathan mtcrf 0x03,r31 ; we need c6 & cr7 now. 226*1fd5a2e1SPrashanth Swaminathan bf 29,L(done_return_value) /* No floats in the struct. */ 227*1fd5a2e1SPrashanth Swaminathan stfd f1, -SAVE_REGS_SIZE-(13*FPR_SIZE)(r28) 228*1fd5a2e1SPrashanth Swaminathan stfd f2, -SAVE_REGS_SIZE-(12*FPR_SIZE)(r28) 229*1fd5a2e1SPrashanth Swaminathan stfd f3, -SAVE_REGS_SIZE-(11*FPR_SIZE)(r28) 230*1fd5a2e1SPrashanth Swaminathan stfd f4, -SAVE_REGS_SIZE-(10*FPR_SIZE)(r28) 231*1fd5a2e1SPrashanth Swaminathan nop 232*1fd5a2e1SPrashanth Swaminathan stfd f5, -SAVE_REGS_SIZE-( 9*FPR_SIZE)(r28) 233*1fd5a2e1SPrashanth Swaminathan stfd f6, -SAVE_REGS_SIZE-( 8*FPR_SIZE)(r28) 234*1fd5a2e1SPrashanth Swaminathan stfd f7, -SAVE_REGS_SIZE-( 7*FPR_SIZE)(r28) 235*1fd5a2e1SPrashanth Swaminathan stfd f8, -SAVE_REGS_SIZE-( 6*FPR_SIZE)(r28) 236*1fd5a2e1SPrashanth Swaminathan nop 237*1fd5a2e1SPrashanth Swaminathan stfd f9, -SAVE_REGS_SIZE-( 5*FPR_SIZE)(r28) 238*1fd5a2e1SPrashanth Swaminathan stfd f10,-SAVE_REGS_SIZE-( 4*FPR_SIZE)(r28) 239*1fd5a2e1SPrashanth Swaminathan stfd f11,-SAVE_REGS_SIZE-( 3*FPR_SIZE)(r28) 240*1fd5a2e1SPrashanth Swaminathan stfd f12,-SAVE_REGS_SIZE-( 2*FPR_SIZE)(r28) 241*1fd5a2e1SPrashanth Swaminathan nop 242*1fd5a2e1SPrashanth Swaminathan stfd f13,-SAVE_REGS_SIZE-( 1*FPR_SIZE)(r28) 243*1fd5a2e1SPrashanth Swaminathan 244*1fd5a2e1SPrashanth Swaminathan mr r3,r29 ; ffi_type * 245*1fd5a2e1SPrashanth Swaminathan mr r4,r30 ; dest 246*1fd5a2e1SPrashanth Swaminathan addi r5,r28,-SAVE_REGS_SIZE-(13*FPR_SIZE) ; fprs 247*1fd5a2e1SPrashanth Swaminathan xor r6,r6,r6 248*1fd5a2e1SPrashanth Swaminathan sg r6,(LINKAGE_SIZE + 7 * GPR_BYTES)(r28) 249*1fd5a2e1SPrashanth Swaminathan addi r6,r28,(LINKAGE_SIZE + 7 * GPR_BYTES) ; point to a zeroed counter. 250*1fd5a2e1SPrashanth Swaminathan bl _darwin64_struct_floats_to_mem 251*1fd5a2e1SPrashanth Swaminathan 252*1fd5a2e1SPrashanth Swaminathan b L(done_return_value) 253*1fd5a2e1SPrashanth Swaminathan#else 254*1fd5a2e1SPrashanth Swaminathan stw r3,0(r30) ; m32 the only struct return in reg is 4 bytes. 255*1fd5a2e1SPrashanth Swaminathan#endif 256*1fd5a2e1SPrashanth Swaminathan b L(done_return_value) 257*1fd5a2e1SPrashanth Swaminathan 258*1fd5a2e1SPrashanth SwaminathanL(fp_return_value): 259*1fd5a2e1SPrashanth Swaminathan /* Do we have long double to store? */ 260*1fd5a2e1SPrashanth Swaminathan bf 31,L(fd_return_value) ; FLAG_RETURNS_128BITS 261*1fd5a2e1SPrashanth Swaminathan stfd f1,0(r30) 262*1fd5a2e1SPrashanth Swaminathan stfd f2,FPR_SIZE(r30) 263*1fd5a2e1SPrashanth Swaminathan b L(done_return_value) 264*1fd5a2e1SPrashanth Swaminathan 265*1fd5a2e1SPrashanth SwaminathanL(fd_return_value): 266*1fd5a2e1SPrashanth Swaminathan /* Do we have double to store? */ 267*1fd5a2e1SPrashanth Swaminathan bf 28,L(float_return_value) 268*1fd5a2e1SPrashanth Swaminathan stfd f1,0(r30) 269*1fd5a2e1SPrashanth Swaminathan b L(done_return_value) 270*1fd5a2e1SPrashanth Swaminathan 271*1fd5a2e1SPrashanth SwaminathanL(float_return_value): 272*1fd5a2e1SPrashanth Swaminathan /* We only have a float to store. */ 273*1fd5a2e1SPrashanth Swaminathan stfs f1,0(r30) 274*1fd5a2e1SPrashanth Swaminathan b L(done_return_value) 275*1fd5a2e1SPrashanth Swaminathan 276*1fd5a2e1SPrashanth SwaminathanL(scalar_return_value): 277*1fd5a2e1SPrashanth Swaminathan bt 29,L(fp_return_value) ; FLAG_RETURNS_FP 278*1fd5a2e1SPrashanth Swaminathan ; ffi_arg is defined as unsigned long. 279*1fd5a2e1SPrashanth Swaminathan sg r3,0(r30) ; Save the reg. 280*1fd5a2e1SPrashanth Swaminathan bf 28,L(done_return_value) ; not FLAG_RETURNS_64BITS 281*1fd5a2e1SPrashanth Swaminathan 282*1fd5a2e1SPrashanth Swaminathan#if defined(__ppc64__) 283*1fd5a2e1SPrashanth SwaminathanL(maybe_return_128): 284*1fd5a2e1SPrashanth Swaminathan std r3,0(r30) 285*1fd5a2e1SPrashanth Swaminathan bf 31,L(done_return_value) ; not FLAG_RETURNS_128BITS 286*1fd5a2e1SPrashanth Swaminathan std r4,8(r30) 287*1fd5a2e1SPrashanth Swaminathan#else 288*1fd5a2e1SPrashanth Swaminathan stw r4,4(r30) 289*1fd5a2e1SPrashanth Swaminathan#endif 290*1fd5a2e1SPrashanth Swaminathan 291*1fd5a2e1SPrashanth Swaminathan /* Fall through. */ 292*1fd5a2e1SPrashanth Swaminathan /* We want this at the end to simplify eh epilog computation. */ 293*1fd5a2e1SPrashanth Swaminathan 294*1fd5a2e1SPrashanth SwaminathanL(done_return_value): 295*1fd5a2e1SPrashanth Swaminathan /* Restore the registers we used and return. */ 296*1fd5a2e1SPrashanth Swaminathan lg r29,SAVED_LR_OFFSET(r28) 297*1fd5a2e1SPrashanth Swaminathan ; epilog 298*1fd5a2e1SPrashanth Swaminathan lg r31,-(1 * GPR_BYTES)(r28) 299*1fd5a2e1SPrashanth Swaminathan mtlr r29 300*1fd5a2e1SPrashanth Swaminathan lg r30,-(2 * GPR_BYTES)(r28) 301*1fd5a2e1SPrashanth Swaminathan lg r29,-(3 * GPR_BYTES)(r28) 302*1fd5a2e1SPrashanth Swaminathan lg r28,-(4 * GPR_BYTES)(r28) 303*1fd5a2e1SPrashanth Swaminathan lg r1,0(r1) 304*1fd5a2e1SPrashanth Swaminathan blr 305*1fd5a2e1SPrashanth SwaminathanLFE1: 306*1fd5a2e1SPrashanth Swaminathan .align 1 307*1fd5a2e1SPrashanth Swaminathan/* END(_ffi_call_DARWIN) */ 308*1fd5a2e1SPrashanth Swaminathan 309*1fd5a2e1SPrashanth Swaminathan/* Provide a null definition of _ffi_call_AIX. */ 310*1fd5a2e1SPrashanth Swaminathan .text 311*1fd5a2e1SPrashanth Swaminathan .globl _ffi_call_AIX 312*1fd5a2e1SPrashanth Swaminathan .align 2 313*1fd5a2e1SPrashanth Swaminathan_ffi_call_AIX: 314*1fd5a2e1SPrashanth Swaminathan blr 315*1fd5a2e1SPrashanth Swaminathan/* END(_ffi_call_AIX) */ 316*1fd5a2e1SPrashanth Swaminathan 317*1fd5a2e1SPrashanth Swaminathan/* EH stuff. */ 318*1fd5a2e1SPrashanth Swaminathan 319*1fd5a2e1SPrashanth Swaminathan#define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78) 320*1fd5a2e1SPrashanth Swaminathan 321*1fd5a2e1SPrashanth Swaminathan .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support 322*1fd5a2e1SPrashanth SwaminathanEH_frame1: 323*1fd5a2e1SPrashanth Swaminathan .set L$set$0,LECIE1-LSCIE1 324*1fd5a2e1SPrashanth Swaminathan .long L$set$0 ; Length of Common Information Entry 325*1fd5a2e1SPrashanth SwaminathanLSCIE1: 326*1fd5a2e1SPrashanth Swaminathan .long 0x0 ; CIE Identifier Tag 327*1fd5a2e1SPrashanth Swaminathan .byte 0x1 ; CIE Version 328*1fd5a2e1SPrashanth Swaminathan .ascii "zR\0" ; CIE Augmentation 329*1fd5a2e1SPrashanth Swaminathan .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor 330*1fd5a2e1SPrashanth Swaminathan .byte EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor 331*1fd5a2e1SPrashanth Swaminathan .byte 0x41 ; CIE RA Column 332*1fd5a2e1SPrashanth Swaminathan .byte 0x1 ; uleb128 0x1; Augmentation size 333*1fd5a2e1SPrashanth Swaminathan .byte 0x10 ; FDE Encoding (pcrel) 334*1fd5a2e1SPrashanth Swaminathan .byte 0xc ; DW_CFA_def_cfa 335*1fd5a2e1SPrashanth Swaminathan .byte 0x1 ; uleb128 0x1 336*1fd5a2e1SPrashanth Swaminathan .byte 0x0 ; uleb128 0x0 337*1fd5a2e1SPrashanth Swaminathan .align LOG2_GPR_BYTES 338*1fd5a2e1SPrashanth SwaminathanLECIE1: 339*1fd5a2e1SPrashanth Swaminathan 340*1fd5a2e1SPrashanth Swaminathan .globl _ffi_call_DARWIN.eh 341*1fd5a2e1SPrashanth Swaminathan_ffi_call_DARWIN.eh: 342*1fd5a2e1SPrashanth SwaminathanLSFDE1: 343*1fd5a2e1SPrashanth Swaminathan .set L$set$1,LEFDE1-LASFDE1 344*1fd5a2e1SPrashanth Swaminathan .long L$set$1 ; FDE Length 345*1fd5a2e1SPrashanth SwaminathanLASFDE1: 346*1fd5a2e1SPrashanth Swaminathan .long LASFDE1-EH_frame1 ; FDE CIE offset 347*1fd5a2e1SPrashanth Swaminathan .g_long Lstartcode-. ; FDE initial location 348*1fd5a2e1SPrashanth Swaminathan .set L$set$3,LFE1-Lstartcode 349*1fd5a2e1SPrashanth Swaminathan .g_long L$set$3 ; FDE address range 350*1fd5a2e1SPrashanth Swaminathan .byte 0x0 ; uleb128 0x0; Augmentation size 351*1fd5a2e1SPrashanth Swaminathan .byte 0x4 ; DW_CFA_advance_loc4 352*1fd5a2e1SPrashanth Swaminathan .set L$set$4,LCFI0-Lstartcode 353*1fd5a2e1SPrashanth Swaminathan .long L$set$4 354*1fd5a2e1SPrashanth Swaminathan .byte 0xd ; DW_CFA_def_cfa_register 355*1fd5a2e1SPrashanth Swaminathan .byte 0x08 ; uleb128 0x08 356*1fd5a2e1SPrashanth Swaminathan .byte 0x4 ; DW_CFA_advance_loc4 357*1fd5a2e1SPrashanth Swaminathan .set L$set$5,LCFI1-LCFI0 358*1fd5a2e1SPrashanth Swaminathan .long L$set$5 359*1fd5a2e1SPrashanth Swaminathan .byte 0x11 ; DW_CFA_offset_extended_sf 360*1fd5a2e1SPrashanth Swaminathan .byte 0x41 ; uleb128 0x41 361*1fd5a2e1SPrashanth Swaminathan .byte 0x7e ; sleb128 -2 362*1fd5a2e1SPrashanth Swaminathan .byte 0x9f ; DW_CFA_offset, column 0x1f 363*1fd5a2e1SPrashanth Swaminathan .byte 0x1 ; uleb128 0x1 364*1fd5a2e1SPrashanth Swaminathan .byte 0x9e ; DW_CFA_offset, column 0x1e 365*1fd5a2e1SPrashanth Swaminathan .byte 0x2 ; uleb128 0x2 366*1fd5a2e1SPrashanth Swaminathan .byte 0x9d ; DW_CFA_offset, column 0x1d 367*1fd5a2e1SPrashanth Swaminathan .byte 0x3 ; uleb128 0x3 368*1fd5a2e1SPrashanth Swaminathan .byte 0x9c ; DW_CFA_offset, column 0x1c 369*1fd5a2e1SPrashanth Swaminathan .byte 0x4 ; uleb128 0x4 370*1fd5a2e1SPrashanth Swaminathan .byte 0x4 ; DW_CFA_advance_loc4 371*1fd5a2e1SPrashanth Swaminathan .set L$set$6,LCFI2-LCFI1 372*1fd5a2e1SPrashanth Swaminathan .long L$set$6 373*1fd5a2e1SPrashanth Swaminathan .byte 0xd ; DW_CFA_def_cfa_register 374*1fd5a2e1SPrashanth Swaminathan .byte 0x1c ; uleb128 0x1c 375*1fd5a2e1SPrashanth Swaminathan .align LOG2_GPR_BYTES 376*1fd5a2e1SPrashanth SwaminathanLEFDE1: 377*1fd5a2e1SPrashanth Swaminathan .align 1 378*1fd5a2e1SPrashanth Swaminathan 379