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