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