linux/arch/m68k/math-emu/fp_movem.S
<<
>>
Prefs
   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