diff options
Diffstat (limited to 'arch/m68k/math-emu/fp_entry.S')
-rw-r--r-- | arch/m68k/math-emu/fp_entry.S | 325 |
1 files changed, 325 insertions, 0 deletions
diff --git a/arch/m68k/math-emu/fp_entry.S b/arch/m68k/math-emu/fp_entry.S new file mode 100644 index 000000000000..5ec2d9101ea3 --- /dev/null +++ b/arch/m68k/math-emu/fp_entry.S | |||
@@ -0,0 +1,325 @@ | |||
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 fpu_emu | ||
45 | .globl fp_debugprint | ||
46 | .globl fp_err_ua1,fp_err_ua2 | ||
47 | |||
48 | .text | ||
49 | 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 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,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 ret_from_exception | ||
76 | |||
77 | | send some signal to program here | ||
78 | |||
79 | jra 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 fpemu_signal | ||
92 | add.w #12,%sp | ||
93 | jra 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 fpemu_signal | ||
103 | add.w #12,%sp | ||
104 | jra 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 | ||