1/*
2 * fp_cond.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	.globl	fp_fscc, fp_fbccw, fp_fbccl
42
43#ifdef FPU_EMU_DEBUG
44fp_fnop:
45	printf	PDECODE,"fnop\n"
46	jra	fp_end
47#else
48#define fp_fnop fp_end
49#endif
50
51fp_fbccw:
52	tst.w	%d2
53	jeq	fp_fnop
54	printf	PDECODE,"fbccw "
55	fp_get_pc %a0
56	lea	(-2,%a0,%d2.w),%a0
57	jra	1f
58
59fp_fbccl:
60	printf	PDECODE,"fbccl "
61	fp_get_pc %a0
62	move.l	%d2,%d0
63	swap	%d0
64	fp_get_instr_word %d0,fp_err_ua1
65	lea	(-2,%a0,%d0.l),%a0
661:	printf	PDECODE,"%x",1,%a0
67	move.l	%d2,%d0
68	swap	%d0
69	jsr	fp_compute_cond
70	tst.l	%d0
71	jeq	1f
72	fp_put_pc %a0,1
731:	printf	PDECODE,"\n"
74	jra	fp_end
75
76fp_fdbcc:
77	printf	PDECODE,"fdbcc "
78	fp_get_pc %a1				| calculate new pc
79	fp_get_instr_word %d0,fp_err_ua1
80	add.w	%d0,%a1
81	fp_decode_addr_reg
82	printf	PDECODE,"d%d,%x\n",2,%d0,%a1
83	swap	%d1				| test condition in %d1
84	tst.w	%d1
85	jne	2f
86	move.l	%d0,%d1
87	jsr	fp_get_data_reg
88	subq.w	#1,%d0
89	jcs	1f
90	fp_put_pc %a1,1
911:	jsr	fp_put_data_reg
922:	jra	fp_end
93
94| set flags for decode macros for fs<cc>
95do_fscc=1
96do_no_pc_mode=1
97
98fp_fscc:
99	printf	PDECODE,"fscc "
100	move.l	%d2,%d0
101	jsr	fp_compute_cond
102	move.w	%d0,%d1
103	swap	%d1
104
105	| decode addressing mode
106	fp_decode_addr_mode
107
108	.long	fp_data, fp_fdbcc
109	.long	fp_indirect, fp_postinc
110	.long	fp_predecr, fp_disp16
111	.long	fp_extmode0, fp_extmode1
112
113	| addressing mode: data register direct
114fp_data:
115	fp_mode_data_direct
116	move.w	%d0,%d1			| save register nr
117	jsr	fp_get_data_reg
118	swap	%d1
119	move.b	%d1,%d0
120	swap	%d1
121	jsr	fp_put_data_reg
122	printf	PDECODE,"\n"
123	jra	fp_end
124
125fp_indirect:
126	fp_mode_addr_indirect
127	jra	fp_do_scc
128
129fp_postinc:
130	fp_mode_addr_indirect_postinc
131	jra	fp_do_scc
132
133fp_predecr:
134	fp_mode_addr_indirect_predec
135	jra	fp_do_scc
136
137fp_disp16:
138	fp_mode_addr_indirect_disp16
139	jra	fp_do_scc
140
141fp_extmode0:
142	fp_mode_addr_indirect_extmode0
143	jra	fp_do_scc
144
145fp_extmode1:
146	bfextu	%d2{#13,#3},%d0
147	jmp	([0f:w,%pc,%d0*4])
148
149	.align	4
1500:
151	.long	fp_absolute_short, fp_absolute_long
152	.long	fp_ill, fp_ill		| NOTE: jump here to ftrap.x
153	.long	fp_ill, fp_ill
154	.long	fp_ill, fp_ill
155
156fp_absolute_short:
157	fp_mode_abs_short
158	jra	fp_do_scc
159
160fp_absolute_long:
161	fp_mode_abs_long
162|	jra	fp_do_scc
163
164fp_do_scc:
165	swap	%d1
166	putuser.b %d1,(%a0),fp_err_ua1,%a0
167	printf	PDECODE,"\n"
168	jra	fp_end
169
170
171#define tst_NAN	btst #24,%d1
172#define tst_Z	btst #26,%d1
173#define tst_N	btst #27,%d1
174
175fp_compute_cond:
176	move.l	(FPD_FPSR,FPDATA),%d1
177	btst	#4,%d0
178	jeq	1f
179	tst_NAN
180	jeq	1f
181	bset	#15,%d1
182	bset	#7,%d1
183	move.l	%d1,(FPD_FPSR,FPDATA)
1841:	and.w	#0xf,%d0
185	jmp	([0f:w,%pc,%d0.w*4])
186
187	.align	4
1880:
189	.long	fp_f  , fp_eq , fp_ogt, fp_oge
190	.long	fp_olt, fp_ole, fp_ogl, fp_or
191	.long	fp_un , fp_ueq, fp_ugt, fp_uge
192	.long	fp_ult, fp_ule, fp_ne , fp_t
193
194fp_f:
195	moveq	#0,%d0
196	rts
197
198fp_eq:
199	moveq	#0,%d0
200	tst_Z
201	jeq	1f
202	moveq	#-1,%d0
2031:	rts
204
205fp_ogt:
206	moveq	#0,%d0
207	tst_NAN
208	jne	1f
209	tst_Z
210	jne	1f
211	tst_N
212	jne	1f
213	moveq	#-1,%d0
2141:	rts
215
216fp_oge:
217	moveq	#-1,%d0
218	tst_Z
219	jne	2f
220	tst_NAN
221	jne	1f
222	tst_N
223	jeq	2f
2241:	moveq	#0,%d0
2252:	rts
226
227fp_olt:
228	moveq	#0,%d0
229	tst_NAN
230	jne	1f
231	tst_Z
232	jne	1f
233	tst_N
234	jeq	1f
235	moveq	#-1,%d0
2361:	rts
237
238fp_ole:
239	moveq	#-1,%d0
240	tst_Z
241	jne	2f
242	tst_NAN
243	jne	1f
244	tst_N
245	jne	2f
2461:	moveq	#0,%d0
2472:	rts
248
249fp_ogl:
250	moveq	#0,%d0
251	tst_NAN
252	jne	1f
253	tst_Z
254	jne	1f
255	moveq	#-1,%d0
2561:	rts
257
258fp_or:
259	moveq	#0,%d0
260	tst_NAN
261	jne	1f
262	moveq	#-1,%d0
2631:	rts
264
265fp_un:
266	moveq	#0,%d0
267	tst_NAN
268	jeq	1f
269	moveq	#-1,%d0
270	rts
271
272fp_ueq:
273	moveq	#-1,%d0
274	tst_NAN
275	jne	1f
276	tst_Z
277	jne	1f
278	moveq	#0,%d0
2791:	rts
280
281fp_ugt:
282	moveq	#-1,%d0
283	tst_NAN
284	jne	2f
285	tst_N
286	jne	1f
287	tst_Z
288	jeq	2f
2891:	moveq	#0,%d0
2902:	rts
291
292fp_uge:
293	moveq	#-1,%d0
294	tst_NAN
295	jne	1f
296	tst_Z
297	jne	1f
298	tst_N
299	jeq	1f
300	moveq	#0,%d0
3011:	rts
302
303fp_ult:
304	moveq	#-1,%d0
305	tst_NAN
306	jne	2f
307	tst_Z
308	jne	1f
309	tst_N
310	jne	2f
3111:	moveq	#0,%d0
3122:	rts
313
314fp_ule:
315	moveq	#-1,%d0
316	tst_NAN
317	jne	1f
318	tst_Z
319	jne	1f
320	tst_N
321	jne	1f
322	moveq	#0,%d0
3231:	rts
324
325fp_ne:
326	moveq	#0,%d0
327	tst_Z
328	jne	1f
329	moveq	#-1,%d0
3301:	rts
331
332fp_t:
333	moveq	#-1,%d0
334	rts
335