1*1fd5a2e1SPrashanth Swaminathan/* ----------------------------------------------------------------------- 2*1fd5a2e1SPrashanth Swaminathan sysv.S - Copyright (c) 2012 Alexandre K. I. de Mendonca <[email protected]>, 3*1fd5a2e1SPrashanth Swaminathan Paulo Pizarro <[email protected]> 4*1fd5a2e1SPrashanth Swaminathan 5*1fd5a2e1SPrashanth Swaminathan Blackfin Foreign Function Interface 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 32*1fd5a2e1SPrashanth Swaminathan.text 33*1fd5a2e1SPrashanth Swaminathan.align 4 34*1fd5a2e1SPrashanth Swaminathan 35*1fd5a2e1SPrashanth Swaminathan /* 36*1fd5a2e1SPrashanth Swaminathan There is a "feature" in the bfin toolchain that it puts a _ before function names 37*1fd5a2e1SPrashanth Swaminathan that's why the function here it's called _ffi_call_SYSV and not ffi_call_SYSV 38*1fd5a2e1SPrashanth Swaminathan */ 39*1fd5a2e1SPrashanth Swaminathan .global _ffi_call_SYSV; 40*1fd5a2e1SPrashanth Swaminathan .type _ffi_call_SYSV, STT_FUNC; 41*1fd5a2e1SPrashanth Swaminathan .func ffi_call_SYSV 42*1fd5a2e1SPrashanth Swaminathan 43*1fd5a2e1SPrashanth Swaminathan /* 44*1fd5a2e1SPrashanth Swaminathan cif->bytes = R0 (fp+8) 45*1fd5a2e1SPrashanth Swaminathan &ecif = R1 (fp+12) 46*1fd5a2e1SPrashanth Swaminathan ffi_prep_args = R2 (fp+16) 47*1fd5a2e1SPrashanth Swaminathan ret_type = stack (fp+20) 48*1fd5a2e1SPrashanth Swaminathan ecif.rvalue = stack (fp+24) 49*1fd5a2e1SPrashanth Swaminathan fn = stack (fp+28) 50*1fd5a2e1SPrashanth Swaminathan got (fp+32) 51*1fd5a2e1SPrashanth Swaminathan 52*1fd5a2e1SPrashanth Swaminathan There is room for improvement here (we can use temporary registers 53*1fd5a2e1SPrashanth Swaminathan instead of saving the values in the memory) 54*1fd5a2e1SPrashanth Swaminathan REGS: 55*1fd5a2e1SPrashanth Swaminathan P5 => Stack pointer (function arguments) 56*1fd5a2e1SPrashanth Swaminathan R5 => cif->bytes 57*1fd5a2e1SPrashanth Swaminathan R4 => ret->type 58*1fd5a2e1SPrashanth Swaminathan 59*1fd5a2e1SPrashanth Swaminathan FP-20 = P3 60*1fd5a2e1SPrashanth Swaminathan FP-16 = SP (parameters area) 61*1fd5a2e1SPrashanth Swaminathan FP-12 = SP (temp) 62*1fd5a2e1SPrashanth Swaminathan FP-08 = function return part 1 [R0] 63*1fd5a2e1SPrashanth Swaminathan FP-04 = function return part 2 [R1] 64*1fd5a2e1SPrashanth Swaminathan */ 65*1fd5a2e1SPrashanth Swaminathan 66*1fd5a2e1SPrashanth Swaminathan_ffi_call_SYSV: 67*1fd5a2e1SPrashanth Swaminathan.prologue: 68*1fd5a2e1SPrashanth Swaminathan LINK 20; 69*1fd5a2e1SPrashanth Swaminathan [FP-20] = P3; 70*1fd5a2e1SPrashanth Swaminathan [FP+8] = R0; 71*1fd5a2e1SPrashanth Swaminathan [FP+12] = R1; 72*1fd5a2e1SPrashanth Swaminathan [FP+16] = R2; 73*1fd5a2e1SPrashanth Swaminathan 74*1fd5a2e1SPrashanth Swaminathan.allocate_stack: 75*1fd5a2e1SPrashanth Swaminathan //alocate cif->bytes into the stack 76*1fd5a2e1SPrashanth Swaminathan R1 = [FP+8]; 77*1fd5a2e1SPrashanth Swaminathan R0 = SP; 78*1fd5a2e1SPrashanth Swaminathan R0 = R0 - R1; 79*1fd5a2e1SPrashanth Swaminathan R1 = 4; 80*1fd5a2e1SPrashanth Swaminathan R0 = R0 - R1; 81*1fd5a2e1SPrashanth Swaminathan [FP-12] = SP; 82*1fd5a2e1SPrashanth Swaminathan SP = R0; 83*1fd5a2e1SPrashanth Swaminathan [FP-16] = SP; 84*1fd5a2e1SPrashanth Swaminathan 85*1fd5a2e1SPrashanth Swaminathan.call_prep_args: 86*1fd5a2e1SPrashanth Swaminathan //get the addr of prep_args 87*1fd5a2e1SPrashanth Swaminathan P0 = [P3 + _ffi_prep_args@FUNCDESC_GOT17M4]; 88*1fd5a2e1SPrashanth Swaminathan P1 = [P0]; 89*1fd5a2e1SPrashanth Swaminathan P3 = [P0+4]; 90*1fd5a2e1SPrashanth Swaminathan R0 = [FP-16];//SP (parameter area) 91*1fd5a2e1SPrashanth Swaminathan R1 = [FP+12];//ecif 92*1fd5a2e1SPrashanth Swaminathan call (P1); 93*1fd5a2e1SPrashanth Swaminathan 94*1fd5a2e1SPrashanth Swaminathan.call_user_function: 95*1fd5a2e1SPrashanth Swaminathan //ajust SP so as to allow the user function access the parameters on the stack 96*1fd5a2e1SPrashanth Swaminathan SP = [FP-16]; //point to function parameters 97*1fd5a2e1SPrashanth Swaminathan R0 = [SP]; 98*1fd5a2e1SPrashanth Swaminathan R1 = [SP+4]; 99*1fd5a2e1SPrashanth Swaminathan R2 = [SP+8]; 100*1fd5a2e1SPrashanth Swaminathan //load user function address 101*1fd5a2e1SPrashanth Swaminathan P0 = FP; 102*1fd5a2e1SPrashanth Swaminathan P0 +=28; 103*1fd5a2e1SPrashanth Swaminathan P1 = [P0]; 104*1fd5a2e1SPrashanth Swaminathan P1 = [P1]; 105*1fd5a2e1SPrashanth Swaminathan P3 = [P0+4]; 106*1fd5a2e1SPrashanth Swaminathan /* 107*1fd5a2e1SPrashanth Swaminathan For functions returning aggregate values (struct) occupying more than 8 bytes, 108*1fd5a2e1SPrashanth Swaminathan the caller allocates the return value object on the stack and the address 109*1fd5a2e1SPrashanth Swaminathan of this object is passed to the callee as a hidden argument in register P0. 110*1fd5a2e1SPrashanth Swaminathan */ 111*1fd5a2e1SPrashanth Swaminathan P0 = [FP+24]; 112*1fd5a2e1SPrashanth Swaminathan 113*1fd5a2e1SPrashanth Swaminathan call (P1); 114*1fd5a2e1SPrashanth Swaminathan SP = [FP-12]; 115*1fd5a2e1SPrashanth Swaminathan.compute_return: 116*1fd5a2e1SPrashanth Swaminathan P2 = [FP-20]; 117*1fd5a2e1SPrashanth Swaminathan [FP-8] = R0; 118*1fd5a2e1SPrashanth Swaminathan [FP-4] = R1; 119*1fd5a2e1SPrashanth Swaminathan 120*1fd5a2e1SPrashanth Swaminathan R0 = [FP+20]; 121*1fd5a2e1SPrashanth Swaminathan R1 = R0 << 2; 122*1fd5a2e1SPrashanth Swaminathan 123*1fd5a2e1SPrashanth Swaminathan R0 = [P2+.rettable@GOT17M4]; 124*1fd5a2e1SPrashanth Swaminathan R0 = R1 + R0; 125*1fd5a2e1SPrashanth Swaminathan P2 = R0; 126*1fd5a2e1SPrashanth Swaminathan R1 = [P2]; 127*1fd5a2e1SPrashanth Swaminathan 128*1fd5a2e1SPrashanth Swaminathan P2 = [FP+-20]; 129*1fd5a2e1SPrashanth Swaminathan R0 = [P2+.rettable@GOT17M4]; 130*1fd5a2e1SPrashanth Swaminathan R0 = R1 + R0; 131*1fd5a2e1SPrashanth Swaminathan P2 = R0; 132*1fd5a2e1SPrashanth Swaminathan R0 = [FP-8]; 133*1fd5a2e1SPrashanth Swaminathan R1 = [FP-4]; 134*1fd5a2e1SPrashanth Swaminathan jump (P2); 135*1fd5a2e1SPrashanth Swaminathan 136*1fd5a2e1SPrashanth Swaminathan/* 137*1fd5a2e1SPrashanth Swaminathan#define FFIBFIN_RET_VOID 0 138*1fd5a2e1SPrashanth Swaminathan#define FFIBFIN_RET_BYTE 1 139*1fd5a2e1SPrashanth Swaminathan#define FFIBFIN_RET_HALFWORD 2 140*1fd5a2e1SPrashanth Swaminathan#define FFIBFIN_RET_INT64 3 141*1fd5a2e1SPrashanth Swaminathan#define FFIBFIN_RET_INT32 4 142*1fd5a2e1SPrashanth Swaminathan*/ 143*1fd5a2e1SPrashanth Swaminathan.align 4 144*1fd5a2e1SPrashanth Swaminathan.align 4 145*1fd5a2e1SPrashanth Swaminathan.rettable: 146*1fd5a2e1SPrashanth Swaminathan .dd .epilogue - .rettable 147*1fd5a2e1SPrashanth Swaminathan .dd .rbyte - .rettable; 148*1fd5a2e1SPrashanth Swaminathan .dd .rhalfword - .rettable; 149*1fd5a2e1SPrashanth Swaminathan .dd .rint64 - .rettable; 150*1fd5a2e1SPrashanth Swaminathan .dd .rint32 - .rettable; 151*1fd5a2e1SPrashanth Swaminathan 152*1fd5a2e1SPrashanth Swaminathan.rbyte: 153*1fd5a2e1SPrashanth Swaminathan P0 = [FP+24]; 154*1fd5a2e1SPrashanth Swaminathan R0 = R0.B (Z); 155*1fd5a2e1SPrashanth Swaminathan [P0] = R0; 156*1fd5a2e1SPrashanth Swaminathan JUMP .epilogue 157*1fd5a2e1SPrashanth Swaminathan.rhalfword: 158*1fd5a2e1SPrashanth Swaminathan P0 = [FP+24]; 159*1fd5a2e1SPrashanth Swaminathan R0 = R0.L; 160*1fd5a2e1SPrashanth Swaminathan [P0] = R0; 161*1fd5a2e1SPrashanth Swaminathan JUMP .epilogue 162*1fd5a2e1SPrashanth Swaminathan.rint64: 163*1fd5a2e1SPrashanth Swaminathan P0 = [FP+24];// &rvalue 164*1fd5a2e1SPrashanth Swaminathan [P0] = R0; 165*1fd5a2e1SPrashanth Swaminathan [P0+4] = R1; 166*1fd5a2e1SPrashanth Swaminathan JUMP .epilogue 167*1fd5a2e1SPrashanth Swaminathan.rint32: 168*1fd5a2e1SPrashanth Swaminathan P0 = [FP+24]; 169*1fd5a2e1SPrashanth Swaminathan [P0] = R0; 170*1fd5a2e1SPrashanth Swaminathan.epilogue: 171*1fd5a2e1SPrashanth Swaminathan R0 = [FP+8]; 172*1fd5a2e1SPrashanth Swaminathan R1 = [FP+12]; 173*1fd5a2e1SPrashanth Swaminathan R2 = [FP+16]; 174*1fd5a2e1SPrashanth Swaminathan P3 = [FP-20]; 175*1fd5a2e1SPrashanth Swaminathan UNLINK; 176*1fd5a2e1SPrashanth Swaminathan RTS; 177*1fd5a2e1SPrashanth Swaminathan 178*1fd5a2e1SPrashanth Swaminathan.size _ffi_call_SYSV,.-_ffi_call_SYSV; 179*1fd5a2e1SPrashanth Swaminathan.endfunc 180