OSDN Git Service

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