xref: /aosp_15_r20/external/libffi/src/avr32/sysv.S (revision 1fd5a2e1d639cd1ddf29dd0c484c123bbd850c21)
1*1fd5a2e1SPrashanth Swaminathan/* -----------------------------------------------------------------------
2*1fd5a2e1SPrashanth Swaminathan   sysv.S - Copyright (c) 2009  Bradley Smith <[email protected]>
3*1fd5a2e1SPrashanth Swaminathan
4*1fd5a2e1SPrashanth Swaminathan   AVR32 Foreign Function Interface
5*1fd5a2e1SPrashanth Swaminathan
6*1fd5a2e1SPrashanth Swaminathan   Permission is hereby granted, free of charge, to any person obtaining
7*1fd5a2e1SPrashanth Swaminathan   a copy of this software and associated documentation files (the
8*1fd5a2e1SPrashanth Swaminathan   ``Software''), to deal in the Software without restriction, including
9*1fd5a2e1SPrashanth Swaminathan   without limitation the rights to use, copy, modify, merge, publish,
10*1fd5a2e1SPrashanth Swaminathan   distribute, sublicense, and/or sell copies of the Software, and to
11*1fd5a2e1SPrashanth Swaminathan   permit persons to whom the Software is furnished to do so, subject to
12*1fd5a2e1SPrashanth Swaminathan   the following conditions:
13*1fd5a2e1SPrashanth Swaminathan
14*1fd5a2e1SPrashanth Swaminathan   The above copyright notice and this permission notice shall be included
15*1fd5a2e1SPrashanth Swaminathan   in all copies or substantial portions of the Software.
16*1fd5a2e1SPrashanth Swaminathan
17*1fd5a2e1SPrashanth Swaminathan   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18*1fd5a2e1SPrashanth Swaminathan   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19*1fd5a2e1SPrashanth Swaminathan   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20*1fd5a2e1SPrashanth Swaminathan   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21*1fd5a2e1SPrashanth Swaminathan   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22*1fd5a2e1SPrashanth Swaminathan   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23*1fd5a2e1SPrashanth Swaminathan   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24*1fd5a2e1SPrashanth Swaminathan   --------------------------------------------------------------------- */
25*1fd5a2e1SPrashanth Swaminathan
26*1fd5a2e1SPrashanth Swaminathan#define LIBFFI_ASM
27*1fd5a2e1SPrashanth Swaminathan#include <fficonfig.h>
28*1fd5a2e1SPrashanth Swaminathan#include <ffi.h>
29*1fd5a2e1SPrashanth Swaminathan
30*1fd5a2e1SPrashanth Swaminathan    /* r12:  ffi_prep_args
31*1fd5a2e1SPrashanth Swaminathan     * r11:  &ecif
32*1fd5a2e1SPrashanth Swaminathan     * r10:  size
33*1fd5a2e1SPrashanth Swaminathan     * r9:   cif->flags
34*1fd5a2e1SPrashanth Swaminathan     * r8:   ecif.rvalue
35*1fd5a2e1SPrashanth Swaminathan     * sp+0: cif->rstruct_flag
36*1fd5a2e1SPrashanth Swaminathan     * sp+4: fn */
37*1fd5a2e1SPrashanth Swaminathan
38*1fd5a2e1SPrashanth Swaminathan    .text
39*1fd5a2e1SPrashanth Swaminathan    .align  1
40*1fd5a2e1SPrashanth Swaminathan    .globl  ffi_call_SYSV
41*1fd5a2e1SPrashanth Swaminathan    .type   ffi_call_SYSV, @function
42*1fd5a2e1SPrashanth Swaminathanffi_call_SYSV:
43*1fd5a2e1SPrashanth Swaminathan    stm     --sp, r0,r1,lr
44*1fd5a2e1SPrashanth Swaminathan    stm     --sp, r8-r12
45*1fd5a2e1SPrashanth Swaminathan    mov     r0, sp
46*1fd5a2e1SPrashanth Swaminathan
47*1fd5a2e1SPrashanth Swaminathan    /* Make room for all of the new args. */
48*1fd5a2e1SPrashanth Swaminathan    sub     sp, r10
49*1fd5a2e1SPrashanth Swaminathan    /* Pad to make way for potential skipped registers */
50*1fd5a2e1SPrashanth Swaminathan    sub     sp, 20
51*1fd5a2e1SPrashanth Swaminathan
52*1fd5a2e1SPrashanth Swaminathan    /* Call ffi_prep_args(stack, &ecif). */
53*1fd5a2e1SPrashanth Swaminathan    /* r11 already set */
54*1fd5a2e1SPrashanth Swaminathan    mov     r1, r12
55*1fd5a2e1SPrashanth Swaminathan    mov     r12, sp
56*1fd5a2e1SPrashanth Swaminathan    icall   r1
57*1fd5a2e1SPrashanth Swaminathan
58*1fd5a2e1SPrashanth Swaminathan    /* Save new argument size */
59*1fd5a2e1SPrashanth Swaminathan    mov     r1, r12
60*1fd5a2e1SPrashanth Swaminathan
61*1fd5a2e1SPrashanth Swaminathan    /* Move first 5 parameters in registers. */
62*1fd5a2e1SPrashanth Swaminathan    ldm     sp++, r8-r12
63*1fd5a2e1SPrashanth Swaminathan
64*1fd5a2e1SPrashanth Swaminathan    /* call (fn) (...). */
65*1fd5a2e1SPrashanth Swaminathan    ld.w    r1, r0[36]
66*1fd5a2e1SPrashanth Swaminathan    icall   r1
67*1fd5a2e1SPrashanth Swaminathan
68*1fd5a2e1SPrashanth Swaminathan    /* Remove the space we pushed for the args. */
69*1fd5a2e1SPrashanth Swaminathan    mov     sp, r0
70*1fd5a2e1SPrashanth Swaminathan
71*1fd5a2e1SPrashanth Swaminathan    /* Load r1 with the rstruct flag. */
72*1fd5a2e1SPrashanth Swaminathan    ld.w    r1, sp[32]
73*1fd5a2e1SPrashanth Swaminathan
74*1fd5a2e1SPrashanth Swaminathan    /* Load r9 with the return type code. */
75*1fd5a2e1SPrashanth Swaminathan    ld.w    r9, sp[12]
76*1fd5a2e1SPrashanth Swaminathan
77*1fd5a2e1SPrashanth Swaminathan    /* Load r8 with the return value pointer. */
78*1fd5a2e1SPrashanth Swaminathan    ld.w    r8, sp[16]
79*1fd5a2e1SPrashanth Swaminathan
80*1fd5a2e1SPrashanth Swaminathan    /* If the return value pointer is NULL, assume no return value. */
81*1fd5a2e1SPrashanth Swaminathan    cp.w    r8, 0
82*1fd5a2e1SPrashanth Swaminathan    breq    .Lend
83*1fd5a2e1SPrashanth Swaminathan
84*1fd5a2e1SPrashanth Swaminathan    /* Check if return type is actually a struct */
85*1fd5a2e1SPrashanth Swaminathan    cp.w    r1, 0
86*1fd5a2e1SPrashanth Swaminathan    breq    1f
87*1fd5a2e1SPrashanth Swaminathan
88*1fd5a2e1SPrashanth Swaminathan    /* Return 8bit */
89*1fd5a2e1SPrashanth Swaminathan    cp.w    r9, FFI_TYPE_UINT8
90*1fd5a2e1SPrashanth Swaminathan    breq    .Lstore8
91*1fd5a2e1SPrashanth Swaminathan
92*1fd5a2e1SPrashanth Swaminathan    /* Return 16bit */
93*1fd5a2e1SPrashanth Swaminathan    cp.w    r9, FFI_TYPE_UINT16
94*1fd5a2e1SPrashanth Swaminathan    breq    .Lstore16
95*1fd5a2e1SPrashanth Swaminathan
96*1fd5a2e1SPrashanth Swaminathan1:
97*1fd5a2e1SPrashanth Swaminathan    /* Return 32bit */
98*1fd5a2e1SPrashanth Swaminathan    cp.w    r9, FFI_TYPE_UINT32
99*1fd5a2e1SPrashanth Swaminathan    breq    .Lstore32
100*1fd5a2e1SPrashanth Swaminathan    cp.w    r9, FFI_TYPE_UINT16
101*1fd5a2e1SPrashanth Swaminathan    breq    .Lstore32
102*1fd5a2e1SPrashanth Swaminathan    cp.w    r9, FFI_TYPE_UINT8
103*1fd5a2e1SPrashanth Swaminathan    breq    .Lstore32
104*1fd5a2e1SPrashanth Swaminathan
105*1fd5a2e1SPrashanth Swaminathan    /* Return 64bit */
106*1fd5a2e1SPrashanth Swaminathan    cp.w    r9, FFI_TYPE_UINT64
107*1fd5a2e1SPrashanth Swaminathan    breq    .Lstore64
108*1fd5a2e1SPrashanth Swaminathan
109*1fd5a2e1SPrashanth Swaminathan    /* Didn't match anything */
110*1fd5a2e1SPrashanth Swaminathan    bral    .Lend
111*1fd5a2e1SPrashanth Swaminathan
112*1fd5a2e1SPrashanth Swaminathan.Lstore64:
113*1fd5a2e1SPrashanth Swaminathan    st.w    r8[0], r11
114*1fd5a2e1SPrashanth Swaminathan    st.w    r8[4], r10
115*1fd5a2e1SPrashanth Swaminathan    bral    .Lend
116*1fd5a2e1SPrashanth Swaminathan
117*1fd5a2e1SPrashanth Swaminathan.Lstore32:
118*1fd5a2e1SPrashanth Swaminathan    st.w    r8[0], r12
119*1fd5a2e1SPrashanth Swaminathan    bral    .Lend
120*1fd5a2e1SPrashanth Swaminathan
121*1fd5a2e1SPrashanth Swaminathan.Lstore16:
122*1fd5a2e1SPrashanth Swaminathan    st.h    r8[0], r12
123*1fd5a2e1SPrashanth Swaminathan    bral    .Lend
124*1fd5a2e1SPrashanth Swaminathan
125*1fd5a2e1SPrashanth Swaminathan.Lstore8:
126*1fd5a2e1SPrashanth Swaminathan    st.b    r8[0], r12
127*1fd5a2e1SPrashanth Swaminathan    bral    .Lend
128*1fd5a2e1SPrashanth Swaminathan
129*1fd5a2e1SPrashanth Swaminathan.Lend:
130*1fd5a2e1SPrashanth Swaminathan    sub     sp, -20
131*1fd5a2e1SPrashanth Swaminathan    ldm     sp++, r0,r1,pc
132*1fd5a2e1SPrashanth Swaminathan
133*1fd5a2e1SPrashanth Swaminathan    .size   ffi_call_SYSV, . - ffi_call_SYSV
134*1fd5a2e1SPrashanth Swaminathan
135*1fd5a2e1SPrashanth Swaminathan
136*1fd5a2e1SPrashanth Swaminathan    /* r12:  __ctx
137*1fd5a2e1SPrashanth Swaminathan     * r11:  __rstruct_flag
138*1fd5a2e1SPrashanth Swaminathan     * r10:  __inner */
139*1fd5a2e1SPrashanth Swaminathan
140*1fd5a2e1SPrashanth Swaminathan    .align  1
141*1fd5a2e1SPrashanth Swaminathan    .globl  ffi_closure_SYSV
142*1fd5a2e1SPrashanth Swaminathan    .type   ffi_closure_SYSV, @function
143*1fd5a2e1SPrashanth Swaminathanffi_closure_SYSV:
144*1fd5a2e1SPrashanth Swaminathan    stm     --sp, r0,lr
145*1fd5a2e1SPrashanth Swaminathan    mov     r0, r11
146*1fd5a2e1SPrashanth Swaminathan    mov     r8, r10
147*1fd5a2e1SPrashanth Swaminathan    sub     r10, sp, -8
148*1fd5a2e1SPrashanth Swaminathan    sub     sp, 12
149*1fd5a2e1SPrashanth Swaminathan    st.w    sp[8], sp
150*1fd5a2e1SPrashanth Swaminathan    sub     r11, sp, -8
151*1fd5a2e1SPrashanth Swaminathan    icall   r8
152*1fd5a2e1SPrashanth Swaminathan
153*1fd5a2e1SPrashanth Swaminathan    /* Check if return type is actually a struct */
154*1fd5a2e1SPrashanth Swaminathan    cp.w    r0, 0
155*1fd5a2e1SPrashanth Swaminathan    breq    1f
156*1fd5a2e1SPrashanth Swaminathan
157*1fd5a2e1SPrashanth Swaminathan    /* Return 8bit */
158*1fd5a2e1SPrashanth Swaminathan    cp.w    r12, FFI_TYPE_UINT8
159*1fd5a2e1SPrashanth Swaminathan    breq    .Lget8
160*1fd5a2e1SPrashanth Swaminathan
161*1fd5a2e1SPrashanth Swaminathan    /* Return 16bit */
162*1fd5a2e1SPrashanth Swaminathan    cp.w    r12, FFI_TYPE_UINT16
163*1fd5a2e1SPrashanth Swaminathan    breq    .Lget16
164*1fd5a2e1SPrashanth Swaminathan
165*1fd5a2e1SPrashanth Swaminathan1:
166*1fd5a2e1SPrashanth Swaminathan    /* Return 32bit */
167*1fd5a2e1SPrashanth Swaminathan    cp.w    r12, FFI_TYPE_UINT32
168*1fd5a2e1SPrashanth Swaminathan    breq    .Lget32
169*1fd5a2e1SPrashanth Swaminathan    cp.w    r12, FFI_TYPE_UINT16
170*1fd5a2e1SPrashanth Swaminathan    breq    .Lget32
171*1fd5a2e1SPrashanth Swaminathan    cp.w    r12, FFI_TYPE_UINT8
172*1fd5a2e1SPrashanth Swaminathan    breq    .Lget32
173*1fd5a2e1SPrashanth Swaminathan
174*1fd5a2e1SPrashanth Swaminathan    /* Return 64bit */
175*1fd5a2e1SPrashanth Swaminathan    cp.w    r12, FFI_TYPE_UINT64
176*1fd5a2e1SPrashanth Swaminathan    breq    .Lget64
177*1fd5a2e1SPrashanth Swaminathan
178*1fd5a2e1SPrashanth Swaminathan    /* Didn't match anything */
179*1fd5a2e1SPrashanth Swaminathan    bral    .Lclend
180*1fd5a2e1SPrashanth Swaminathan
181*1fd5a2e1SPrashanth Swaminathan.Lget64:
182*1fd5a2e1SPrashanth Swaminathan    ld.w    r11, sp[0]
183*1fd5a2e1SPrashanth Swaminathan    ld.w    r10, sp[4]
184*1fd5a2e1SPrashanth Swaminathan    bral    .Lclend
185*1fd5a2e1SPrashanth Swaminathan
186*1fd5a2e1SPrashanth Swaminathan.Lget32:
187*1fd5a2e1SPrashanth Swaminathan    ld.w    r12, sp[0]
188*1fd5a2e1SPrashanth Swaminathan    bral    .Lclend
189*1fd5a2e1SPrashanth Swaminathan
190*1fd5a2e1SPrashanth Swaminathan.Lget16:
191*1fd5a2e1SPrashanth Swaminathan    ld.uh   r12, sp[0]
192*1fd5a2e1SPrashanth Swaminathan    bral    .Lclend
193*1fd5a2e1SPrashanth Swaminathan
194*1fd5a2e1SPrashanth Swaminathan.Lget8:
195*1fd5a2e1SPrashanth Swaminathan    ld.ub   r12, sp[0]
196*1fd5a2e1SPrashanth Swaminathan    bral    .Lclend
197*1fd5a2e1SPrashanth Swaminathan
198*1fd5a2e1SPrashanth Swaminathan.Lclend:
199*1fd5a2e1SPrashanth Swaminathan    sub     sp, -12
200*1fd5a2e1SPrashanth Swaminathan    ldm     sp++, r0,lr
201*1fd5a2e1SPrashanth Swaminathan    sub     sp, -20
202*1fd5a2e1SPrashanth Swaminathan    mov     pc, lr
203*1fd5a2e1SPrashanth Swaminathan
204*1fd5a2e1SPrashanth Swaminathan    .size   ffi_closure_SYSV, . - ffi_closure_SYSV
205*1fd5a2e1SPrashanth Swaminathan
206*1fd5a2e1SPrashanth Swaminathan#if defined __ELF__ && defined __linux__
207*1fd5a2e1SPrashanth Swaminathan    .section    .note.GNU-stack,"",@progbits
208*1fd5a2e1SPrashanth Swaminathan#endif
209