1*4882a593Smuzhiyun/* 2*4882a593Smuzhiyun * fp_movem.S 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * Copyright Roman Zippel, 1997. All rights reserved. 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * Redistribution and use in source and binary forms, with or without 7*4882a593Smuzhiyun * modification, are permitted provided that the following conditions 8*4882a593Smuzhiyun * are met: 9*4882a593Smuzhiyun * 1. Redistributions of source code must retain the above copyright 10*4882a593Smuzhiyun * notice, and the entire permission notice in its entirety, 11*4882a593Smuzhiyun * including the disclaimer of warranties. 12*4882a593Smuzhiyun * 2. Redistributions in binary form must reproduce the above copyright 13*4882a593Smuzhiyun * notice, this list of conditions and the following disclaimer in the 14*4882a593Smuzhiyun * documentation and/or other materials provided with the distribution. 15*4882a593Smuzhiyun * 3. The name of the author may not be used to endorse or promote 16*4882a593Smuzhiyun * products derived from this software without specific prior 17*4882a593Smuzhiyun * written permission. 18*4882a593Smuzhiyun * 19*4882a593Smuzhiyun * ALTERNATIVELY, this product may be distributed under the terms of 20*4882a593Smuzhiyun * the GNU General Public License, in which case the provisions of the GPL are 21*4882a593Smuzhiyun * required INSTEAD OF the above restrictions. (This clause is 22*4882a593Smuzhiyun * necessary due to a potential bad interaction between the GPL and 23*4882a593Smuzhiyun * the restrictions contained in a BSD-style copyright.) 24*4882a593Smuzhiyun * 25*4882a593Smuzhiyun * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 26*4882a593Smuzhiyun * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27*4882a593Smuzhiyun * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28*4882a593Smuzhiyun * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 29*4882a593Smuzhiyun * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30*4882a593Smuzhiyun * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31*4882a593Smuzhiyun * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32*4882a593Smuzhiyun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 33*4882a593Smuzhiyun * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34*4882a593Smuzhiyun * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 35*4882a593Smuzhiyun * OF THE POSSIBILITY OF SUCH DAMAGE. 36*4882a593Smuzhiyun */ 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun#include "fp_emu.h" 39*4882a593Smuzhiyun#include "fp_decode.h" 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun| set flags for decode macros for fmovem 42*4882a593Smuzhiyundo_fmovem=1 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun .globl fp_fmovem_fp, fp_fmovem_cr 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun| %d1 contains the mask and count of the register list 47*4882a593Smuzhiyun| for other register usage see fp_decode.h 48*4882a593Smuzhiyun 49*4882a593Smuzhiyunfp_fmovem_fp: 50*4882a593Smuzhiyun printf PDECODE,"fmovem.x " 51*4882a593Smuzhiyun | get register list and count them 52*4882a593Smuzhiyun btst #11,%d2 53*4882a593Smuzhiyun jne 1f 54*4882a593Smuzhiyun bfextu %d2{#24,#8},%d0 | static register list 55*4882a593Smuzhiyun jra 2f 56*4882a593Smuzhiyun1: bfextu %d2{#25,#3},%d0 | dynamic register list 57*4882a593Smuzhiyun jsr fp_get_data_reg 58*4882a593Smuzhiyun2: move.l %d0,%d1 59*4882a593Smuzhiyun swap %d1 60*4882a593Smuzhiyun jra 2f 61*4882a593Smuzhiyun1: addq.w #1,%d1 | count the # of registers in 62*4882a593Smuzhiyun2: lsr.b #1,%d0 | register list and keep it in %d1 63*4882a593Smuzhiyun jcs 1b 64*4882a593Smuzhiyun jne 2b 65*4882a593Smuzhiyun printf PDECODE,"#%08x",1,%d1 66*4882a593Smuzhiyun#ifdef FPU_EMU_DEBUG 67*4882a593Smuzhiyun btst #12,%d2 68*4882a593Smuzhiyun jne 1f 69*4882a593Smuzhiyun printf PDECODE,"-" | decremental move 70*4882a593Smuzhiyun jra 2f 71*4882a593Smuzhiyun1: printf PDECODE,"+" | incremental move 72*4882a593Smuzhiyun2: btst #13,%d2 73*4882a593Smuzhiyun jeq 1f 74*4882a593Smuzhiyun printf PDECODE,"->" | fpu -> cpu 75*4882a593Smuzhiyun jra 2f 76*4882a593Smuzhiyun1: printf PDECODE,"<-" | fpu <- cpu 77*4882a593Smuzhiyun2: 78*4882a593Smuzhiyun#endif 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun | decode address mode 81*4882a593Smuzhiyun fp_decode_addr_mode 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun .long fp_ill, fp_ill 84*4882a593Smuzhiyun .long fpr_indirect, fpr_postinc 85*4882a593Smuzhiyun .long fpr_predecr, fpr_disp16 86*4882a593Smuzhiyun .long fpr_extmode0, fpr_extmode1 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun | addressing mode: address register indirect 89*4882a593Smuzhiyunfpr_indirect: 90*4882a593Smuzhiyun fp_mode_addr_indirect 91*4882a593Smuzhiyun jra fpr_do_movem 92*4882a593Smuzhiyun 93*4882a593Smuzhiyun | addressing mode: address register indirect with postincrement 94*4882a593Smuzhiyunfpr_postinc: 95*4882a593Smuzhiyun fp_mode_addr_indirect_postinc 96*4882a593Smuzhiyun jra fpr_do_movem 97*4882a593Smuzhiyun 98*4882a593Smuzhiyunfpr_predecr: 99*4882a593Smuzhiyun fp_mode_addr_indirect_predec 100*4882a593Smuzhiyun jra fpr_do_movem 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun | addressing mode: address register/programm counter indirect 103*4882a593Smuzhiyun | with 16bit displacement 104*4882a593Smuzhiyunfpr_disp16: 105*4882a593Smuzhiyun fp_mode_addr_indirect_disp16 106*4882a593Smuzhiyun jra fpr_do_movem 107*4882a593Smuzhiyun 108*4882a593Smuzhiyunfpr_extmode0: 109*4882a593Smuzhiyun fp_mode_addr_indirect_extmode0 110*4882a593Smuzhiyun jra fpr_do_movem 111*4882a593Smuzhiyun 112*4882a593Smuzhiyunfpr_extmode1: 113*4882a593Smuzhiyun fp_decode_addr_reg 114*4882a593Smuzhiyun jmp ([0f:w,%pc,%d0*4]) 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun .align 4 117*4882a593Smuzhiyun0: 118*4882a593Smuzhiyun .long fpr_absolute_short, fpr_absolute_long 119*4882a593Smuzhiyun .long fpr_disp16, fpr_extmode0 120*4882a593Smuzhiyun .long fp_ill, fp_ill 121*4882a593Smuzhiyun .long fp_ill, fp_ill 122*4882a593Smuzhiyun 123*4882a593Smuzhiyunfpr_absolute_short: 124*4882a593Smuzhiyun fp_mode_abs_short 125*4882a593Smuzhiyun jra fpr_do_movem 126*4882a593Smuzhiyun 127*4882a593Smuzhiyunfpr_absolute_long: 128*4882a593Smuzhiyun fp_mode_abs_long 129*4882a593Smuzhiyun| jra fpr_do_movem 130*4882a593Smuzhiyun 131*4882a593Smuzhiyunfpr_do_movem: 132*4882a593Smuzhiyun swap %d1 | get fpu register list 133*4882a593Smuzhiyun lea (FPD_FPREG,FPDATA),%a1 134*4882a593Smuzhiyun moveq #12,%d0 135*4882a593Smuzhiyun btst #12,%d2 136*4882a593Smuzhiyun jne 1f 137*4882a593Smuzhiyun lea (-12,%a1,%d0*8),%a1 138*4882a593Smuzhiyun neg.l %d0 139*4882a593Smuzhiyun1: btst #13,%d2 140*4882a593Smuzhiyun jne 4f 141*4882a593Smuzhiyun | move register from memory into fpu 142*4882a593Smuzhiyun jra 3f 143*4882a593Smuzhiyun1: printf PMOVEM,"(%p>%p)",2,%a0,%a1 144*4882a593Smuzhiyun getuser.l (%a0)+,%d2,fp_err_ua1,%a0 145*4882a593Smuzhiyun lsr.l #8,%d2 146*4882a593Smuzhiyun lsr.l #7,%d2 147*4882a593Smuzhiyun lsr.w #1,%d2 148*4882a593Smuzhiyun move.l %d2,(%a1)+ 149*4882a593Smuzhiyun getuser.l (%a0)+,%d2,fp_err_ua1,%a0 150*4882a593Smuzhiyun move.l %d2,(%a1)+ 151*4882a593Smuzhiyun getuser.l (%a0),%d2,fp_err_ua1,%a0 152*4882a593Smuzhiyun move.l %d2,(%a1) 153*4882a593Smuzhiyun subq.l #8,%a0 154*4882a593Smuzhiyun subq.l #8,%a1 155*4882a593Smuzhiyun add.l %d0,%a0 156*4882a593Smuzhiyun2: add.l %d0,%a1 157*4882a593Smuzhiyun3: lsl.b #1,%d1 158*4882a593Smuzhiyun jcs 1b 159*4882a593Smuzhiyun jne 2b 160*4882a593Smuzhiyun jra 5f 161*4882a593Smuzhiyun | move register from fpu into memory 162*4882a593Smuzhiyun1: printf PMOVEM,"(%p>%p)",2,%a1,%a0 163*4882a593Smuzhiyun move.l (%a1)+,%d2 164*4882a593Smuzhiyun lsl.w #1,%d2 165*4882a593Smuzhiyun lsl.l #7,%d2 166*4882a593Smuzhiyun lsl.l #8,%d2 167*4882a593Smuzhiyun putuser.l %d2,(%a0)+,fp_err_ua1,%a0 168*4882a593Smuzhiyun move.l (%a1)+,%d2 169*4882a593Smuzhiyun putuser.l %d2,(%a0)+,fp_err_ua1,%a0 170*4882a593Smuzhiyun move.l (%a1),%d2 171*4882a593Smuzhiyun putuser.l %d2,(%a0),fp_err_ua1,%a0 172*4882a593Smuzhiyun subq.l #8,%a1 173*4882a593Smuzhiyun subq.l #8,%a0 174*4882a593Smuzhiyun add.l %d0,%a0 175*4882a593Smuzhiyun2: add.l %d0,%a1 176*4882a593Smuzhiyun4: lsl.b #1,%d1 177*4882a593Smuzhiyun jcs 1b 178*4882a593Smuzhiyun jne 2b 179*4882a593Smuzhiyun5: 180*4882a593Smuzhiyun printf PDECODE,"\n" 181*4882a593Smuzhiyun#if 0 182*4882a593Smuzhiyun lea (FPD_FPREG,FPDATA),%a0 183*4882a593Smuzhiyun printf PMOVEM,"fp:" 184*4882a593Smuzhiyun printx PMOVEM,%a0@(0) 185*4882a593Smuzhiyun printx PMOVEM,%a0@(12) 186*4882a593Smuzhiyun printf PMOVEM,"\n " 187*4882a593Smuzhiyun printx PMOVEM,%a0@(24) 188*4882a593Smuzhiyun printx PMOVEM,%a0@(36) 189*4882a593Smuzhiyun printf PMOVEM,"\n " 190*4882a593Smuzhiyun printx PMOVEM,%a0@(48) 191*4882a593Smuzhiyun printx PMOVEM,%a0@(60) 192*4882a593Smuzhiyun printf PMOVEM,"\n " 193*4882a593Smuzhiyun printx PMOVEM,%a0@(72) 194*4882a593Smuzhiyun printx PMOVEM,%a0@(84) 195*4882a593Smuzhiyun printf PMOVEM,"\n" 196*4882a593Smuzhiyun#endif 197*4882a593Smuzhiyun jra fp_end 198*4882a593Smuzhiyun 199*4882a593Smuzhiyun| set flags for decode macros for fmovem control register 200*4882a593Smuzhiyundo_fmovem=1 201*4882a593Smuzhiyundo_fmovem_cr=1 202*4882a593Smuzhiyun 203*4882a593Smuzhiyunfp_fmovem_cr: 204*4882a593Smuzhiyun printf PDECODE,"fmovem.cr " 205*4882a593Smuzhiyun | get register list and count them 206*4882a593Smuzhiyun bfextu %d2{#19,#3},%d0 207*4882a593Smuzhiyun move.l %d0,%d1 208*4882a593Smuzhiyun swap %d1 209*4882a593Smuzhiyun jra 2f 210*4882a593Smuzhiyun1: addq.w #1,%d1 211*4882a593Smuzhiyun2: lsr.l #1,%d0 212*4882a593Smuzhiyun jcs 1b 213*4882a593Smuzhiyun jne 2b 214*4882a593Smuzhiyun printf PDECODE,"#%08x",1,%d1 215*4882a593Smuzhiyun#ifdef FPU_EMU_DEBUG 216*4882a593Smuzhiyun btst #13,%d2 217*4882a593Smuzhiyun jeq 1f 218*4882a593Smuzhiyun printf PDECODE,"->" | fpu -> cpu 219*4882a593Smuzhiyun jra 2f 220*4882a593Smuzhiyun1: printf PDECODE,"<-" | fpu <- cpu 221*4882a593Smuzhiyun2: 222*4882a593Smuzhiyun#endif 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun | decode address mode 225*4882a593Smuzhiyun fp_decode_addr_mode 226*4882a593Smuzhiyun 227*4882a593Smuzhiyun .long fpc_data, fpc_addr 228*4882a593Smuzhiyun .long fpc_indirect, fpc_postinc 229*4882a593Smuzhiyun .long fpc_predecr, fpc_disp16 230*4882a593Smuzhiyun .long fpc_extmode0, fpc_extmode1 231*4882a593Smuzhiyun 232*4882a593Smuzhiyunfpc_data: 233*4882a593Smuzhiyun fp_mode_data_direct 234*4882a593Smuzhiyun move.w %d0,%d1 235*4882a593Smuzhiyun bfffo %d2{#19,#3},%d0 236*4882a593Smuzhiyun sub.w #19,%d0 237*4882a593Smuzhiyun lea (FPD_FPCR,FPDATA,%d0.w*4),%a1 238*4882a593Smuzhiyun btst #13,%d2 239*4882a593Smuzhiyun jne 1f 240*4882a593Smuzhiyun move.w %d1,%d0 241*4882a593Smuzhiyun jsr fp_get_data_reg 242*4882a593Smuzhiyun move.l %d0,(%a1) 243*4882a593Smuzhiyun jra fpc_movem_fin 244*4882a593Smuzhiyun1: move.l (%a1),%d0 245*4882a593Smuzhiyun jsr fp_put_data_reg 246*4882a593Smuzhiyun jra fpc_movem_fin 247*4882a593Smuzhiyun 248*4882a593Smuzhiyunfpc_addr: 249*4882a593Smuzhiyun fp_decode_addr_reg 250*4882a593Smuzhiyun printf PDECODE,"a%d",1,%d0 251*4882a593Smuzhiyun btst #13,%d2 252*4882a593Smuzhiyun jne 1f 253*4882a593Smuzhiyun jsr fp_get_addr_reg 254*4882a593Smuzhiyun move.l %a0,(FPD_FPIAR,FPDATA) 255*4882a593Smuzhiyun jra fpc_movem_fin 256*4882a593Smuzhiyun1: move.l (FPD_FPIAR,FPDATA),%a0 257*4882a593Smuzhiyun jsr fp_put_addr_reg 258*4882a593Smuzhiyun jra fpc_movem_fin 259*4882a593Smuzhiyun 260*4882a593Smuzhiyunfpc_indirect: 261*4882a593Smuzhiyun fp_mode_addr_indirect 262*4882a593Smuzhiyun jra fpc_do_movem 263*4882a593Smuzhiyun 264*4882a593Smuzhiyunfpc_postinc: 265*4882a593Smuzhiyun fp_mode_addr_indirect_postinc 266*4882a593Smuzhiyun jra fpc_do_movem 267*4882a593Smuzhiyun 268*4882a593Smuzhiyunfpc_predecr: 269*4882a593Smuzhiyun fp_mode_addr_indirect_predec 270*4882a593Smuzhiyun jra fpc_do_movem 271*4882a593Smuzhiyun 272*4882a593Smuzhiyunfpc_disp16: 273*4882a593Smuzhiyun fp_mode_addr_indirect_disp16 274*4882a593Smuzhiyun jra fpc_do_movem 275*4882a593Smuzhiyun 276*4882a593Smuzhiyunfpc_extmode0: 277*4882a593Smuzhiyun fp_mode_addr_indirect_extmode0 278*4882a593Smuzhiyun jra fpc_do_movem 279*4882a593Smuzhiyun 280*4882a593Smuzhiyunfpc_extmode1: 281*4882a593Smuzhiyun fp_decode_addr_reg 282*4882a593Smuzhiyun jmp ([0f:w,%pc,%d0*4]) 283*4882a593Smuzhiyun 284*4882a593Smuzhiyun .align 4 285*4882a593Smuzhiyun0: 286*4882a593Smuzhiyun .long fpc_absolute_short, fpc_absolute_long 287*4882a593Smuzhiyun .long fpc_disp16, fpc_extmode0 288*4882a593Smuzhiyun .long fpc_immediate, fp_ill 289*4882a593Smuzhiyun .long fp_ill, fp_ill 290*4882a593Smuzhiyun 291*4882a593Smuzhiyunfpc_absolute_short: 292*4882a593Smuzhiyun fp_mode_abs_short 293*4882a593Smuzhiyun jra fpc_do_movem 294*4882a593Smuzhiyun 295*4882a593Smuzhiyunfpc_absolute_long: 296*4882a593Smuzhiyun fp_mode_abs_long 297*4882a593Smuzhiyun jra fpc_do_movem 298*4882a593Smuzhiyun 299*4882a593Smuzhiyunfpc_immediate: 300*4882a593Smuzhiyun fp_get_pc %a0 301*4882a593Smuzhiyun lea (%a0,%d1.w*4),%a1 302*4882a593Smuzhiyun fp_put_pc %a1 303*4882a593Smuzhiyun printf PDECODE,"#imm" 304*4882a593Smuzhiyun| jra fpc_do_movem 305*4882a593Smuzhiyun#if 0 306*4882a593Smuzhiyun swap %d1 307*4882a593Smuzhiyun lsl.l #5,%d1 308*4882a593Smuzhiyun lea (FPD_FPCR,FPDATA),%a0 309*4882a593Smuzhiyun jra 3f 310*4882a593Smuzhiyun1: move.l %d0,(%a0) 311*4882a593Smuzhiyun2: addq.l #4,%a0 312*4882a593Smuzhiyun3: lsl.b #1,%d1 313*4882a593Smuzhiyun jcs 1b 314*4882a593Smuzhiyun jne 2b 315*4882a593Smuzhiyun jra fpc_movem_fin 316*4882a593Smuzhiyun#endif 317*4882a593Smuzhiyun 318*4882a593Smuzhiyunfpc_do_movem: 319*4882a593Smuzhiyun swap %d1 | get fpu register list 320*4882a593Smuzhiyun lsl.l #5,%d1 321*4882a593Smuzhiyun lea (FPD_FPCR,FPDATA),%a1 322*4882a593Smuzhiyun1: btst #13,%d2 323*4882a593Smuzhiyun jne 4f 324*4882a593Smuzhiyun 325*4882a593Smuzhiyun | move register from memory into fpu 326*4882a593Smuzhiyun jra 3f 327*4882a593Smuzhiyun1: printf PMOVEM,"(%p>%p)",2,%a0,%a1 328*4882a593Smuzhiyun getuser.l (%a0)+,%d0,fp_err_ua1,%a0 329*4882a593Smuzhiyun move.l %d0,(%a1) 330*4882a593Smuzhiyun2: addq.l #4,%a1 331*4882a593Smuzhiyun3: lsl.b #1,%d1 332*4882a593Smuzhiyun jcs 1b 333*4882a593Smuzhiyun jne 2b 334*4882a593Smuzhiyun jra fpc_movem_fin 335*4882a593Smuzhiyun 336*4882a593Smuzhiyun | move register from fpu into memory 337*4882a593Smuzhiyun1: printf PMOVEM,"(%p>%p)",2,%a1,%a0 338*4882a593Smuzhiyun move.l (%a1),%d0 339*4882a593Smuzhiyun putuser.l %d0,(%a0)+,fp_err_ua1,%a0 340*4882a593Smuzhiyun2: addq.l #4,%a1 341*4882a593Smuzhiyun4: lsl.b #1,%d1 342*4882a593Smuzhiyun jcs 1b 343*4882a593Smuzhiyun jne 2b 344*4882a593Smuzhiyun 345*4882a593Smuzhiyunfpc_movem_fin: 346*4882a593Smuzhiyun and.l #0x0000fff0,(FPD_FPCR,FPDATA) 347*4882a593Smuzhiyun and.l #0x0ffffff8,(FPD_FPSR,FPDATA) 348*4882a593Smuzhiyun move.l (FPD_FPCR,FPDATA),%d0 349*4882a593Smuzhiyun lsr.l #4,%d0 350*4882a593Smuzhiyun moveq #3,%d1 351*4882a593Smuzhiyun and.l %d0,%d1 352*4882a593Smuzhiyun move.w %d1,(FPD_RND,FPDATA) 353*4882a593Smuzhiyun lsr.l #2,%d0 354*4882a593Smuzhiyun moveq #3,%d1 355*4882a593Smuzhiyun and.l %d0,%d1 356*4882a593Smuzhiyun move.w %d1,(FPD_PREC,FPDATA) 357*4882a593Smuzhiyun printf PDECODE,"\n" 358*4882a593Smuzhiyun#if 0 359*4882a593Smuzhiyun printf PMOVEM,"fpcr : %08x\n",1,FPDATA@(FPD_FPCR) 360*4882a593Smuzhiyun printf PMOVEM,"fpsr : %08x\n",1,FPDATA@(FPD_FPSR) 361*4882a593Smuzhiyun printf PMOVEM,"fpiar: %08x\n",1,FPDATA@(FPD_FPIAR) 362*4882a593Smuzhiyun clr.l %d0 363*4882a593Smuzhiyun move.w (FPD_PREC,FPDATA),%d0 364*4882a593Smuzhiyun printf PMOVEM,"prec : %04x\n",1,%d0 365*4882a593Smuzhiyun move.w (FPD_RND,FPDATA),%d0 366*4882a593Smuzhiyun printf PMOVEM,"rnd : %04x\n",1,%d0 367*4882a593Smuzhiyun#endif 368*4882a593Smuzhiyun jra fp_end 369