more changes on original files
[linux-2.4.git] / arch / m68k / math-emu / fp_entry.S
1 /*
2  * fp_emu.S
3  *
4  * Copyright Roman Zippel, 1997.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, and the entire permission notice in its entirety,
11  *    including the disclaimer of warranties.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote
16  *    products derived from this software without specific prior
17  *    written permission.
18  *
19  * ALTERNATIVELY, this product may be distributed under the terms of
20  * the GNU General Public License, in which case the provisions of the GPL are
21  * required INSTEAD OF the above restrictions.  (This clause is
22  * necessary due to a potential bad interaction between the GPL and
23  * the restrictions contained in a BSD-style copyright.)
24  *
25  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
26  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
29  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
35  * OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37
38 #include <linux/config.h>
39 #include <linux/linkage.h>
40 #include <asm/entry.h>
41
42 #include "fp_emu.h"
43
44         .globl  SYMBOL_NAME(fpu_emu)
45         .globl  fp_debugprint
46         .globl  fp_err_ua1,fp_err_ua2
47
48         .text
49 SYMBOL_NAME_LABEL(fpu_emu)
50         SAVE_ALL_INT
51         GET_CURRENT(%d0)
52
53 #if defined(CPU_M68020_OR_M68030) && defined(CPU_M68040_OR_M68060)
54         tst.l   SYMBOL_NAME(m68k_is040or060)
55         jeq     1f
56 #endif
57 #if defined(CPU_M68040_OR_M68060)
58         move.l  (FPS_PC2,%sp),(FPS_PC,%sp)
59 #endif
60 1:
61         | emulate the instruction
62         jsr     fp_scan
63
64 #if defined(CONFIG_M68060)
65 #if !defined(CPU_M68060_ONLY)
66         btst    #3,SYMBOL_NAME(m68k_cputype)+3
67         jeq     1f
68 #endif
69         btst    #7,(FPS_SR,%sp)
70         jne     fp_sendtrace060
71 #endif
72 1:
73         | emulation successful?
74         tst.l   %d0
75         jeq     SYMBOL_NAME(ret_from_exception)
76
77         | send some signal to program here
78
79         jra     SYMBOL_NAME(ret_from_exception)
80
81         | we jump here after an access error while trying to access
82         | user space, we correct stackpointer and send a SIGSEGV to
83         | the user process
84 fp_err_ua2:
85         addq.l  #4,%sp
86 fp_err_ua1:
87         addq.l  #4,%sp
88         move.l  %a0,-(%sp)
89         pea     SEGV_MAPERR
90         pea     SIGSEGV
91         jsr     SYMBOL_NAME(fpemu_signal)
92         add.w   #12,%sp
93         jra     SYMBOL_NAME(ret_from_exception)
94
95 #if defined(CONFIG_M68060)
96         | send a trace signal if we are debugged
97         | it does not really belong here, but...
98 fp_sendtrace060:
99         move.l  (FPS_PC,%sp),-(%sp)
100         pea     TRAP_TRACE
101         pea     SIGTRAP
102         jsr     SYMBOL_NAME(fpemu_signal)
103         add.w   #12,%sp
104         jra     SYMBOL_NAME(ret_from_exception)
105 #endif
106
107         .globl  fp_get_data_reg, fp_put_data_reg
108         .globl  fp_get_addr_reg, fp_put_addr_reg
109
110         | Entry points to get/put a register. Some of them can be get/put
111         | directly, others are on the stack, as we read/write the stack
112         | directly here, these function may only be called from within
113         | instruction decoding, otherwise the stack pointer is incorrect
114         | and the stack gets corrupted.
115 fp_get_data_reg:
116         jmp     ([0f:w,%pc,%d0.w*4])
117
118         .align  4
119 0:
120         .long   fp_get_d0, fp_get_d1
121         .long   fp_get_d2, fp_get_d3
122         .long   fp_get_d4, fp_get_d5
123         .long   fp_get_d6, fp_get_d7
124
125 fp_get_d0:
126         move.l  (PT_D0+8,%sp),%d0
127         printf  PREGISTER,"{d0->%08x}",1,%d0
128         rts
129
130 fp_get_d1:
131         move.l  (PT_D1+8,%sp),%d0
132         printf  PREGISTER,"{d1->%08x}",1,%d0
133         rts
134
135 fp_get_d2:
136         move.l  (PT_D2+8,%sp),%d0
137         printf  PREGISTER,"{d2->%08x}",1,%d0
138         rts
139
140 fp_get_d3:
141         move.l  %d3,%d0
142         printf  PREGISTER,"{d3->%08x}",1,%d0
143         rts
144
145 fp_get_d4:
146         move.l  %d4,%d0
147         printf  PREGISTER,"{d4->%08x}",1,%d0
148         rts
149
150 fp_get_d5:
151         move.l  %d5,%d0
152         printf  PREGISTER,"{d5->%08x}",1,%d0
153         rts
154
155 fp_get_d6:
156         move.l  %d6,%d0
157         printf  PREGISTER,"{d6->%08x}",1,%d0
158         rts
159
160 fp_get_d7:
161         move.l  %d7,%d0
162         printf  PREGISTER,"{d7->%08x}",1,%d0
163         rts
164
165 fp_put_data_reg:
166         jmp     ([0f:w,%pc,%d1.w*4])
167
168         .align  4
169 0:
170         .long   fp_put_d0, fp_put_d1
171         .long   fp_put_d2, fp_put_d3
172         .long   fp_put_d4, fp_put_d5
173         .long   fp_put_d6, fp_put_d7
174
175 fp_put_d0:
176         printf  PREGISTER,"{d0<-%08x}",1,%d0
177         move.l  %d0,(PT_D0+8,%sp)
178         rts
179
180 fp_put_d1:
181         printf  PREGISTER,"{d1<-%08x}",1,%d0
182         move.l  %d0,(PT_D1+8,%sp)
183         rts
184
185 fp_put_d2:
186         printf  PREGISTER,"{d2<-%08x}",1,%d0
187         move.l  %d0,(PT_D2+8,%sp)
188         rts
189
190 fp_put_d3:
191         printf  PREGISTER,"{d3<-%08x}",1,%d0
192 |       move.l  %d0,%d3
193         move.l  %d0,(PT_D3+8,%sp)
194         rts
195
196 fp_put_d4:
197         printf  PREGISTER,"{d4<-%08x}",1,%d0
198 |       move.l  %d0,%d4
199         move.l  %d0,(PT_D4+8,%sp)
200         rts
201
202 fp_put_d5:
203         printf  PREGISTER,"{d5<-%08x}",1,%d0
204 |       move.l  %d0,%d5
205         move.l  %d0,(PT_D5+8,%sp)
206         rts
207
208 fp_put_d6:
209         printf  PREGISTER,"{d6<-%08x}",1,%d0
210         move.l  %d0,%d6
211         rts
212
213 fp_put_d7:
214         printf  PREGISTER,"{d7<-%08x}",1,%d0
215         move.l  %d0,%d7
216         rts
217
218 fp_get_addr_reg:
219         jmp     ([0f:w,%pc,%d0.w*4])
220
221         .align  4
222 0:
223         .long   fp_get_a0, fp_get_a1
224         .long   fp_get_a2, fp_get_a3
225         .long   fp_get_a4, fp_get_a5
226         .long   fp_get_a6, fp_get_a7
227
228 fp_get_a0:
229         move.l  (PT_A0+8,%sp),%a0
230         printf  PREGISTER,"{a0->%08x}",1,%a0
231         rts
232
233 fp_get_a1:
234         move.l  (PT_A1+8,%sp),%a0
235         printf  PREGISTER,"{a1->%08x}",1,%a0
236         rts
237
238 fp_get_a2:
239         move.l  (PT_A2+8,%sp),%a0
240         printf  PREGISTER,"{a2->%08x}",1,%a0
241         rts
242
243 fp_get_a3:
244         move.l  %a3,%a0
245         printf  PREGISTER,"{a3->%08x}",1,%a0
246         rts
247
248 fp_get_a4:
249         move.l  %a4,%a0
250         printf  PREGISTER,"{a4->%08x}",1,%a0
251         rts
252
253 fp_get_a5:
254         move.l  %a5,%a0
255         printf  PREGISTER,"{a5->%08x}",1,%a0
256         rts
257
258 fp_get_a6:
259         move.l  %a6,%a0
260         printf  PREGISTER,"{a6->%08x}",1,%a0
261         rts
262
263 fp_get_a7:
264         move.l  %usp,%a0
265         printf  PREGISTER,"{a7->%08x}",1,%a0
266         rts
267
268 fp_put_addr_reg:
269         jmp     ([0f:w,%pc,%d0.w*4])
270
271         .align  4
272 0:
273         .long   fp_put_a0, fp_put_a1
274         .long   fp_put_a2, fp_put_a3
275         .long   fp_put_a4, fp_put_a5
276         .long   fp_put_a6, fp_put_a7
277
278 fp_put_a0:
279         printf  PREGISTER,"{a0<-%08x}",1,%a0
280         move.l  %a0,(PT_A0+8,%sp)
281         rts
282
283 fp_put_a1:
284         printf  PREGISTER,"{a1<-%08x}",1,%a0
285         move.l  %a0,(PT_A1+8,%sp)
286         rts
287
288 fp_put_a2:
289         printf  PREGISTER,"{a2<-%08x}",1,%a0
290         move.l  %a0,(PT_A2+8,%sp)
291         rts
292
293 fp_put_a3:
294         printf  PREGISTER,"{a3<-%08x}",1,%a0
295         move.l  %a0,%a3
296         rts
297
298 fp_put_a4:
299         printf  PREGISTER,"{a4<-%08x}",1,%a0
300         move.l  %a0,%a4
301         rts
302
303 fp_put_a5:
304         printf  PREGISTER,"{a5<-%08x}",1,%a0
305         move.l  %a0,%a5
306         rts
307
308 fp_put_a6:
309         printf  PREGISTER,"{a6<-%08x}",1,%a0
310         move.l  %a0,%a6
311         rts
312
313 fp_put_a7:
314         printf  PREGISTER,"{a7<-%08x}",1,%a0
315         move.l  %a0,%usp
316         rts
317
318         .data
319         .align  4
320
321 fp_debugprint:
322 |       .long   PMDECODE
323         .long   PMINSTR+PMDECODE+PMCONV+PMNORM
324 |       .long   PMCONV+PMNORM+PMINSTR
325 |       .long   0