More cygwin fixes
[platform/upstream/libffi.git] / src / m68k / sysv.S
1 /* -----------------------------------------------------------------------
2         
3    sysv.S - Copyright (c) 2012 Alan Hourihane
4             Copyright (c) 1998, 2012 Andreas Schwab
5             Copyright (c) 2008 Red Hat, Inc. 
6    
7    m68k Foreign Function Interface 
8
9    Permission is hereby granted, free of charge, to any person obtaining
10    a copy of this software and associated documentation files (the
11    ``Software''), to deal in the Software without restriction, including
12    without limitation the rights to use, copy, modify, merge, publish,
13    distribute, sublicense, and/or sell copies of the Software, and to
14    permit persons to whom the Software is furnished to do so, subject to
15    the following conditions:
16
17    The above copyright notice and this permission notice shall be included
18    in all copies or substantial portions of the Software.
19
20    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
21    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23    NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27    DEALINGS IN THE SOFTWARE.
28    ----------------------------------------------------------------------- */
29
30 #define LIBFFI_ASM      
31 #include <fficonfig.h>
32 #include <ffi.h>
33
34 #ifdef HAVE_AS_CFI_PSEUDO_OP
35 #define CFI_STARTPROC()         .cfi_startproc
36 #define CFI_OFFSET(reg,off)     .cfi_offset     reg,off
37 #define CFI_DEF_CFA(reg,off)    .cfi_def_cfa    reg,off
38 #define CFI_ENDPROC()           .cfi_endproc
39 #else
40 #define CFI_STARTPROC()
41 #define CFI_OFFSET(reg,off)
42 #define CFI_DEF_CFA(reg,off)
43 #define CFI_ENDPROC()
44 #endif
45
46 #ifdef __MINT__
47 #define CALLFUNC(funcname) _ ## funcname
48 #else
49 #define CALLFUNC(funcname) funcname
50 #endif
51
52         .text
53
54         .globl  CALLFUNC(ffi_call_SYSV)
55         .type   CALLFUNC(ffi_call_SYSV),@function
56         .align  4
57
58 CALLFUNC(ffi_call_SYSV):
59         CFI_STARTPROC()
60         link    %fp,#0
61         CFI_OFFSET(14,-8)
62         CFI_DEF_CFA(14,8)
63         move.l  %d2,-(%sp)
64         CFI_OFFSET(2,-12)
65
66         | Make room for all of the new args.
67         sub.l   12(%fp),%sp
68
69         | Call ffi_prep_args
70         move.l  8(%fp),-(%sp)
71         pea     4(%sp)
72 #if !defined __PIC__
73         jsr     CALLFUNC(ffi_prep_args)
74 #else
75         bsr.l   CALLFUNC(ffi_prep_args@PLTPC)
76 #endif
77         addq.l  #8,%sp  
78
79         | Pass pointer to struct value, if any
80 #ifdef __MINT__
81         move.l  %d0,%a1
82 #else
83         move.l  %a0,%a1
84 #endif
85
86         | Call the function
87         move.l  24(%fp),%a0
88         jsr     (%a0)
89
90         | Remove the space we pushed for the args
91         add.l   12(%fp),%sp
92
93         | Load the pointer to storage for the return value
94         move.l  20(%fp),%a1
95
96         | Load the return type code 
97         move.l  16(%fp),%d2
98
99         | If the return value pointer is NULL, assume no return value.
100         | NOTE: On the mc68000, tst on an address register is not supported.
101 #if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__)
102         cmp.w   #0, %a1
103 #else
104         tst.l   %a1
105 #endif
106         jbeq    noretval
107
108         btst    #0,%d2
109         jbeq    retlongint
110         move.l  %d0,(%a1)
111         jbra    epilogue
112
113 retlongint:
114         btst    #1,%d2
115         jbeq    retfloat
116         move.l  %d0,(%a1)
117         move.l  %d1,4(%a1)
118         jbra    epilogue
119
120 retfloat:
121         btst    #2,%d2
122         jbeq    retdouble
123 #if defined(__MC68881__) || defined(__HAVE_68881__)
124         fmove.s %fp0,(%a1)
125 #else
126         move.l  %d0,(%a1)
127 #endif
128         jbra    epilogue
129
130 retdouble:
131         btst    #3,%d2
132         jbeq    retlongdouble
133 #if defined(__MC68881__) || defined(__HAVE_68881__)
134         fmove.d %fp0,(%a1)
135 #else
136         move.l  %d0,(%a1)+
137         move.l  %d1,(%a1)
138 #endif
139         jbra    epilogue
140
141 retlongdouble:
142         btst    #4,%d2
143         jbeq    retpointer
144 #if defined(__MC68881__) || defined(__HAVE_68881__)
145         fmove.x %fp0,(%a1)
146 #else
147         move.l  %d0,(%a1)+
148         move.l  %d1,(%a1)+
149         move.l  %d2,(%a1)
150 #endif
151         jbra    epilogue
152
153 retpointer:
154         btst    #5,%d2
155         jbeq    retstruct1
156 #ifdef __MINT__
157         move.l  %d0,(%a1)
158 #else
159         move.l  %a0,(%a1)
160 #endif
161         jbra    epilogue
162
163 retstruct1:
164         btst    #6,%d2
165         jbeq    retstruct2
166         move.b  %d0,(%a1)
167         jbra    epilogue
168
169 retstruct2:
170         btst    #7,%d2
171         jbeq    noretval
172         move.w  %d0,(%a1)
173
174 noretval:
175 epilogue:
176         move.l  (%sp)+,%d2
177         unlk    %fp
178         rts
179         CFI_ENDPROC()
180         .size   CALLFUNC(ffi_call_SYSV),.-CALLFUNC(ffi_call_SYSV)
181
182         .globl  CALLFUNC(ffi_closure_SYSV)
183         .type   CALLFUNC(ffi_closure_SYSV), @function
184         .align  4
185
186 CALLFUNC(ffi_closure_SYSV):
187         CFI_STARTPROC()
188         link    %fp,#-12
189         CFI_OFFSET(14,-8)
190         CFI_DEF_CFA(14,8)
191         move.l  %sp,-12(%fp)
192         pea     8(%fp)
193         pea     -12(%fp)
194         move.l  %a0,-(%sp)
195 #if !defined __PIC__
196         jsr     CALLFUNC(ffi_closure_SYSV_inner)
197 #else
198         bsr.l   CALLFUNC(ffi_closure_SYSV_inner@PLTPC)
199 #endif
200
201         lsr.l   #1,%d0
202         jne     1f
203         jcc     .Lcls_epilogue
204         move.l  -12(%fp),%d0
205 .Lcls_epilogue:
206         unlk    %fp
207         rts
208 1:
209         lea     -12(%fp),%a0
210         lsr.l   #2,%d0
211         jne     1f
212         jcs     .Lcls_ret_float
213         move.l  (%a0)+,%d0
214         move.l  (%a0),%d1
215         jra     .Lcls_epilogue
216 .Lcls_ret_float:
217 #if defined(__MC68881__) || defined(__HAVE_68881__)
218         fmove.s (%a0),%fp0
219 #else
220         move.l  (%a0),%d0
221 #endif
222         jra     .Lcls_epilogue
223 1:
224         lsr.l   #2,%d0
225         jne     1f
226         jcs     .Lcls_ret_ldouble
227 #if defined(__MC68881__) || defined(__HAVE_68881__)
228         fmove.d (%a0),%fp0
229 #else
230         move.l  (%a0)+,%d0
231         move.l  (%a0),%d1
232 #endif
233         jra     .Lcls_epilogue
234 .Lcls_ret_ldouble:
235 #if defined(__MC68881__) || defined(__HAVE_68881__)
236         fmove.x (%a0),%fp0
237 #else
238         move.l  (%a0)+,%d0
239         move.l  (%a0)+,%d1
240         move.l  (%a0),%d2
241 #endif
242         jra     .Lcls_epilogue
243 1:
244         lsr.l   #2,%d0
245         jne     .Lcls_ret_struct2
246         jcs     .Lcls_ret_struct1
247         move.l  (%a0),%a0
248         move.l  %a0,%d0
249         jra     .Lcls_epilogue
250 .Lcls_ret_struct1:
251         move.b  (%a0),%d0
252         jra     .Lcls_epilogue
253 .Lcls_ret_struct2:
254         move.w  (%a0),%d0
255         jra     .Lcls_epilogue
256         CFI_ENDPROC()
257
258         .size   CALLFUNC(ffi_closure_SYSV),.-CALLFUNC(ffi_closure_SYSV)
259
260         .globl  CALLFUNC(ffi_closure_struct_SYSV)
261         .type   CALLFUNC(ffi_closure_struct_SYSV), @function
262         .align  4
263
264 CALLFUNC(ffi_closure_struct_SYSV):
265         CFI_STARTPROC()
266         link    %fp,#0
267         CFI_OFFSET(14,-8)
268         CFI_DEF_CFA(14,8)
269         move.l  %sp,-12(%fp)
270         pea     8(%fp)
271         move.l  %a1,-(%sp)
272         move.l  %a0,-(%sp)
273 #if !defined __PIC__
274         jsr     CALLFUNC(ffi_closure_SYSV_inner)
275 #else
276         bsr.l   CALLFUNC(ffi_closure_SYSV_inner@PLTPC)
277 #endif
278         unlk    %fp
279         rts
280         CFI_ENDPROC()
281         .size   CALLFUNC(ffi_closure_struct_SYSV),.-CALLFUNC(ffi_closure_struct_SYSV)
282
283 #if defined __ELF__ && defined __linux__
284         .section        .note.GNU-stack,"",@progbits
285 #endif