1*1fd5a2e1SPrashanth Swaminathan/* ----------------------------------------------------------------------- 2*1fd5a2e1SPrashanth Swaminathan sysv.S - Copyright (c) 1998 Geoffrey Keating 3*1fd5a2e1SPrashanth Swaminathan Copyright (C) 2007 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, 19*1fd5a2e1SPrashanth Swaminathan EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20*1fd5a2e1SPrashanth Swaminathan MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21*1fd5a2e1SPrashanth Swaminathan NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22*1fd5a2e1SPrashanth Swaminathan HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23*1fd5a2e1SPrashanth Swaminathan WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24*1fd5a2e1SPrashanth Swaminathan OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25*1fd5a2e1SPrashanth Swaminathan DEALINGS IN THE SOFTWARE. 26*1fd5a2e1SPrashanth Swaminathan ----------------------------------------------------------------------- */ 27*1fd5a2e1SPrashanth Swaminathan 28*1fd5a2e1SPrashanth Swaminathan#define LIBFFI_ASM 29*1fd5a2e1SPrashanth Swaminathan#include <fficonfig.h> 30*1fd5a2e1SPrashanth Swaminathan#include <ffi.h> 31*1fd5a2e1SPrashanth Swaminathan#include <powerpc/asm.h> 32*1fd5a2e1SPrashanth Swaminathan 33*1fd5a2e1SPrashanth Swaminathan#ifndef POWERPC64 34*1fd5a2e1SPrashanth SwaminathanFFI_HIDDEN(ffi_call_SYSV) 35*1fd5a2e1SPrashanth SwaminathanENTRY(ffi_call_SYSV) 36*1fd5a2e1SPrashanth Swaminathan .cfi_startproc 37*1fd5a2e1SPrashanth Swaminathan /* Save the old stack pointer as AP. */ 38*1fd5a2e1SPrashanth Swaminathan mr %r10,%r1 39*1fd5a2e1SPrashanth Swaminathan .cfi_def_cfa_register 10 40*1fd5a2e1SPrashanth Swaminathan 41*1fd5a2e1SPrashanth Swaminathan /* Allocate the stack space we need. */ 42*1fd5a2e1SPrashanth Swaminathan stwux %r1,%r1,%r8 43*1fd5a2e1SPrashanth Swaminathan /* Save registers we use. */ 44*1fd5a2e1SPrashanth Swaminathan mflr %r9 45*1fd5a2e1SPrashanth Swaminathan stw %r28,-16(%r10) 46*1fd5a2e1SPrashanth Swaminathan stw %r29,-12(%r10) 47*1fd5a2e1SPrashanth Swaminathan stw %r30, -8(%r10) 48*1fd5a2e1SPrashanth Swaminathan stw %r31, -4(%r10) 49*1fd5a2e1SPrashanth Swaminathan stw %r9, 4(%r10) 50*1fd5a2e1SPrashanth Swaminathan .cfi_offset 65, 4 51*1fd5a2e1SPrashanth Swaminathan .cfi_offset 31, -4 52*1fd5a2e1SPrashanth Swaminathan .cfi_offset 30, -8 53*1fd5a2e1SPrashanth Swaminathan .cfi_offset 29, -12 54*1fd5a2e1SPrashanth Swaminathan .cfi_offset 28, -16 55*1fd5a2e1SPrashanth Swaminathan 56*1fd5a2e1SPrashanth Swaminathan /* Save arguments over call... */ 57*1fd5a2e1SPrashanth Swaminathan stw %r7, -20(%r10) /* closure, */ 58*1fd5a2e1SPrashanth Swaminathan mr %r31,%r6 /* flags, */ 59*1fd5a2e1SPrashanth Swaminathan mr %r30,%r5 /* rvalue, */ 60*1fd5a2e1SPrashanth Swaminathan mr %r29,%r4 /* function address, */ 61*1fd5a2e1SPrashanth Swaminathan mr %r28,%r10 /* our AP. */ 62*1fd5a2e1SPrashanth Swaminathan .cfi_def_cfa_register 28 63*1fd5a2e1SPrashanth Swaminathan 64*1fd5a2e1SPrashanth Swaminathan /* Call ffi_prep_args_SYSV. */ 65*1fd5a2e1SPrashanth Swaminathan mr %r4,%r1 66*1fd5a2e1SPrashanth Swaminathan bl ffi_prep_args_SYSV@local 67*1fd5a2e1SPrashanth Swaminathan 68*1fd5a2e1SPrashanth Swaminathan /* Now do the call. */ 69*1fd5a2e1SPrashanth Swaminathan /* Set up cr1 with bits 4-7 of the flags. */ 70*1fd5a2e1SPrashanth Swaminathan mtcrf 0x40,%r31 71*1fd5a2e1SPrashanth Swaminathan /* Get the address to call into CTR. */ 72*1fd5a2e1SPrashanth Swaminathan mtctr %r29 73*1fd5a2e1SPrashanth Swaminathan /* Load all those argument registers. */ 74*1fd5a2e1SPrashanth Swaminathan lwz %r3,-24-(8*4)(%r28) 75*1fd5a2e1SPrashanth Swaminathan lwz %r4,-24-(7*4)(%r28) 76*1fd5a2e1SPrashanth Swaminathan lwz %r5,-24-(6*4)(%r28) 77*1fd5a2e1SPrashanth Swaminathan lwz %r6,-24-(5*4)(%r28) 78*1fd5a2e1SPrashanth Swaminathan bf- 5,1f 79*1fd5a2e1SPrashanth Swaminathan nop 80*1fd5a2e1SPrashanth Swaminathan lwz %r7,-24-(4*4)(%r28) 81*1fd5a2e1SPrashanth Swaminathan lwz %r8,-24-(3*4)(%r28) 82*1fd5a2e1SPrashanth Swaminathan lwz %r9,-24-(2*4)(%r28) 83*1fd5a2e1SPrashanth Swaminathan lwz %r10,-24-(1*4)(%r28) 84*1fd5a2e1SPrashanth Swaminathan nop 85*1fd5a2e1SPrashanth Swaminathan1: 86*1fd5a2e1SPrashanth Swaminathan 87*1fd5a2e1SPrashanth Swaminathan#ifndef __NO_FPRS__ 88*1fd5a2e1SPrashanth Swaminathan /* Load all the FP registers. */ 89*1fd5a2e1SPrashanth Swaminathan bf- 6,2f 90*1fd5a2e1SPrashanth Swaminathan lfd %f1,-24-(8*4)-(8*8)(%r28) 91*1fd5a2e1SPrashanth Swaminathan lfd %f2,-24-(8*4)-(7*8)(%r28) 92*1fd5a2e1SPrashanth Swaminathan lfd %f3,-24-(8*4)-(6*8)(%r28) 93*1fd5a2e1SPrashanth Swaminathan lfd %f4,-24-(8*4)-(5*8)(%r28) 94*1fd5a2e1SPrashanth Swaminathan nop 95*1fd5a2e1SPrashanth Swaminathan lfd %f5,-24-(8*4)-(4*8)(%r28) 96*1fd5a2e1SPrashanth Swaminathan lfd %f6,-24-(8*4)-(3*8)(%r28) 97*1fd5a2e1SPrashanth Swaminathan lfd %f7,-24-(8*4)-(2*8)(%r28) 98*1fd5a2e1SPrashanth Swaminathan lfd %f8,-24-(8*4)-(1*8)(%r28) 99*1fd5a2e1SPrashanth Swaminathan#endif 100*1fd5a2e1SPrashanth Swaminathan2: 101*1fd5a2e1SPrashanth Swaminathan 102*1fd5a2e1SPrashanth Swaminathan /* Make the call. */ 103*1fd5a2e1SPrashanth Swaminathan lwz %r11, -20(%r28) 104*1fd5a2e1SPrashanth Swaminathan bctrl 105*1fd5a2e1SPrashanth Swaminathan 106*1fd5a2e1SPrashanth Swaminathan /* Now, deal with the return value. */ 107*1fd5a2e1SPrashanth Swaminathan mtcrf 0x01,%r31 /* cr7 */ 108*1fd5a2e1SPrashanth Swaminathan bt- 31,L(small_struct_return_value) 109*1fd5a2e1SPrashanth Swaminathan bt- 30,L(done_return_value) 110*1fd5a2e1SPrashanth Swaminathan#ifndef __NO_FPRS__ 111*1fd5a2e1SPrashanth Swaminathan bt- 29,L(fp_return_value) 112*1fd5a2e1SPrashanth Swaminathan#endif 113*1fd5a2e1SPrashanth Swaminathan stw %r3,0(%r30) 114*1fd5a2e1SPrashanth Swaminathan bf+ 28,L(done_return_value) 115*1fd5a2e1SPrashanth Swaminathan stw %r4,4(%r30) 116*1fd5a2e1SPrashanth Swaminathan mtcrf 0x02,%r31 /* cr6 */ 117*1fd5a2e1SPrashanth Swaminathan bf 27,L(done_return_value) 118*1fd5a2e1SPrashanth Swaminathan stw %r5,8(%r30) 119*1fd5a2e1SPrashanth Swaminathan stw %r6,12(%r30) 120*1fd5a2e1SPrashanth Swaminathan /* Fall through... */ 121*1fd5a2e1SPrashanth Swaminathan 122*1fd5a2e1SPrashanth SwaminathanL(done_return_value): 123*1fd5a2e1SPrashanth Swaminathan /* Restore the registers we used and return. */ 124*1fd5a2e1SPrashanth Swaminathan lwz %r9, 4(%r28) 125*1fd5a2e1SPrashanth Swaminathan lwz %r31, -4(%r28) 126*1fd5a2e1SPrashanth Swaminathan mtlr %r9 127*1fd5a2e1SPrashanth Swaminathan lwz %r30, -8(%r28) 128*1fd5a2e1SPrashanth Swaminathan lwz %r29,-12(%r28) 129*1fd5a2e1SPrashanth Swaminathan lwz %r28,-16(%r28) 130*1fd5a2e1SPrashanth Swaminathan .cfi_remember_state 131*1fd5a2e1SPrashanth Swaminathan /* At this point we don't have a cfa register. Say all our 132*1fd5a2e1SPrashanth Swaminathan saved regs have been restored. */ 133*1fd5a2e1SPrashanth Swaminathan .cfi_same_value 65 134*1fd5a2e1SPrashanth Swaminathan .cfi_same_value 31 135*1fd5a2e1SPrashanth Swaminathan .cfi_same_value 30 136*1fd5a2e1SPrashanth Swaminathan .cfi_same_value 29 137*1fd5a2e1SPrashanth Swaminathan .cfi_same_value 28 138*1fd5a2e1SPrashanth Swaminathan /* Hopefully this works.. */ 139*1fd5a2e1SPrashanth Swaminathan .cfi_def_cfa_register 1 140*1fd5a2e1SPrashanth Swaminathan .cfi_offset 1, 0 141*1fd5a2e1SPrashanth Swaminathan lwz %r1,0(%r1) 142*1fd5a2e1SPrashanth Swaminathan .cfi_same_value 1 143*1fd5a2e1SPrashanth Swaminathan blr 144*1fd5a2e1SPrashanth Swaminathan 145*1fd5a2e1SPrashanth Swaminathan#ifndef __NO_FPRS__ 146*1fd5a2e1SPrashanth SwaminathanL(fp_return_value): 147*1fd5a2e1SPrashanth Swaminathan .cfi_restore_state 148*1fd5a2e1SPrashanth Swaminathan bf 28,L(float_return_value) 149*1fd5a2e1SPrashanth Swaminathan stfd %f1,0(%r30) 150*1fd5a2e1SPrashanth Swaminathan mtcrf 0x02,%r31 /* cr6 */ 151*1fd5a2e1SPrashanth Swaminathan bf 27,L(done_return_value) 152*1fd5a2e1SPrashanth Swaminathan stfd %f2,8(%r30) 153*1fd5a2e1SPrashanth Swaminathan b L(done_return_value) 154*1fd5a2e1SPrashanth SwaminathanL(float_return_value): 155*1fd5a2e1SPrashanth Swaminathan stfs %f1,0(%r30) 156*1fd5a2e1SPrashanth Swaminathan b L(done_return_value) 157*1fd5a2e1SPrashanth Swaminathan#endif 158*1fd5a2e1SPrashanth Swaminathan 159*1fd5a2e1SPrashanth SwaminathanL(small_struct_return_value): 160*1fd5a2e1SPrashanth Swaminathan /* 161*1fd5a2e1SPrashanth Swaminathan * The C code always allocates a properly-aligned 8-byte bounce 162*1fd5a2e1SPrashanth Swaminathan * buffer to make this assembly code very simple. Just write out 163*1fd5a2e1SPrashanth Swaminathan * r3 and r4 to the buffer to allow the C code to handle the rest. 164*1fd5a2e1SPrashanth Swaminathan */ 165*1fd5a2e1SPrashanth Swaminathan stw %r3, 0(%r30) 166*1fd5a2e1SPrashanth Swaminathan stw %r4, 4(%r30) 167*1fd5a2e1SPrashanth Swaminathan b L(done_return_value) 168*1fd5a2e1SPrashanth Swaminathan .cfi_endproc 169*1fd5a2e1SPrashanth Swaminathan 170*1fd5a2e1SPrashanth SwaminathanEND(ffi_call_SYSV) 171*1fd5a2e1SPrashanth Swaminathan 172*1fd5a2e1SPrashanth Swaminathan#if defined __ELF__ && defined __linux__ 173*1fd5a2e1SPrashanth Swaminathan .section .note.GNU-stack,"",@progbits 174*1fd5a2e1SPrashanth Swaminathan#endif 175*1fd5a2e1SPrashanth Swaminathan#endif 176