blob: 8354d39e6c47b31941326e049ea45f799e84ce38 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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
42do_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
49fp_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
561: bfextu %d2{#25,#3},%d0 | dynamic register list
57 jsr fp_get_data_reg
582: move.l %d0,%d1
59 swap %d1
60 jra 2f
611: addq.w #1,%d1 | count the # of registers in
622: 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
711: printf PDECODE,"+" | incremental move
722: btst #13,%d2
73 jeq 1f
74 printf PDECODE,"->" | fpu -> cpu
75 jra 2f
761: printf PDECODE,"<-" | fpu <- cpu
772:
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
89fpr_indirect:
90 fp_mode_addr_indirect
91 jra fpr_do_movem
92
93 | addressing mode: address register indirect with postincrement
94fpr_postinc:
95 fp_mode_addr_indirect_postinc
96 jra fpr_do_movem
97
98fpr_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
104fpr_disp16:
105 fp_mode_addr_indirect_disp16
106 jra fpr_do_movem
107
108fpr_extmode0:
109 fp_mode_addr_indirect_extmode0
110 jra fpr_do_movem
111
112fpr_extmode1:
113 fp_decode_addr_reg
114 jmp ([0f:w,%pc,%d0*4])
115
116 .align 4
1170:
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
123fpr_absolute_short:
124 fp_mode_abs_short
125 jra fpr_do_movem
126
127fpr_absolute_long:
128 fp_mode_abs_long
129| jra fpr_do_movem
130
131fpr_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
1391: btst #13,%d2
140 jne 4f
141 | move register from memory into fpu
142 jra 3f
1431: 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
1562: add.l %d0,%a1
1573: lsl.b #1,%d1
158 jcs 1b
159 jne 2b
160 jra 5f
161 | move register from fpu into memory
1621: 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
1752: add.l %d0,%a1
1764: lsl.b #1,%d1
177 jcs 1b
178 jne 2b
1795:
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
200do_fmovem=1
201do_fmovem_cr=1
202
203fp_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
2101: addq.w #1,%d1
2112: 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
2201: printf PDECODE,"<-" | fpu <- cpu
2212:
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
232fpc_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
2441: move.l (%a1),%d0
245 jsr fp_put_data_reg
246 jra fpc_movem_fin
247
248fpc_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
2561: move.l (FPD_FPIAR,FPDATA),%a0
257 jsr fp_put_addr_reg
258 jra fpc_movem_fin
259
260fpc_indirect:
261 fp_mode_addr_indirect
262 jra fpc_do_movem
263
264fpc_postinc:
265 fp_mode_addr_indirect_postinc
266 jra fpc_do_movem
267
268fpc_predecr:
269 fp_mode_addr_indirect_predec
270 jra fpc_do_movem
271
272fpc_disp16:
273 fp_mode_addr_indirect_disp16
274 jra fpc_do_movem
275
276fpc_extmode0:
277 fp_mode_addr_indirect_extmode0
278 jra fpc_do_movem
279
280fpc_extmode1:
281 fp_decode_addr_reg
282 jmp ([0f:w,%pc,%d0*4])
283
284 .align 4
2850:
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
291fpc_absolute_short:
292 fp_mode_abs_short
293 jra fpc_do_movem
294
295fpc_absolute_long:
296 fp_mode_abs_long
297 jra fpc_do_movem
298
299fpc_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
3101: move.l %d0,(%a0)
3112: addq.l #4,%a0
3123: lsl.b #1,%d1
313 jcs 1b
314 jne 2b
315 jra fpc_movem_fin
316#endif
317
318fpc_do_movem:
319 swap %d1 | get fpu register list
320 lsl.l #5,%d1
321 lea (FPD_FPCR,FPDATA),%a1
3221: btst #13,%d2
323 jne 4f
324
325 | move register from memory into fpu
326 jra 3f
3271: printf PMOVEM,"(%p>%p)",2,%a0,%a1
328 getuser.l (%a0)+,%d0,fp_err_ua1,%a0
329 move.l %d0,(%a1)
3302: addq.l #4,%a1
3313: lsl.b #1,%d1
332 jcs 1b
333 jne 2b
334 jra fpc_movem_fin
335
336 | move register from fpu into memory
3371: printf PMOVEM,"(%p>%p)",2,%a1,%a0
338 move.l (%a1),%d0
339 putuser.l %d0,(%a0)+,fp_err_ua1,%a0
3402: addq.l #4,%a1
3414: lsl.b #1,%d1
342 jcs 1b
343 jne 2b
344
345fpc_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