4 * Copyright Roman Zippel, 1997. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
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.)
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.
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:
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
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.
70 | first decoding of the instr type
71 | this separates the conditional instr
72 .macro fp_decode_cond_instr_type
74 jmp ([0f
:w
,%pc
,%d0
*4])
78 | .long "f<op>","fscc/fdbcc"
79 | .long "fbccw","fbccl"
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])
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>"
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
102 | decode destination format
for fmove reg
,ea
103 .macro fp_decode_dest_format
104 bfextu
%d2
{#19,#3},%d0
107 | decode source
register for fmove reg
,ea
108 .macro fp_decode_src_reg
109 bfextu
%d2
{#22,#3},%d0
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])
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"
128 | extract the
register for the addressing mode
129 .macro fp_decode_addr_reg
130 bfextu
%d2
{#13,#3},%d0
133 | decode the
8bit displacement from the brief extension word
134 .macro fp_decode_disp8
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
144 printf PDECODE
,"d%d",1,%d0
147 1\@
: printf PDECODE
,"a%d",1,%d0
151 debug lea
"'l'.w,%a0"
152 btst
#11,%d2 | 16/32 bit size?
154 debug lea
"'w'.w,%a0"
156 3\@
: printf PDECODE
,":%c",1,%a0
157 move
.w
%d2
,%d1
| scale factor
160 debug move
.l
"%d1,-(%sp)"
162 printf PDECODE
,":%d",1,%d1
163 debug move
.l
"(%sp)+,%d1"
167 | decode the base displacement size
168 .macro fp_decode_basedisp
169 bfextu
%d2
{#26,#2},%d0
170 jmp ([0f
:w
,%pc
,%d0
*4])
174 | .long "reserved","null displacement"
175 | .long "word displacement","long displacement"
178 .macro fp_decode_outerdisp
179 bfextu
%d2
{#30,#2},%d0
180 jmp ([0f
:w
,%pc
,%d0
*4])
184 | .long "no memory indirect action/reserved","null outer displacement"
185 | .long "word outer displacement","long outer displacement"
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
196 | test
if %pc is the base
register for the indirect addr mode
197 .macro fp_test_basereg_d16 label
202 | test
if %pc is the base
register for one of the extended modes
203 .macro fp_test_basereg_ext label
208 .macro fp_test_suppr_index label
214 | addressing mode
: data
register direct
215 .macro fp_mode_data_direct
217 printf PDECODE
,"d%d",1,%d0
220 | addressing mode
: address
register indirect
221 .macro fp_mode_addr_indirect
223 printf PDECODE
,"(a%d)",1,%d0
227 | adjust stack
for byte moves from
/to stack
228 .macro fp_test_sp_byte_move
244 | addressing mode
: address
register indirect with postincrement
245 .macro fp_mode_addr_indirect_postinc
247 printf PDECODE
,"(a%d)+",1,%d0
250 move
.l
%a0
,%a1
| save addr
252 lea (%a0
,%d1
.w
*4),%a0
254 lea (%a0
,%d1
.w
*8),%a0
257 add
.w (fp_datasize
,%d1
.w
*2),%a0
263 | addressing mode
: address
register indirect with predecrement
264 .macro fp_mode_addr_indirect_predec
266 printf PDECODE
,"-(a%d)",1,%d0
271 lea (-12,%a0
),%a1
| setup to addr of
1st reg to move
273 lea (%a0
,%d1
.w
*4),%a0
275 lea (%a0
,%d1
.w
*4),%a0
280 lea (%a0
,%d1
.w
*4),%a0
284 sub
.w (fp_datasize
,%d1
.w
*2),%a0
289 | addressing mode
: address
register/programm counter indirect
290 | with
16bit displacement
291 .macro fp_mode_addr_indirect_disp16
293 fp_test_basereg_d16
1f
298 1: fp_decode_addr_reg
299 printf PDECODE
,"a%d",1,%d0
301 2: fp_get_instr_word
%a1
,fp_err_ua1
302 printf PDECODE
,"@(%x)",1,%a1
306 | perform
preindex (if I
/IS
== 0xx
and xx
!= 00)
307 .macro fp_do_preindex
314 getuser
.l (%a1
),%a1
,fp_err_ua1
,%a1
316 1: printf PDECODE
,","
320 | perform
postindex (if I
/IS
== 1xx
)
321 .macro fp_do_postindex
325 getuser
.l (%a1
),%a1
,fp_err_ua1
,%a1
327 1: printf PDECODE
,","
331 | all other indirect addressing modes will finally end up here
332 .macro fp_mode_addr_indirect_extmode0
334 fp_test_basereg_ext
1f
339 1: fp_decode_addr_reg
340 printf PDECODE
,"a%d",1,%d0
344 fp_get_test_extword
3f
345 | addressing mode
: address
register/programm counter indirect
346 | with index
and 8bit displacement
349 printf PDECODE
,"@(%x,",1,%d0
355 3: | addressing mode
: address
register/programm counter memory indirect
356 | with base
and/or outer displacement
357 btst
#7,%d2 | base register suppressed?
361 1: printf PDECODE
,"@("
368 1: printf PDECODE
,"0" | null base displacement
371 2: fp_get_instr_word
%a0
,fp_err_ua1
| 16bit base displacement
372 printf PDECODE
,"%x:w",1,%a0
374 3: fp_get_instr_long
%a0
,fp_err_ua1
| 32bit base displacement
375 printf PDECODE
,"%x:l",1,%a0
379 fp_test_suppr_index
1f
390 1: printf PDECODE
,"0" | null outer displacement
393 2: fp_get_instr_word
%a0
,fp_err_ua1
| 16bit outer displacement
394 printf PDECODE
,"%x:w",1,%a0
396 3: fp_get_instr_long
%a0
,fp_err_ua1
| 32bit outer displacement
397 printf PDECODE
,"%x:l",1,%a0
400 5: printf PDECODE
,")"
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
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
417 #endif /* _FP_DECODE_H */