root/arch/m68k/math-emu/fp_movem.S

/* [<][>][^][v][top][bottom][index][help] */
   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

/* [<][>][^][v][top][bottom][index][help] */