xref: /aosp_15_r20/external/libffi/src/bfin/sysv.S (revision 1fd5a2e1d639cd1ddf29dd0c484c123bbd850c21)
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