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 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 369