root/arch/m68k/math-emu/fp_decode.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. jmp
  2. jmp
  3. jmp
  4. jmp

   1 /*
   2  * fp_decode.h
   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 #ifndef _FP_DECODE_H
  39 #define _FP_DECODE_H
  40 
  41 /* These macros do the dirty work of the instr decoding, several variables
  42  * can be defined in the source file to modify the work of these macros,
  43  * currently the following variables are used:
  44  * ...
  45  * The register usage:
  46  * d0 - will contain source operand for data direct mode,
  47  *      otherwise scratch register
  48  * d1 - upper 16bit are reserved for caller
  49  *      lower 16bit may contain further arguments,
  50  *      is destroyed during decoding
  51  * d2 - contains first two instruction words,
  52  *      first word will be used for extension word
  53  * a0 - will point to source/dest operand for any indirect mode
  54  *      otherwise scratch register
  55  * a1 - scratch register
  56  * a2 - base addr to the task structure
  57  *
  58  * the current implementation doesn't check for every disallowed
  59  * addressing mode (e.g. pc relative modes as destination), as long
  60  * as it only means a new addressing mode, which should not appear
  61  * in a program and that doesn't crash the emulation, I think it's
  62  * not a problem to allow these modes.
  63  */
  64 
  65 do_fmovem=0
  66 do_fmovem_cr=0
  67 do_no_pc_mode=0
  68 do_fscc=0
  69 
  70 | first decoding of the instr type
  71 | this separates the conditional instr
  72 .macro  fp_decode_cond_instr_type
  73         bfextu  %d2{#8,#2},%d0
  74         jmp     ([0f:w,%pc,%d0*4])
  75 
  76         .align  4
  77 0:
  78 |       .long   "f<op>","fscc/fdbcc"
  79 |       .long   "fbccw","fbccl"
  80 .endm
  81 
  82 | second decoding of the instr type
  83 | this separates most move instr
  84 .macro  fp_decode_move_instr_type
  85         bfextu  %d2{#16,#3},%d0
  86         jmp     ([0f:w,%pc,%d0*4])
  87 
  88         .align  4
  89 0:
  90 |       .long   "f<op> fpx,fpx","invalid instr"
  91 |       .long   "f<op> <ea>,fpx","fmove fpx,<ea>"
  92 |       .long   "fmovem <ea>,fpcr","fmovem <ea>,fpx"
  93 |       .long   "fmovem fpcr,<ea>","fmovem fpx,<ea>"
  94 .endm
  95 
  96 | extract the source specifier, specifies
  97 | either source fp register or data format
  98 .macro  fp_decode_sourcespec
  99         bfextu  %d2{#19,#3},%d0
 100 .endm
 101 
 102 | decode destination format for fmove reg,ea
 103 .macro  fp_decode_dest_format
 104         bfextu  %d2{#19,#3},%d0
 105 .endm
 106 
 107 | decode source register for fmove reg,ea
 108 .macro  fp_decode_src_reg
 109         bfextu  %d2{#22,#3},%d0
 110 .endm
 111 
 112 | extract the addressing mode
 113 | it depends on the instr which of the modes is valid
 114 .macro  fp_decode_addr_mode
 115         bfextu  %d2{#10,#3},%d0
 116         jmp     ([0f:w,%pc,%d0*4])
 117 
 118         .align  4
 119 0:
 120 |       .long   "data register direct","addr register direct"
 121 |       .long   "addr register indirect"
 122 |       .long   "addr register indirect postincrement"
 123 |       .long   "addr register indirect predecrement"
 124 |       .long   "addr register + index16"
 125 |       .long   "extension mode1","extension mode2"
 126 .endm
 127 
 128 | extract the register for the addressing mode
 129 .macro  fp_decode_addr_reg
 130         bfextu  %d2{#13,#3},%d0
 131 .endm
 132 
 133 | decode the 8bit displacement from the brief extension word
 134 .macro  fp_decode_disp8
 135         move.b  %d2,%d0
 136         ext.w   %d0
 137 .endm
 138 
 139 | decode the index of the brief/full extension word
 140 .macro  fp_decode_index
 141         bfextu  %d2{#17,#3},%d0         | get the register nr
 142         btst    #15,%d2                 | test for data/addr register
 143         jne     1\@f
 144         printf  PDECODE,"d%d",1,%d0
 145         jsr     fp_get_data_reg
 146         jra     2\@f
 147 1\@:    printf  PDECODE,"a%d",1,%d0
 148         jsr     fp_get_addr_reg
 149         move.l  %a0,%d0
 150 2\@:
 151 debug   lea     "'l'.w,%a0"
 152         btst    #11,%d2                 | 16/32 bit size?
 153         jne     3\@f
 154 debug   lea     "'w'.w,%a0"
 155         ext.l   %d0
 156 3\@:    printf  PDECODE,":%c",1,%a0
 157         move.w  %d2,%d1                 | scale factor
 158         rol.w   #7,%d1
 159         and.w   #3,%d1
 160 debug   move.l  "%d1,-(%sp)"
 161 debug   ext.l   "%d1"
 162         printf  PDECODE,":%d",1,%d1
 163 debug   move.l  "(%sp)+,%d1"
 164         lsl.l   %d1,%d0
 165 .endm
 166 
 167 | decode the base displacement size
 168 .macro  fp_decode_basedisp
 169         bfextu  %d2{#26,#2},%d0
 170         jmp     ([0f:w,%pc,%d0*4])
 171 
 172         .align  4
 173 0:
 174 |       .long   "reserved","null displacement"
 175 |       .long   "word displacement","long displacement"
 176 .endm
 177 
 178 .macro  fp_decode_outerdisp
 179         bfextu  %d2{#30,#2},%d0
 180         jmp     ([0f:w,%pc,%d0*4])
 181 
 182         .align  4
 183 0:
 184 |       .long   "no memory indirect action/reserved","null outer displacement"
 185 |       .long   "word outer displacement","long outer displacement"
 186 .endm
 187 
 188 | get the extension word and test for brief or full extension type
 189 .macro  fp_get_test_extword label
 190         fp_get_instr_word %d2,fp_err_ua1
 191         btst    #8,%d2
 192         jne     \label
 193 .endm
 194 
 195 
 196 | test if %pc is the base register for the indirect addr mode
 197 .macro  fp_test_basereg_d16     label
 198         btst    #20,%d2
 199         jeq     \label
 200 .endm
 201 
 202 | test if %pc is the base register for one of the extended modes
 203 .macro  fp_test_basereg_ext     label
 204         btst    #19,%d2
 205         jeq     \label
 206 .endm
 207 
 208 .macro  fp_test_suppr_index label
 209         btst    #6,%d2
 210         jne     \label
 211 .endm
 212 
 213 
 214 | addressing mode: data register direct
 215 .macro  fp_mode_data_direct
 216         fp_decode_addr_reg
 217         printf  PDECODE,"d%d",1,%d0
 218 .endm
 219 
 220 | addressing mode: address register indirect
 221 .macro  fp_mode_addr_indirect
 222         fp_decode_addr_reg
 223         printf  PDECODE,"(a%d)",1,%d0
 224         jsr     fp_get_addr_reg
 225 .endm
 226 
 227 | adjust stack for byte moves from/to stack
 228 .macro  fp_test_sp_byte_move
 229         .if     !do_fmovem
 230         .if     do_fscc
 231         move.w  #6,%d1
 232         .endif
 233         cmp.w   #7,%d0
 234         jne     1\@f
 235         .if     !do_fscc
 236         cmp.w   #6,%d1
 237         jne     1\@f
 238         .endif
 239         move.w  #4,%d1
 240 1\@:
 241         .endif
 242 .endm
 243 
 244 | addressing mode: address register indirect with postincrement
 245 .macro  fp_mode_addr_indirect_postinc
 246         fp_decode_addr_reg
 247         printf  PDECODE,"(a%d)+",1,%d0
 248         fp_test_sp_byte_move
 249         jsr     fp_get_addr_reg
 250         move.l  %a0,%a1                 | save addr
 251         .if     do_fmovem
 252         lea     (%a0,%d1.w*4),%a0
 253         .if     !do_fmovem_cr
 254         lea     (%a0,%d1.w*8),%a0
 255         .endif
 256         .else
 257         add.w   (fp_datasize,%d1.w*2),%a0
 258         .endif
 259         jsr     fp_put_addr_reg
 260         move.l  %a1,%a0
 261 .endm
 262 
 263 | addressing mode: address register indirect with predecrement
 264 .macro  fp_mode_addr_indirect_predec
 265         fp_decode_addr_reg
 266         printf  PDECODE,"-(a%d)",1,%d0
 267         fp_test_sp_byte_move
 268         jsr     fp_get_addr_reg
 269         .if     do_fmovem
 270         .if     !do_fmovem_cr
 271         lea     (-12,%a0),%a1           | setup to addr of 1st reg to move
 272         neg.w   %d1
 273         lea     (%a0,%d1.w*4),%a0
 274         add.w   %d1,%d1
 275         lea     (%a0,%d1.w*4),%a0
 276         jsr     fp_put_addr_reg
 277         move.l  %a1,%a0
 278         .else
 279         neg.w   %d1
 280         lea     (%a0,%d1.w*4),%a0
 281         jsr     fp_put_addr_reg
 282         .endif
 283         .else
 284         sub.w   (fp_datasize,%d1.w*2),%a0
 285         jsr     fp_put_addr_reg
 286         .endif
 287 .endm
 288 
 289 | addressing mode: address register/programm counter indirect
 290 |                  with 16bit displacement
 291 .macro  fp_mode_addr_indirect_disp16
 292         .if     !do_no_pc_mode
 293         fp_test_basereg_d16 1f
 294         printf  PDECODE,"pc"
 295         fp_get_pc %a0
 296         jra     2f
 297         .endif
 298 1:      fp_decode_addr_reg
 299         printf  PDECODE,"a%d",1,%d0
 300         jsr     fp_get_addr_reg
 301 2:      fp_get_instr_word %a1,fp_err_ua1
 302         printf  PDECODE,"@(%x)",1,%a1
 303         add.l   %a1,%a0
 304 .endm
 305 
 306 | perform preindex (if I/IS == 0xx and xx != 00)
 307 .macro  fp_do_preindex
 308         moveq   #3,%d0
 309         and.w   %d2,%d0
 310         jeq     1f
 311         btst    #2,%d2
 312         jne     1f
 313         printf  PDECODE,")@("
 314         getuser.l (%a1),%a1,fp_err_ua1,%a1
 315 debug   jra     "2f"
 316 1:      printf  PDECODE,","
 317 2:
 318 .endm
 319 
 320 | perform postindex (if I/IS == 1xx)
 321 .macro  fp_do_postindex
 322         btst    #2,%d2
 323         jeq     1f
 324         printf  PDECODE,")@("
 325         getuser.l (%a1),%a1,fp_err_ua1,%a1
 326 debug   jra     "2f"
 327 1:      printf  PDECODE,","
 328 2:
 329 .endm
 330 
 331 | all other indirect addressing modes will finally end up here
 332 .macro  fp_mode_addr_indirect_extmode0
 333         .if     !do_no_pc_mode
 334         fp_test_basereg_ext 1f
 335         printf  PDECODE,"pc"
 336         fp_get_pc %a0
 337         jra     2f
 338         .endif
 339 1:      fp_decode_addr_reg
 340         printf  PDECODE,"a%d",1,%d0
 341         jsr     fp_get_addr_reg
 342 2:      move.l  %a0,%a1
 343         swap    %d2
 344         fp_get_test_extword 3f
 345         | addressing mode: address register/programm counter indirect
 346         |                  with index and 8bit displacement
 347         fp_decode_disp8
 348 debug   ext.l   "%d0"
 349         printf  PDECODE,"@(%x,",1,%d0
 350         add.w   %d0,%a1
 351         fp_decode_index
 352         add.l   %d0,%a1
 353         printf  PDECODE,")"
 354         jra     9f
 355 3:      | addressing mode: address register/programm counter memory indirect
 356         |                  with base and/or outer displacement
 357         btst    #7,%d2                  | base register suppressed?
 358         jeq     1f
 359         printf  PDECODE,"!"
 360         sub.l   %a1,%a1
 361 1:      printf  PDECODE,"@("
 362         fp_decode_basedisp
 363 
 364         .long   fp_ill,1f
 365         .long   2f,3f
 366 
 367 #ifdef FPU_EMU_DEBUG
 368 1:      printf  PDECODE,"0"             | null base displacement
 369         jra     1f
 370 #endif
 371 2:      fp_get_instr_word %a0,fp_err_ua1 | 16bit base displacement
 372         printf  PDECODE,"%x:w",1,%a0
 373         jra     4f
 374 3:      fp_get_instr_long %a0,fp_err_ua1 | 32bit base displacement
 375         printf  PDECODE,"%x:l",1,%a0
 376 4:      add.l   %a0,%a1
 377 1:
 378         fp_do_postindex
 379         fp_test_suppr_index 1f
 380         fp_decode_index
 381         add.l   %d0,%a1
 382 1:      fp_do_preindex
 383 
 384         fp_decode_outerdisp
 385 
 386         .long   5f,1f
 387         .long   2f,3f
 388 
 389 #ifdef FPU_EMU_DEBUG
 390 1:      printf  PDECODE,"0"             | null outer displacement
 391         jra     1f
 392 #endif
 393 2:      fp_get_instr_word %a0,fp_err_ua1 | 16bit outer displacement
 394         printf  PDECODE,"%x:w",1,%a0
 395         jra     4f
 396 3:      fp_get_instr_long %a0,fp_err_ua1 | 32bit outer displacement
 397         printf  PDECODE,"%x:l",1,%a0
 398 4:      add.l   %a0,%a1
 399 1:
 400 5:      printf  PDECODE,")"
 401 9:      move.l  %a1,%a0
 402         swap    %d2
 403 .endm
 404 
 405 | get the absolute short address from user space
 406 .macro  fp_mode_abs_short
 407         fp_get_instr_word %a0,fp_err_ua1
 408         printf  PDECODE,"%x.w",1,%a0
 409 .endm
 410 
 411 | get the absolute long address from user space
 412 .macro  fp_mode_abs_long
 413         fp_get_instr_long %a0,fp_err_ua1
 414         printf  PDECODE,"%x.l",1,%a0
 415 .endm
 416 
 417 #endif /* _FP_DECODE_H */

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