1d4c9320412177895f598a93d73a0e654db27c351Thomas Heller/* ----------------------------------------------------------------------- 2d4c9320412177895f598a93d73a0e654db27c351Thomas Heller darwin.S - Copyright (c) 2000 John Hornkvist 32a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com Copyright (c) 2004, 2010 Free Software Foundation, Inc. 4d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 5d4c9320412177895f598a93d73a0e654db27c351Thomas Heller PowerPC Assembly glue. 6d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 7d4c9320412177895f598a93d73a0e654db27c351Thomas Heller Permission is hereby granted, free of charge, to any person obtaining 8d4c9320412177895f598a93d73a0e654db27c351Thomas Heller a copy of this software and associated documentation files (the 9d4c9320412177895f598a93d73a0e654db27c351Thomas Heller ``Software''), to deal in the Software without restriction, including 10d4c9320412177895f598a93d73a0e654db27c351Thomas Heller without limitation the rights to use, copy, modify, merge, publish, 11d4c9320412177895f598a93d73a0e654db27c351Thomas Heller distribute, sublicense, and/or sell copies of the Software, and to 12d4c9320412177895f598a93d73a0e654db27c351Thomas Heller permit persons to whom the Software is furnished to do so, subject to 13d4c9320412177895f598a93d73a0e654db27c351Thomas Heller the following conditions: 14d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 15d4c9320412177895f598a93d73a0e654db27c351Thomas Heller The above copyright notice and this permission notice shall be included 16d4c9320412177895f598a93d73a0e654db27c351Thomas Heller in all copies or substantial portions of the Software. 17d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 18d4c9320412177895f598a93d73a0e654db27c351Thomas Heller THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 19d4c9320412177895f598a93d73a0e654db27c351Thomas Heller OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20d4c9320412177895f598a93d73a0e654db27c351Thomas Heller MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21d4c9320412177895f598a93d73a0e654db27c351Thomas Heller IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR 22d4c9320412177895f598a93d73a0e654db27c351Thomas Heller OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23d4c9320412177895f598a93d73a0e654db27c351Thomas Heller ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24d4c9320412177895f598a93d73a0e654db27c351Thomas Heller OTHER DEALINGS IN THE SOFTWARE. 25d4c9320412177895f598a93d73a0e654db27c351Thomas Heller ----------------------------------------------------------------------- */ 26d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 272a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define LIBFFI_ASM 28d4c9320412177895f598a93d73a0e654db27c351Thomas Heller#if defined(__ppc64__) 29d4c9320412177895f598a93d73a0e654db27c351Thomas Heller#define MODE_CHOICE(x, y) y 30d4c9320412177895f598a93d73a0e654db27c351Thomas Heller#else 31d4c9320412177895f598a93d73a0e654db27c351Thomas Heller#define MODE_CHOICE(x, y) x 32d4c9320412177895f598a93d73a0e654db27c351Thomas Heller#endif 33d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 342a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define machine_choice MODE_CHOICE(ppc7400,ppc64) 35d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 362a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com; Define some pseudo-opcodes for size-independent load & store of GPRs ... 372a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define lgu MODE_CHOICE(lwzu, ldu) 382a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define lg MODE_CHOICE(lwz,ld) 392a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define sg MODE_CHOICE(stw,std) 402a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define sgu MODE_CHOICE(stwu,stdu) 412a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define sgux MODE_CHOICE(stwux,stdux) 422a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 432a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com; ... and the size of GPRs and their storage indicator. 442a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define GPR_BYTES MODE_CHOICE(4,8) 452a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */ 462a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */ 472a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 482a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com; From the ABI doc: "Mac OS X ABI Function Call Guide" Version 2009-02-04. 492a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define LINKAGE_SIZE MODE_CHOICE(24,48) 502a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define PARAM_AREA MODE_CHOICE(32,64) 512a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define SAVED_LR_OFFSET MODE_CHOICE(8,16) /* save position for lr */ 522a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 532a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com/* If there is any FP stuff we make space for all of the regs. */ 542a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define SAVED_FPR_COUNT 13 552a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define FPR_SIZE 8 562a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define RESULT_BYTES 16 572a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 582a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com/* This should be kept in step with the same value in ffi_darwin.c. */ 592a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define ASM_NEEDS_REGISTERS 4 602a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define SAVE_REGS_SIZE (ASM_NEEDS_REGISTERS * GPR_BYTES) 61d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 62d4c9320412177895f598a93d73a0e654db27c351Thomas Heller#include <fficonfig.h> 63d4c9320412177895f598a93d73a0e654db27c351Thomas Heller#include <ffi.h> 642a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 65d4c9320412177895f598a93d73a0e654db27c351Thomas Heller#define JUMPTARGET(name) name 66d4c9320412177895f598a93d73a0e654db27c351Thomas Heller#define L(x) x 67d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 682a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com .text 69d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .align 2 702a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com .globl _ffi_prep_args 712a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 72d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .align 2 732a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com .globl _ffi_call_DARWIN 742a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 752a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* We arrive here with: 762a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com r3 = ptr to extended cif. 772a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com r4 = -bytes. 782a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com r5 = cif flags. 792a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com r6 = ptr to return value. 802a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com r7 = fn pointer (user func). 812a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com r8 = fn pointer (ffi_prep_args). 822a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com r9 = ffi_type* for the ret val. */ 832a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 84d4c9320412177895f598a93d73a0e654db27c351Thomas Heller_ffi_call_DARWIN: 852a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.comLstartcode: 86d4c9320412177895f598a93d73a0e654db27c351Thomas Heller mr r12,r8 /* We only need r12 until the call, 872a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com so it does not have to be saved. */ 88d4c9320412177895f598a93d73a0e654db27c351Thomas HellerLFB1: 89d4c9320412177895f598a93d73a0e654db27c351Thomas Heller /* Save the old stack pointer as AP. */ 90d4c9320412177895f598a93d73a0e654db27c351Thomas Heller mr r8,r1 91d4c9320412177895f598a93d73a0e654db27c351Thomas HellerLCFI0: 922a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 932a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* Save the retval type in parents frame. */ 942a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r9,(LINKAGE_SIZE+6*GPR_BYTES)(r8) 952a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 96d4c9320412177895f598a93d73a0e654db27c351Thomas Heller /* Allocate the stack space we need. */ 972a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sgux r1,r1,r4 98d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 99d4c9320412177895f598a93d73a0e654db27c351Thomas Heller /* Save registers we use. */ 100d4c9320412177895f598a93d73a0e654db27c351Thomas Heller mflr r9 1012a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r9,SAVED_LR_OFFSET(r8) 1022a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 1032a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r28,-(4 * GPR_BYTES)(r8) 1042a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r29,-(3 * GPR_BYTES)(r8) 1052a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r30,-(2 * GPR_BYTES)(r8) 1062a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r31,-( GPR_BYTES)(r8) 107d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 1082a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#if !defined(POWERPC_DARWIN) 1092a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* The TOC slot is reserved in the Darwin ABI and r2 is volatile. */ 1102a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r2,(5 * GPR_BYTES)(r1) 1112a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#endif 112d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 113d4c9320412177895f598a93d73a0e654db27c351Thomas HellerLCFI1: 114d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 115d4c9320412177895f598a93d73a0e654db27c351Thomas Heller /* Save arguments over call. */ 116d4c9320412177895f598a93d73a0e654db27c351Thomas Heller mr r31,r5 /* flags, */ 117d4c9320412177895f598a93d73a0e654db27c351Thomas Heller mr r30,r6 /* rvalue, */ 118d4c9320412177895f598a93d73a0e654db27c351Thomas Heller mr r29,r7 /* function address, */ 119d4c9320412177895f598a93d73a0e654db27c351Thomas Heller mr r28,r8 /* our AP. */ 120d4c9320412177895f598a93d73a0e654db27c351Thomas HellerLCFI2: 1212a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* Call ffi_prep_args. r3 = extended cif, r4 = stack ptr copy. */ 122d4c9320412177895f598a93d73a0e654db27c351Thomas Heller mr r4,r1 123d4c9320412177895f598a93d73a0e654db27c351Thomas Heller li r9,0 124d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 125d4c9320412177895f598a93d73a0e654db27c351Thomas Heller mtctr r12 /* r12 holds address of _ffi_prep_args. */ 126d4c9320412177895f598a93d73a0e654db27c351Thomas Heller bctrl 127d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 1282a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#if !defined(POWERPC_DARWIN) 1292a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* The TOC slot is reserved in the Darwin ABI and r2 is volatile. */ 1302a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r2,(5 * GPR_BYTES)(r1) 1312a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#endif 132d4c9320412177895f598a93d73a0e654db27c351Thomas Heller /* Now do the call. 133d4c9320412177895f598a93d73a0e654db27c351Thomas Heller Set up cr1 with bits 4-7 of the flags. */ 134d4c9320412177895f598a93d73a0e654db27c351Thomas Heller mtcrf 0x40,r31 135d4c9320412177895f598a93d73a0e654db27c351Thomas Heller /* Get the address to call into CTR. */ 136d4c9320412177895f598a93d73a0e654db27c351Thomas Heller mtctr r29 137d4c9320412177895f598a93d73a0e654db27c351Thomas Heller /* Load all those argument registers. 138d4c9320412177895f598a93d73a0e654db27c351Thomas Heller We have set up a nice stack frame, just load it into registers. */ 1392a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r3, (LINKAGE_SIZE )(r1) 1402a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r4, (LINKAGE_SIZE + GPR_BYTES)(r1) 1412a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r5, (LINKAGE_SIZE + 2 * GPR_BYTES)(r1) 1422a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r6, (LINKAGE_SIZE + 3 * GPR_BYTES)(r1) 143d4c9320412177895f598a93d73a0e654db27c351Thomas Heller nop 1442a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r7, (LINKAGE_SIZE + 4 * GPR_BYTES)(r1) 1452a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r8, (LINKAGE_SIZE + 5 * GPR_BYTES)(r1) 1462a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r9, (LINKAGE_SIZE + 6 * GPR_BYTES)(r1) 1472a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r10,(LINKAGE_SIZE + 7 * GPR_BYTES)(r1) 148d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 149d4c9320412177895f598a93d73a0e654db27c351Thomas HellerL1: 1502a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* ... Load all the FP registers. */ 151d4c9320412177895f598a93d73a0e654db27c351Thomas Heller bf 6,L2 /* No floats to load. */ 1522a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lfd f1, -SAVE_REGS_SIZE-(13*FPR_SIZE)(r28) 1532a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lfd f2, -SAVE_REGS_SIZE-(12*FPR_SIZE)(r28) 1542a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lfd f3, -SAVE_REGS_SIZE-(11*FPR_SIZE)(r28) 1552a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lfd f4, -SAVE_REGS_SIZE-(10*FPR_SIZE)(r28) 156d4c9320412177895f598a93d73a0e654db27c351Thomas Heller nop 1572a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lfd f5, -SAVE_REGS_SIZE-( 9*FPR_SIZE)(r28) 1582a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lfd f6, -SAVE_REGS_SIZE-( 8*FPR_SIZE)(r28) 1592a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lfd f7, -SAVE_REGS_SIZE-( 7*FPR_SIZE)(r28) 1602a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lfd f8, -SAVE_REGS_SIZE-( 6*FPR_SIZE)(r28) 161d4c9320412177895f598a93d73a0e654db27c351Thomas Heller nop 1622a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lfd f9, -SAVE_REGS_SIZE-( 5*FPR_SIZE)(r28) 1632a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lfd f10,-SAVE_REGS_SIZE-( 4*FPR_SIZE)(r28) 1642a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lfd f11,-SAVE_REGS_SIZE-( 3*FPR_SIZE)(r28) 1652a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lfd f12,-SAVE_REGS_SIZE-( 2*FPR_SIZE)(r28) 166d4c9320412177895f598a93d73a0e654db27c351Thomas Heller nop 1672a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lfd f13,-SAVE_REGS_SIZE-( 1*FPR_SIZE)(r28) 168d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 169d4c9320412177895f598a93d73a0e654db27c351Thomas HellerL2: 170d4c9320412177895f598a93d73a0e654db27c351Thomas Heller mr r12,r29 /* Put the target address in r12 as specified. */ 171d4c9320412177895f598a93d73a0e654db27c351Thomas Heller mtctr r12 172d4c9320412177895f598a93d73a0e654db27c351Thomas Heller nop 173d4c9320412177895f598a93d73a0e654db27c351Thomas Heller nop 1742a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 175d4c9320412177895f598a93d73a0e654db27c351Thomas Heller /* Make the call. */ 176d4c9320412177895f598a93d73a0e654db27c351Thomas Heller bctrl 177d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 178d4c9320412177895f598a93d73a0e654db27c351Thomas Heller /* Now, deal with the return value. */ 179d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 1802a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* m64 structure returns can occupy the same set of registers as 1812a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com would be used to pass such a structure as arg0 - so take care 1822a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com not to step on any possibly hot regs. */ 183d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 1842a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* Get the flags.. */ 1852a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com mtcrf 0x03,r31 ; we need c6 & cr7 now. 1862a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com ; FLAG_RETURNS_NOTHING also covers struct ret-by-ref. 1872a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com bt 30,L(done_return_value) ; FLAG_RETURNS_NOTHING 1882a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com bf 27,L(scalar_return_value) ; not FLAG_RETURNS_STRUCT 1892a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 1902a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* OK, so we have a struct. */ 1912a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#if defined(__ppc64__) 1922a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com bt 31,L(maybe_return_128) ; FLAG_RETURNS_128BITS, special case 193d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 1942a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* OK, we have to map the return back to a mem struct. 1952a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com We are about to trample the parents param area, so recover the 1962a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com return type. r29 is free, since the call is done. */ 1972a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r29,(LINKAGE_SIZE + 6 * GPR_BYTES)(r28) 1982a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 1992a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r3, (LINKAGE_SIZE )(r28) 2002a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r4, (LINKAGE_SIZE + GPR_BYTES)(r28) 2012a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r5, (LINKAGE_SIZE + 2 * GPR_BYTES)(r28) 2022a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r6, (LINKAGE_SIZE + 3 * GPR_BYTES)(r28) 2032a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com nop 2042a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r7, (LINKAGE_SIZE + 4 * GPR_BYTES)(r28) 2052a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r8, (LINKAGE_SIZE + 5 * GPR_BYTES)(r28) 2062a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r9, (LINKAGE_SIZE + 6 * GPR_BYTES)(r28) 2072a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r10,(LINKAGE_SIZE + 7 * GPR_BYTES)(r28) 2082a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* OK, so do the block move - we trust that memcpy will not trample 2092a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com the fprs... */ 2102a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com mr r3,r30 ; dest 2112a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com addi r4,r28,LINKAGE_SIZE ; source 2122a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* The size is a size_t, should be long. */ 2132a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r5,0(r29) 2142a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* Figure out small structs */ 2152a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com cmpi 0,r5,4 2162a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com bgt L3 ; 1, 2 and 4 bytes have special rules. 2172a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com cmpi 0,r5,3 2182a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com beq L3 ; not 3 2192a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com addi r4,r4,8 2202a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com subf r4,r5,r4 2212a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.comL3: 2222a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com bl _memcpy 2232a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 2242a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* ... do we need the FP registers? - recover the flags.. */ 2252a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com mtcrf 0x03,r31 ; we need c6 & cr7 now. 2262a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com bf 29,L(done_return_value) /* No floats in the struct. */ 2272a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com stfd f1, -SAVE_REGS_SIZE-(13*FPR_SIZE)(r28) 2282a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com stfd f2, -SAVE_REGS_SIZE-(12*FPR_SIZE)(r28) 2292a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com stfd f3, -SAVE_REGS_SIZE-(11*FPR_SIZE)(r28) 2302a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com stfd f4, -SAVE_REGS_SIZE-(10*FPR_SIZE)(r28) 2312a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com nop 2322a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com stfd f5, -SAVE_REGS_SIZE-( 9*FPR_SIZE)(r28) 2332a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com stfd f6, -SAVE_REGS_SIZE-( 8*FPR_SIZE)(r28) 2342a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com stfd f7, -SAVE_REGS_SIZE-( 7*FPR_SIZE)(r28) 2352a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com stfd f8, -SAVE_REGS_SIZE-( 6*FPR_SIZE)(r28) 2362a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com nop 2372a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com stfd f9, -SAVE_REGS_SIZE-( 5*FPR_SIZE)(r28) 2382a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com stfd f10,-SAVE_REGS_SIZE-( 4*FPR_SIZE)(r28) 2392a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com stfd f11,-SAVE_REGS_SIZE-( 3*FPR_SIZE)(r28) 2402a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com stfd f12,-SAVE_REGS_SIZE-( 2*FPR_SIZE)(r28) 2412a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com nop 2422a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com stfd f13,-SAVE_REGS_SIZE-( 1*FPR_SIZE)(r28) 2432a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 2442a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com mr r3,r29 ; ffi_type * 2452a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com mr r4,r30 ; dest 2462a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com addi r5,r28,-SAVE_REGS_SIZE-(13*FPR_SIZE) ; fprs 2472a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com xor r6,r6,r6 2482a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r6,(LINKAGE_SIZE + 7 * GPR_BYTES)(r28) 2492a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com addi r6,r28,(LINKAGE_SIZE + 7 * GPR_BYTES) ; point to a zeroed counter. 2502a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com bl _darwin64_struct_floats_to_mem 2512a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 2522a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com b L(done_return_value) 2532a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#else 2542a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com stw r3,0(r30) ; m32 the only struct return in reg is 4 bytes. 2552a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#endif 2562a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com b L(done_return_value) 257d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 258d4c9320412177895f598a93d73a0e654db27c351Thomas HellerL(fp_return_value): 259d4c9320412177895f598a93d73a0e654db27c351Thomas Heller /* Do we have long double to store? */ 2602a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com bf 31,L(fd_return_value) ; FLAG_RETURNS_128BITS 261d4c9320412177895f598a93d73a0e654db27c351Thomas Heller stfd f1,0(r30) 2622a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com stfd f2,FPR_SIZE(r30) 263d4c9320412177895f598a93d73a0e654db27c351Thomas Heller b L(done_return_value) 264d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 265d4c9320412177895f598a93d73a0e654db27c351Thomas HellerL(fd_return_value): 266d4c9320412177895f598a93d73a0e654db27c351Thomas Heller /* Do we have double to store? */ 267d4c9320412177895f598a93d73a0e654db27c351Thomas Heller bf 28,L(float_return_value) 268d4c9320412177895f598a93d73a0e654db27c351Thomas Heller stfd f1,0(r30) 269d4c9320412177895f598a93d73a0e654db27c351Thomas Heller b L(done_return_value) 270d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 271d4c9320412177895f598a93d73a0e654db27c351Thomas HellerL(float_return_value): 272d4c9320412177895f598a93d73a0e654db27c351Thomas Heller /* We only have a float to store. */ 273d4c9320412177895f598a93d73a0e654db27c351Thomas Heller stfs f1,0(r30) 274d4c9320412177895f598a93d73a0e654db27c351Thomas Heller b L(done_return_value) 275d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 2762a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.comL(scalar_return_value): 2772a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com bt 29,L(fp_return_value) ; FLAG_RETURNS_FP 2782a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com ; ffi_arg is defined as unsigned long. 2792a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com sg r3,0(r30) ; Save the reg. 2802a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com bf 28,L(done_return_value) ; not FLAG_RETURNS_64BITS 2812a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 2822a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#if defined(__ppc64__) 2832a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.comL(maybe_return_128): 2842a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com std r3,0(r30) 2852a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com bf 31,L(done_return_value) ; not FLAG_RETURNS_128BITS 2862a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com std r4,8(r30) 2872a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#else 2882a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com stw r4,4(r30) 2892a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#endif 2902a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 2912a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* Fall through. */ 2922a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* We want this at the end to simplify eh epilog computation. */ 2932a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 2942a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.comL(done_return_value): 2952a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com /* Restore the registers we used and return. */ 2962a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r29,SAVED_LR_OFFSET(r28) 2972a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com ; epilog 2982a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r31,-(1 * GPR_BYTES)(r28) 2992a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com mtlr r29 3002a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r30,-(2 * GPR_BYTES)(r28) 3012a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r29,-(3 * GPR_BYTES)(r28) 3022a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r28,-(4 * GPR_BYTES)(r28) 3032a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com lg r1,0(r1) 3042a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com blr 305d4c9320412177895f598a93d73a0e654db27c351Thomas HellerLFE1: 3062a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com .align 1 307d4c9320412177895f598a93d73a0e654db27c351Thomas Heller/* END(_ffi_call_DARWIN) */ 308d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 309d4c9320412177895f598a93d73a0e654db27c351Thomas Heller/* Provide a null definition of _ffi_call_AIX. */ 3102a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com .text 3112a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com .globl _ffi_call_AIX 312d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .align 2 313d4c9320412177895f598a93d73a0e654db27c351Thomas Heller_ffi_call_AIX: 314d4c9320412177895f598a93d73a0e654db27c351Thomas Heller blr 315d4c9320412177895f598a93d73a0e654db27c351Thomas Heller/* END(_ffi_call_AIX) */ 316d4c9320412177895f598a93d73a0e654db27c351Thomas Heller 3172a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com/* EH stuff. */ 3182a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 3192a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com#define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78) 3202a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 3212a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support 322d4c9320412177895f598a93d73a0e654db27c351Thomas HellerEH_frame1: 323d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .set L$set$0,LECIE1-LSCIE1 324d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .long L$set$0 ; Length of Common Information Entry 325d4c9320412177895f598a93d73a0e654db27c351Thomas HellerLSCIE1: 326d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .long 0x0 ; CIE Identifier Tag 327d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x1 ; CIE Version 328d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .ascii "zR\0" ; CIE Augmentation 329d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor 3302a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com .byte EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor 331d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x41 ; CIE RA Column 332d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x1 ; uleb128 0x1; Augmentation size 333736a9133219ec75524d90a976d2e35c76d544b6edoko@ubuntu.com .byte 0x10 ; FDE Encoding (pcrel) 334d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0xc ; DW_CFA_def_cfa 335d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x1 ; uleb128 0x1 336d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x0 ; uleb128 0x0 337d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .align LOG2_GPR_BYTES 338d4c9320412177895f598a93d73a0e654db27c351Thomas HellerLECIE1: 3392a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 3402a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com .globl _ffi_call_DARWIN.eh 341d4c9320412177895f598a93d73a0e654db27c351Thomas Heller_ffi_call_DARWIN.eh: 342d4c9320412177895f598a93d73a0e654db27c351Thomas HellerLSFDE1: 343d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .set L$set$1,LEFDE1-LASFDE1 344d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .long L$set$1 ; FDE Length 345d4c9320412177895f598a93d73a0e654db27c351Thomas HellerLASFDE1: 346d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .long LASFDE1-EH_frame1 ; FDE CIE offset 347736a9133219ec75524d90a976d2e35c76d544b6edoko@ubuntu.com .g_long Lstartcode-. ; FDE initial location 3482a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com .set L$set$3,LFE1-Lstartcode 349d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .g_long L$set$3 ; FDE address range 350d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x0 ; uleb128 0x0; Augmentation size 351d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x4 ; DW_CFA_advance_loc4 3522a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com .set L$set$4,LCFI0-Lstartcode 353d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .long L$set$4 354d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0xd ; DW_CFA_def_cfa_register 355d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x08 ; uleb128 0x08 356d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x4 ; DW_CFA_advance_loc4 357d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .set L$set$5,LCFI1-LCFI0 358d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .long L$set$5 359d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x11 ; DW_CFA_offset_extended_sf 360d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x41 ; uleb128 0x41 361d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x7e ; sleb128 -2 362d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x9f ; DW_CFA_offset, column 0x1f 363d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x1 ; uleb128 0x1 364d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x9e ; DW_CFA_offset, column 0x1e 365d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x2 ; uleb128 0x2 366d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x9d ; DW_CFA_offset, column 0x1d 367d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x3 ; uleb128 0x3 368d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x9c ; DW_CFA_offset, column 0x1c 369d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x4 ; uleb128 0x4 370d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x4 ; DW_CFA_advance_loc4 371d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .set L$set$6,LCFI2-LCFI1 372d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .long L$set$6 373d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0xd ; DW_CFA_def_cfa_register 374d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .byte 0x1c ; uleb128 0x1c 375d4c9320412177895f598a93d73a0e654db27c351Thomas Heller .align LOG2_GPR_BYTES 376d4c9320412177895f598a93d73a0e654db27c351Thomas HellerLEFDE1: 3772a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com .align 1 3782a918768f1825d4a1f1e5f11674614c74176aa5ddoko@ubuntu.com 379