]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * fp_movem.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 "fp_emu.h" | |
39 | #include "fp_decode.h" | |
40 | ||
41 | | set flags for decode macros for fmovem | |
42 | do_fmovem=1 | |
43 | ||
44 | .globl fp_fmovem_fp, fp_fmovem_cr | |
45 | ||
46 | | %d1 contains the mask and count of the register list | |
47 | | for other register usage see fp_decode.h | |
48 | ||
49 | fp_fmovem_fp: | |
50 | printf PDECODE,"fmovem.x " | |
51 | | get register list and count them | |
52 | btst #11,%d2 | |
53 | jne 1f | |
54 | bfextu %d2{#24,#8},%d0 | static register list | |
55 | jra 2f | |
56 | 1: bfextu %d2{#25,#3},%d0 | dynamic register list | |
57 | jsr fp_get_data_reg | |
58 | 2: move.l %d0,%d1 | |
59 | swap %d1 | |
60 | jra 2f | |
61 | 1: addq.w #1,%d1 | count the # of registers in | |
62 | 2: lsr.b #1,%d0 | register list and keep it in %d1 | |
63 | jcs 1b | |
64 | jne 2b | |
65 | printf PDECODE,"#%08x",1,%d1 | |
66 | #ifdef FPU_EMU_DEBUG | |
67 | btst #12,%d2 | |
68 | jne 1f | |
69 | printf PDECODE,"-" | decremental move | |
70 | jra 2f | |
71 | 1: printf PDECODE,"+" | incremental move | |
72 | 2: btst #13,%d2 | |
73 | jeq 1f | |
74 | printf PDECODE,"->" | fpu -> cpu | |
75 | jra 2f | |
76 | 1: printf PDECODE,"<-" | fpu <- cpu | |
77 | 2: | |
78 | #endif | |
79 | ||
80 | | decode address mode | |
81 | fp_decode_addr_mode | |
82 | ||
83 | .long fp_ill, fp_ill | |
84 | .long fpr_indirect, fpr_postinc | |
85 | .long fpr_predecr, fpr_disp16 | |
86 | .long fpr_extmode0, fpr_extmode1 | |
87 | ||
88 | | addressing mode: address register indirect | |
89 | fpr_indirect: | |
90 | fp_mode_addr_indirect | |
91 | jra fpr_do_movem | |
92 | ||
93 | | addressing mode: address register indirect with postincrement | |
94 | fpr_postinc: | |
95 | fp_mode_addr_indirect_postinc | |
96 | jra fpr_do_movem | |
97 | ||
98 | fpr_predecr: | |
99 | fp_mode_addr_indirect_predec | |
100 | jra fpr_do_movem | |
101 | ||
102 | | addressing mode: address register/programm counter indirect | |
103 | | with 16bit displacement | |
104 | fpr_disp16: | |
105 | fp_mode_addr_indirect_disp16 | |
106 | jra fpr_do_movem | |
107 | ||
108 | fpr_extmode0: | |
109 | fp_mode_addr_indirect_extmode0 | |
110 | jra fpr_do_movem | |
111 | ||
112 | fpr_extmode1: | |
113 | fp_decode_addr_reg | |
114 | jmp ([0f:w,%pc,%d0*4]) | |
115 | ||
116 | .align 4 | |
117 | 0: | |
118 | .long fpr_absolute_short, fpr_absolute_long | |
119 | .long fpr_disp16, fpr_extmode0 | |
120 | .long fp_ill, fp_ill | |
121 | .long fp_ill, fp_ill | |
122 | ||
123 | fpr_absolute_short: | |
124 | fp_mode_abs_short | |
125 | jra fpr_do_movem | |
126 | ||
127 | fpr_absolute_long: | |
128 | fp_mode_abs_long | |
129 | | jra fpr_do_movem | |
130 | ||
131 | fpr_do_movem: | |
132 | swap %d1 | get fpu register list | |
133 | lea (FPD_FPREG,FPDATA),%a1 | |
134 | moveq #12,%d0 | |
135 | btst #12,%d2 | |
136 | jne 1f | |
137 | lea (-12,%a1,%d0*8),%a1 | |
138 | neg.l %d0 | |
139 | 1: btst #13,%d2 | |
140 | jne 4f | |
141 | | move register from memory into fpu | |
142 | jra 3f | |
143 | 1: printf PMOVEM,"(%p>%p)",2,%a0,%a1 | |
144 | getuser.l (%a0)+,%d2,fp_err_ua1,%a0 | |
145 | lsr.l #8,%d2 | |
146 | lsr.l #7,%d2 | |
147 | lsr.w #1,%d2 | |
148 | move.l %d2,(%a1)+ | |
149 | getuser.l (%a0)+,%d2,fp_err_ua1,%a0 | |
150 | move.l %d2,(%a1)+ | |
151 | getuser.l (%a0),%d2,fp_err_ua1,%a0 | |
152 | move.l %d2,(%a1) | |
153 | subq.l #8,%a0 | |
154 | subq.l #8,%a1 | |
155 | add.l %d0,%a0 | |
156 | 2: add.l %d0,%a1 | |
157 | 3: lsl.b #1,%d1 | |
158 | jcs 1b | |
159 | jne 2b | |
160 | jra 5f | |
161 | | move register from fpu into memory | |
162 | 1: printf PMOVEM,"(%p>%p)",2,%a1,%a0 | |
163 | move.l (%a1)+,%d2 | |
164 | lsl.w #1,%d2 | |
165 | lsl.l #7,%d2 | |
166 | lsl.l #8,%d2 | |
167 | putuser.l %d2,(%a0)+,fp_err_ua1,%a0 | |
168 | move.l (%a1)+,%d2 | |
169 | putuser.l %d2,(%a0)+,fp_err_ua1,%a0 | |
170 | move.l (%a1),%d2 | |
171 | putuser.l %d2,(%a0),fp_err_ua1,%a0 | |
172 | subq.l #8,%a1 | |
173 | subq.l #8,%a0 | |
174 | add.l %d0,%a0 | |
175 | 2: add.l %d0,%a1 | |
176 | 4: lsl.b #1,%d1 | |
177 | jcs 1b | |
178 | jne 2b | |
179 | 5: | |
180 | printf PDECODE,"\n" | |
181 | #if 0 | |
182 | lea (FPD_FPREG,FPDATA),%a0 | |
183 | printf PMOVEM,"fp:" | |
184 | printx PMOVEM,%a0@(0) | |
185 | printx PMOVEM,%a0@(12) | |
186 | printf PMOVEM,"\n " | |
187 | printx PMOVEM,%a0@(24) | |
188 | printx PMOVEM,%a0@(36) | |
189 | printf PMOVEM,"\n " | |
190 | printx PMOVEM,%a0@(48) | |
191 | printx PMOVEM,%a0@(60) | |
192 | printf PMOVEM,"\n " | |
193 | printx PMOVEM,%a0@(72) | |
194 | printx PMOVEM,%a0@(84) | |
195 | printf PMOVEM,"\n" | |
196 | #endif | |
197 | jra fp_end | |
198 | ||
199 | | set flags for decode macros for fmovem control register | |
200 | do_fmovem=1 | |
201 | do_fmovem_cr=1 | |
202 | ||
203 | fp_fmovem_cr: | |
204 | printf PDECODE,"fmovem.cr " | |
205 | | get register list and count them | |
206 | bfextu %d2{#19,#3},%d0 | |
207 | move.l %d0,%d1 | |
208 | swap %d1 | |
209 | jra 2f | |
210 | 1: addq.w #1,%d1 | |
211 | 2: lsr.l #1,%d0 | |
212 | jcs 1b | |
213 | jne 2b | |
214 | printf PDECODE,"#%08x",1,%d1 | |
215 | #ifdef FPU_EMU_DEBUG | |
216 | btst #13,%d2 | |
217 | jeq 1f | |
218 | printf PDECODE,"->" | fpu -> cpu | |
219 | jra 2f | |
220 | 1: printf PDECODE,"<-" | fpu <- cpu | |
221 | 2: | |
222 | #endif | |
223 | ||
224 | | decode address mode | |
225 | fp_decode_addr_mode | |
226 | ||
227 | .long fpc_data, fpc_addr | |
228 | .long fpc_indirect, fpc_postinc | |
229 | .long fpc_predecr, fpc_disp16 | |
230 | .long fpc_extmode0, fpc_extmode1 | |
231 | ||
232 | fpc_data: | |
233 | fp_mode_data_direct | |
234 | move.w %d0,%d1 | |
235 | bfffo %d2{#19,#3},%d0 | |
236 | sub.w #19,%d0 | |
237 | lea (FPD_FPCR,FPDATA,%d0.w*4),%a1 | |
238 | btst #13,%d2 | |
239 | jne 1f | |
240 | move.w %d1,%d0 | |
241 | jsr fp_get_data_reg | |
242 | move.l %d0,(%a1) | |
243 | jra fpc_movem_fin | |
244 | 1: move.l (%a1),%d0 | |
245 | jsr fp_put_data_reg | |
246 | jra fpc_movem_fin | |
247 | ||
248 | fpc_addr: | |
249 | fp_decode_addr_reg | |
250 | printf PDECODE,"a%d",1,%d0 | |
251 | btst #13,%d2 | |
252 | jne 1f | |
253 | jsr fp_get_addr_reg | |
254 | move.l %a0,(FPD_FPIAR,FPDATA) | |
255 | jra fpc_movem_fin | |
256 | 1: move.l (FPD_FPIAR,FPDATA),%a0 | |
257 | jsr fp_put_addr_reg | |
258 | jra fpc_movem_fin | |
259 | ||
260 | fpc_indirect: | |
261 | fp_mode_addr_indirect | |
262 | jra fpc_do_movem | |
263 | ||
264 | fpc_postinc: | |
265 | fp_mode_addr_indirect_postinc | |
266 | jra fpc_do_movem | |
267 | ||
268 | fpc_predecr: | |
269 | fp_mode_addr_indirect_predec | |
270 | jra fpc_do_movem | |
271 | ||
272 | fpc_disp16: | |
273 | fp_mode_addr_indirect_disp16 | |
274 | jra fpc_do_movem | |
275 | ||
276 | fpc_extmode0: | |
277 | fp_mode_addr_indirect_extmode0 | |
278 | jra fpc_do_movem | |
279 | ||
280 | fpc_extmode1: | |
281 | fp_decode_addr_reg | |
282 | jmp ([0f:w,%pc,%d0*4]) | |
283 | ||
284 | .align 4 | |
285 | 0: | |
286 | .long fpc_absolute_short, fpc_absolute_long | |
287 | .long fpc_disp16, fpc_extmode0 | |
288 | .long fpc_immediate, fp_ill | |
289 | .long fp_ill, fp_ill | |
290 | ||
291 | fpc_absolute_short: | |
292 | fp_mode_abs_short | |
293 | jra fpc_do_movem | |
294 | ||
295 | fpc_absolute_long: | |
296 | fp_mode_abs_long | |
297 | jra fpc_do_movem | |
298 | ||
299 | fpc_immediate: | |
300 | fp_get_pc %a0 | |
301 | lea (%a0,%d1.w*4),%a1 | |
302 | fp_put_pc %a1 | |
303 | printf PDECODE,"#imm" | |
304 | | jra fpc_do_movem | |
305 | #if 0 | |
306 | swap %d1 | |
307 | lsl.l #5,%d1 | |
308 | lea (FPD_FPCR,FPDATA),%a0 | |
309 | jra 3f | |
310 | 1: move.l %d0,(%a0) | |
311 | 2: addq.l #4,%a0 | |
312 | 3: lsl.b #1,%d1 | |
313 | jcs 1b | |
314 | jne 2b | |
315 | jra fpc_movem_fin | |
316 | #endif | |
317 | ||
318 | fpc_do_movem: | |
319 | swap %d1 | get fpu register list | |
320 | lsl.l #5,%d1 | |
321 | lea (FPD_FPCR,FPDATA),%a1 | |
322 | 1: btst #13,%d2 | |
323 | jne 4f | |
324 | ||
325 | | move register from memory into fpu | |
326 | jra 3f | |
327 | 1: printf PMOVEM,"(%p>%p)",2,%a0,%a1 | |
328 | getuser.l (%a0)+,%d0,fp_err_ua1,%a0 | |
329 | move.l %d0,(%a1) | |
330 | 2: addq.l #4,%a1 | |
331 | 3: lsl.b #1,%d1 | |
332 | jcs 1b | |
333 | jne 2b | |
334 | jra fpc_movem_fin | |
335 | ||
336 | | move register from fpu into memory | |
337 | 1: printf PMOVEM,"(%p>%p)",2,%a1,%a0 | |
338 | move.l (%a1),%d0 | |
339 | putuser.l %d0,(%a0)+,fp_err_ua1,%a0 | |
340 | 2: addq.l #4,%a1 | |
341 | 4: lsl.b #1,%d1 | |
342 | jcs 1b | |
343 | jne 2b | |
344 | ||
345 | fpc_movem_fin: | |
346 | and.l #0x0000fff0,(FPD_FPCR,FPDATA) | |
347 | and.l #0x0ffffff8,(FPD_FPSR,FPDATA) | |
348 | move.l (FPD_FPCR,FPDATA),%d0 | |
349 | lsr.l #4,%d0 | |
350 | moveq #3,%d1 | |
351 | and.l %d0,%d1 | |
352 | move.w %d1,(FPD_RND,FPDATA) | |
353 | lsr.l #2,%d0 | |
354 | moveq #3,%d1 | |
355 | and.l %d0,%d1 | |
356 | move.w %d1,(FPD_PREC,FPDATA) | |
357 | printf PDECODE,"\n" | |
358 | #if 0 | |
359 | printf PMOVEM,"fpcr : %08x\n",1,FPDATA@(FPD_FPCR) | |
360 | printf PMOVEM,"fpsr : %08x\n",1,FPDATA@(FPD_FPSR) | |
361 | printf PMOVEM,"fpiar: %08x\n",1,FPDATA@(FPD_FPIAR) | |
362 | clr.l %d0 | |
363 | move.w (FPD_PREC,FPDATA),%d0 | |
364 | printf PMOVEM,"prec : %04x\n",1,%d0 | |
365 | move.w (FPD_RND,FPDATA),%d0 | |
366 | printf PMOVEM,"rnd : %04x\n",1,%d0 | |
367 | #endif | |
368 | jra fp_end |