1706f2543Smrg/****************************************************************************
2706f2543Smrg*
3706f2543Smrg*						Realmode X86 Emulator Library
4706f2543Smrg*
5706f2543Smrg*            	Copyright (C) 1996-1999 SciTech Software, Inc.
6706f2543Smrg* 				     Copyright (C) David Mosberger-Tang
7706f2543Smrg* 					   Copyright (C) 1999 Egbert Eich
8706f2543Smrg*
9706f2543Smrg*  ========================================================================
10706f2543Smrg*
11706f2543Smrg*  Permission to use, copy, modify, distribute, and sell this software and
12706f2543Smrg*  its documentation for any purpose is hereby granted without fee,
13706f2543Smrg*  provided that the above copyright notice appear in all copies and that
14706f2543Smrg*  both that copyright notice and this permission notice appear in
15706f2543Smrg*  supporting documentation, and that the name of the authors not be used
16706f2543Smrg*  in advertising or publicity pertaining to distribution of the software
17706f2543Smrg*  without specific, written prior permission.  The authors makes no
18706f2543Smrg*  representations about the suitability of this software for any purpose.
19706f2543Smrg*  It is provided "as is" without express or implied warranty.
20706f2543Smrg*
21706f2543Smrg*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22706f2543Smrg*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23706f2543Smrg*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24706f2543Smrg*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25706f2543Smrg*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26706f2543Smrg*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27706f2543Smrg*  PERFORMANCE OF THIS SOFTWARE.
28706f2543Smrg*
29706f2543Smrg*  ========================================================================
30706f2543Smrg*
31706f2543Smrg* Language:		ANSI C
32706f2543Smrg* Environment:	Any
33706f2543Smrg* Developer:    Kendall Bennett
34706f2543Smrg*
35706f2543Smrg* Description:  This file contains the code to implement the decoding and
36706f2543Smrg*               emulation of the FPU instructions.
37706f2543Smrg*
38706f2543Smrg****************************************************************************/
39706f2543Smrg
40706f2543Smrg#include "x86emu/x86emui.h"
41706f2543Smrg
42706f2543Smrg/*----------------------------- Implementation ----------------------------*/
43706f2543Smrg
44706f2543Smrg/* opcode=0xd8 */
45706f2543Smrgvoid x86emuOp_esc_coprocess_d8(u8 X86EMU_UNUSED(op1))
46706f2543Smrg{
47706f2543Smrg    START_OF_INSTR();
48706f2543Smrg    DECODE_PRINTF("ESC D8\n");
49706f2543Smrg    DECODE_CLEAR_SEGOVR();
50706f2543Smrg    END_OF_INSTR_NO_TRACE();
51706f2543Smrg}
52706f2543Smrg
53706f2543Smrg#ifdef DEBUG
54706f2543Smrg
55706f2543Smrgstatic char *x86emu_fpu_op_d9_tab[] = {
56706f2543Smrg    "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
57706f2543Smrg    "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
58706f2543Smrg
59706f2543Smrg    "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
60706f2543Smrg    "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
61706f2543Smrg
62706f2543Smrg    "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
63706f2543Smrg    "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
64706f2543Smrg};
65706f2543Smrg
66706f2543Smrgstatic char *x86emu_fpu_op_d9_tab1[] = {
67706f2543Smrg    "FLD\t", "FLD\t", "FLD\t", "FLD\t",
68706f2543Smrg    "FLD\t", "FLD\t", "FLD\t", "FLD\t",
69706f2543Smrg
70706f2543Smrg    "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
71706f2543Smrg    "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
72706f2543Smrg
73706f2543Smrg    "FNOP", "ESC_D9", "ESC_D9", "ESC_D9",
74706f2543Smrg    "ESC_D9", "ESC_D9", "ESC_D9", "ESC_D9",
75706f2543Smrg
76706f2543Smrg    "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
77706f2543Smrg    "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
78706f2543Smrg
79706f2543Smrg    "FCHS", "FABS", "ESC_D9", "ESC_D9",
80706f2543Smrg    "FTST", "FXAM", "ESC_D9", "ESC_D9",
81706f2543Smrg
82706f2543Smrg    "FLD1", "FLDL2T", "FLDL2E", "FLDPI",
83706f2543Smrg    "FLDLG2", "FLDLN2", "FLDZ", "ESC_D9",
84706f2543Smrg
85706f2543Smrg    "F2XM1", "FYL2X", "FPTAN", "FPATAN",
86706f2543Smrg    "FXTRACT", "ESC_D9", "FDECSTP", "FINCSTP",
87706f2543Smrg
88706f2543Smrg    "FPREM", "FYL2XP1", "FSQRT", "ESC_D9",
89706f2543Smrg    "FRNDINT", "FSCALE", "ESC_D9", "ESC_D9",
90706f2543Smrg};
91706f2543Smrg
92706f2543Smrg#endif /* DEBUG */
93706f2543Smrg
94706f2543Smrg/* opcode=0xd9 */
95706f2543Smrgvoid x86emuOp_esc_coprocess_d9(u8 X86EMU_UNUSED(op1))
96706f2543Smrg{
97706f2543Smrg    int mod, rl, rh;
98706f2543Smrg    uint destoffset = 0;
99706f2543Smrg    u8 stkelem = 0;
100706f2543Smrg
101706f2543Smrg    START_OF_INSTR();
102706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
103706f2543Smrg#ifdef DEBUG
104706f2543Smrg    if (mod != 3) {
105706f2543Smrg        DECODE_PRINTINSTR32(x86emu_fpu_op_d9_tab, mod, rh, rl);
106706f2543Smrg    } else {
107706f2543Smrg        DECODE_PRINTF(x86emu_fpu_op_d9_tab1[(rh << 3) + rl]);
108706f2543Smrg    }
109706f2543Smrg#endif
110706f2543Smrg    switch (mod) {
111706f2543Smrg      case 0:
112706f2543Smrg        destoffset = decode_rm00_address(rl);
113706f2543Smrg        DECODE_PRINTF("\n");
114706f2543Smrg        break;
115706f2543Smrg      case 1:
116706f2543Smrg        destoffset = decode_rm01_address(rl);
117706f2543Smrg        DECODE_PRINTF("\n");
118706f2543Smrg        break;
119706f2543Smrg      case 2:
120706f2543Smrg        destoffset = decode_rm10_address(rl);
121706f2543Smrg        DECODE_PRINTF("\n");
122706f2543Smrg        break;
123706f2543Smrg      case 3:                   /* register to register */
124706f2543Smrg		stkelem = (u8)rl;
125706f2543Smrg		if (rh < 4) {
126706f2543Smrg				DECODE_PRINTF2("ST(%d)\n", stkelem);
127706f2543Smrg		} else {
128706f2543Smrg				DECODE_PRINTF("\n");
129706f2543Smrg		}
130706f2543Smrg        break;
131706f2543Smrg    }
132706f2543Smrg#ifdef X86EMU_FPU_PRESENT
133706f2543Smrg    /* execute */
134706f2543Smrg    switch (mod) {
135706f2543Smrg      case 3:
136706f2543Smrg        switch (rh) {
137706f2543Smrg          case 0:
138706f2543Smrg            x86emu_fpu_R_fld(X86EMU_FPU_STKTOP, stkelem);
139706f2543Smrg            break;
140706f2543Smrg          case 1:
141706f2543Smrg            x86emu_fpu_R_fxch(X86EMU_FPU_STKTOP, stkelem);
142706f2543Smrg            break;
143706f2543Smrg          case 2:
144706f2543Smrg            switch (rl) {
145706f2543Smrg              case 0:
146706f2543Smrg                x86emu_fpu_R_nop();
147706f2543Smrg                break;
148706f2543Smrg              default:
149706f2543Smrg                x86emu_fpu_illegal();
150706f2543Smrg                break;
151706f2543Smrg            }
152706f2543Smrg          case 3:
153706f2543Smrg            x86emu_fpu_R_fstp(X86EMU_FPU_STKTOP, stkelem);
154706f2543Smrg            break;
155706f2543Smrg          case 4:
156706f2543Smrg            switch (rl) {
157706f2543Smrg            case 0:
158706f2543Smrg                x86emu_fpu_R_fchs(X86EMU_FPU_STKTOP);
159706f2543Smrg                break;
160706f2543Smrg            case 1:
161706f2543Smrg                x86emu_fpu_R_fabs(X86EMU_FPU_STKTOP);
162706f2543Smrg                break;
163706f2543Smrg            case 4:
164706f2543Smrg                x86emu_fpu_R_ftst(X86EMU_FPU_STKTOP);
165706f2543Smrg                break;
166706f2543Smrg            case 5:
167706f2543Smrg                x86emu_fpu_R_fxam(X86EMU_FPU_STKTOP);
168706f2543Smrg                break;
169706f2543Smrg            default:
170706f2543Smrg                /* 2,3,6,7 */
171706f2543Smrg                x86emu_fpu_illegal();
172706f2543Smrg                break;
173706f2543Smrg            }
174706f2543Smrg            break;
175706f2543Smrg
176706f2543Smrg          case 5:
177706f2543Smrg            switch (rl) {
178706f2543Smrg              case 0:
179706f2543Smrg                x86emu_fpu_R_fld1(X86EMU_FPU_STKTOP);
180706f2543Smrg                break;
181706f2543Smrg              case 1:
182706f2543Smrg                x86emu_fpu_R_fldl2t(X86EMU_FPU_STKTOP);
183706f2543Smrg                break;
184706f2543Smrg              case 2:
185706f2543Smrg                x86emu_fpu_R_fldl2e(X86EMU_FPU_STKTOP);
186706f2543Smrg                break;
187706f2543Smrg              case 3:
188706f2543Smrg                x86emu_fpu_R_fldpi(X86EMU_FPU_STKTOP);
189706f2543Smrg                break;
190706f2543Smrg              case 4:
191706f2543Smrg                x86emu_fpu_R_fldlg2(X86EMU_FPU_STKTOP);
192706f2543Smrg                break;
193706f2543Smrg              case 5:
194706f2543Smrg                x86emu_fpu_R_fldln2(X86EMU_FPU_STKTOP);
195706f2543Smrg                break;
196706f2543Smrg              case 6:
197706f2543Smrg                x86emu_fpu_R_fldz(X86EMU_FPU_STKTOP);
198706f2543Smrg                break;
199706f2543Smrg              default:
200706f2543Smrg                /* 7 */
201706f2543Smrg                x86emu_fpu_illegal();
202706f2543Smrg                break;
203706f2543Smrg            }
204706f2543Smrg            break;
205706f2543Smrg
206706f2543Smrg          case 6:
207706f2543Smrg            switch (rl) {
208706f2543Smrg              case 0:
209706f2543Smrg                x86emu_fpu_R_f2xm1(X86EMU_FPU_STKTOP);
210706f2543Smrg                break;
211706f2543Smrg              case 1:
212706f2543Smrg                x86emu_fpu_R_fyl2x(X86EMU_FPU_STKTOP);
213706f2543Smrg                break;
214706f2543Smrg              case 2:
215706f2543Smrg                x86emu_fpu_R_fptan(X86EMU_FPU_STKTOP);
216706f2543Smrg                break;
217706f2543Smrg              case 3:
218706f2543Smrg                x86emu_fpu_R_fpatan(X86EMU_FPU_STKTOP);
219706f2543Smrg                break;
220706f2543Smrg              case 4:
221706f2543Smrg                x86emu_fpu_R_fxtract(X86EMU_FPU_STKTOP);
222706f2543Smrg                break;
223706f2543Smrg              case 5:
224706f2543Smrg                x86emu_fpu_illegal();
225706f2543Smrg                break;
226706f2543Smrg              case 6:
227706f2543Smrg                x86emu_fpu_R_decstp();
228706f2543Smrg                break;
229706f2543Smrg              case 7:
230706f2543Smrg                x86emu_fpu_R_incstp();
231706f2543Smrg                break;
232706f2543Smrg            }
233706f2543Smrg            break;
234706f2543Smrg
235706f2543Smrg          case 7:
236706f2543Smrg            switch (rl) {
237706f2543Smrg              case 0:
238706f2543Smrg                x86emu_fpu_R_fprem(X86EMU_FPU_STKTOP);
239706f2543Smrg                break;
240706f2543Smrg              case 1:
241706f2543Smrg                x86emu_fpu_R_fyl2xp1(X86EMU_FPU_STKTOP);
242706f2543Smrg                break;
243706f2543Smrg              case 2:
244706f2543Smrg                x86emu_fpu_R_fsqrt(X86EMU_FPU_STKTOP);
245706f2543Smrg                break;
246706f2543Smrg              case 3:
247706f2543Smrg                x86emu_fpu_illegal();
248706f2543Smrg                break;
249706f2543Smrg              case 4:
250706f2543Smrg                x86emu_fpu_R_frndint(X86EMU_FPU_STKTOP);
251706f2543Smrg                break;
252706f2543Smrg              case 5:
253706f2543Smrg                x86emu_fpu_R_fscale(X86EMU_FPU_STKTOP);
254706f2543Smrg                break;
255706f2543Smrg              case 6:
256706f2543Smrg              case 7:
257706f2543Smrg              default:
258706f2543Smrg                x86emu_fpu_illegal();
259706f2543Smrg                break;
260706f2543Smrg            }
261706f2543Smrg            break;
262706f2543Smrg
263706f2543Smrg          default:
264706f2543Smrg            switch (rh) {
265706f2543Smrg              case 0:
266706f2543Smrg                x86emu_fpu_M_fld(X86EMU_FPU_FLOAT, destoffset);
267706f2543Smrg                break;
268706f2543Smrg              case 1:
269706f2543Smrg                x86emu_fpu_illegal();
270706f2543Smrg                break;
271706f2543Smrg              case 2:
272706f2543Smrg                x86emu_fpu_M_fst(X86EMU_FPU_FLOAT, destoffset);
273706f2543Smrg                break;
274706f2543Smrg              case 3:
275706f2543Smrg                x86emu_fpu_M_fstp(X86EMU_FPU_FLOAT, destoffset);
276706f2543Smrg                break;
277706f2543Smrg              case 4:
278706f2543Smrg                x86emu_fpu_M_fldenv(X86EMU_FPU_WORD, destoffset);
279706f2543Smrg                break;
280706f2543Smrg              case 5:
281706f2543Smrg                x86emu_fpu_M_fldcw(X86EMU_FPU_WORD, destoffset);
282706f2543Smrg                break;
283706f2543Smrg              case 6:
284706f2543Smrg                x86emu_fpu_M_fstenv(X86EMU_FPU_WORD, destoffset);
285706f2543Smrg                break;
286706f2543Smrg              case 7:
287706f2543Smrg                x86emu_fpu_M_fstcw(X86EMU_FPU_WORD, destoffset);
288706f2543Smrg                break;
289706f2543Smrg            }
290706f2543Smrg        }
291706f2543Smrg    }
292706f2543Smrg#else
293706f2543Smrg    (void)destoffset;
294706f2543Smrg    (void)stkelem;
295706f2543Smrg#endif /* X86EMU_FPU_PRESENT */
296706f2543Smrg    DECODE_CLEAR_SEGOVR();
297706f2543Smrg    END_OF_INSTR_NO_TRACE();
298706f2543Smrg}
299706f2543Smrg
300706f2543Smrg#ifdef DEBUG
301706f2543Smrg
302706f2543Smrgchar *x86emu_fpu_op_da_tab[] = {
303706f2543Smrg    "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
304706f2543Smrg    "FICOMP\tDWORD PTR ",
305706f2543Smrg    "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
306706f2543Smrg    "FIDIVR\tDWORD PTR ",
307706f2543Smrg
308706f2543Smrg    "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
309706f2543Smrg    "FICOMP\tDWORD PTR ",
310706f2543Smrg    "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
311706f2543Smrg    "FIDIVR\tDWORD PTR ",
312706f2543Smrg
313706f2543Smrg    "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
314706f2543Smrg    "FICOMP\tDWORD PTR ",
315706f2543Smrg    "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
316706f2543Smrg    "FIDIVR\tDWORD PTR ",
317706f2543Smrg
318706f2543Smrg    "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
319706f2543Smrg    "ESC_DA     ", "ESC_DA ", "ESC_DA   ", "ESC_DA ",
320706f2543Smrg};
321706f2543Smrg
322706f2543Smrg#endif /* DEBUG */
323706f2543Smrg
324706f2543Smrg/* opcode=0xda */
325706f2543Smrgvoid x86emuOp_esc_coprocess_da(u8 X86EMU_UNUSED(op1))
326706f2543Smrg{
327706f2543Smrg    int mod, rl, rh;
328706f2543Smrg    uint destoffset = 0;
329706f2543Smrg    u8 stkelem = 0;
330706f2543Smrg
331706f2543Smrg    START_OF_INSTR();
332706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
333706f2543Smrg    DECODE_PRINTINSTR32(x86emu_fpu_op_da_tab, mod, rh, rl);
334706f2543Smrg    switch (mod) {
335706f2543Smrg      case 0:
336706f2543Smrg        destoffset = decode_rm00_address(rl);
337706f2543Smrg        DECODE_PRINTF("\n");
338706f2543Smrg        break;
339706f2543Smrg      case 1:
340706f2543Smrg        destoffset = decode_rm01_address(rl);
341706f2543Smrg        DECODE_PRINTF("\n");
342706f2543Smrg        break;
343706f2543Smrg      case 2:
344706f2543Smrg        destoffset = decode_rm10_address(rl);
345706f2543Smrg        DECODE_PRINTF("\n");
346706f2543Smrg        break;
347706f2543Smrg      case 3:           /* register to register */
348706f2543Smrg		stkelem = (u8)rl;
349706f2543Smrg        DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
350706f2543Smrg        break;
351706f2543Smrg    }
352706f2543Smrg#ifdef X86EMU_FPU_PRESENT
353706f2543Smrg    switch (mod) {
354706f2543Smrg      case 3:
355706f2543Smrg        x86emu_fpu_illegal();
356706f2543Smrg        break;
357706f2543Smrg      default:
358706f2543Smrg        switch (rh) {
359706f2543Smrg          case 0:
360706f2543Smrg            x86emu_fpu_M_iadd(X86EMU_FPU_SHORT, destoffset);
361706f2543Smrg            break;
362706f2543Smrg          case 1:
363706f2543Smrg            x86emu_fpu_M_imul(X86EMU_FPU_SHORT, destoffset);
364706f2543Smrg            break;
365706f2543Smrg          case 2:
366706f2543Smrg            x86emu_fpu_M_icom(X86EMU_FPU_SHORT, destoffset);
367706f2543Smrg            break;
368706f2543Smrg          case 3:
369706f2543Smrg            x86emu_fpu_M_icomp(X86EMU_FPU_SHORT, destoffset);
370706f2543Smrg            break;
371706f2543Smrg          case 4:
372706f2543Smrg            x86emu_fpu_M_isub(X86EMU_FPU_SHORT, destoffset);
373706f2543Smrg            break;
374706f2543Smrg          case 5:
375706f2543Smrg            x86emu_fpu_M_isubr(X86EMU_FPU_SHORT, destoffset);
376706f2543Smrg            break;
377706f2543Smrg          case 6:
378706f2543Smrg            x86emu_fpu_M_idiv(X86EMU_FPU_SHORT, destoffset);
379706f2543Smrg            break;
380706f2543Smrg          case 7:
381706f2543Smrg            x86emu_fpu_M_idivr(X86EMU_FPU_SHORT, destoffset);
382706f2543Smrg            break;
383706f2543Smrg        }
384706f2543Smrg    }
385706f2543Smrg#else
386706f2543Smrg    (void)destoffset;
387706f2543Smrg    (void)stkelem;
388706f2543Smrg#endif
389706f2543Smrg    DECODE_CLEAR_SEGOVR();
390706f2543Smrg    END_OF_INSTR_NO_TRACE();
391706f2543Smrg}
392706f2543Smrg
393706f2543Smrg#ifdef DEBUG
394706f2543Smrg
395706f2543Smrgchar *x86emu_fpu_op_db_tab[] = {
396706f2543Smrg    "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
397706f2543Smrg    "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
398706f2543Smrg
399706f2543Smrg    "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
400706f2543Smrg    "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
401706f2543Smrg
402706f2543Smrg    "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
403706f2543Smrg    "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
404706f2543Smrg};
405706f2543Smrg
406706f2543Smrg#endif /* DEBUG */
407706f2543Smrg
408706f2543Smrg/* opcode=0xdb */
409706f2543Smrgvoid x86emuOp_esc_coprocess_db(u8 X86EMU_UNUSED(op1))
410706f2543Smrg{
411706f2543Smrg    int mod, rl, rh;
412706f2543Smrg    uint destoffset = 0;
413706f2543Smrg
414706f2543Smrg    START_OF_INSTR();
415706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
416706f2543Smrg#ifdef DEBUG
417706f2543Smrg    if (mod != 3) {
418706f2543Smrg        DECODE_PRINTINSTR32(x86emu_fpu_op_db_tab, mod, rh, rl);
419706f2543Smrg    } else if (rh == 4) {       /* === 11 10 0 nnn */
420706f2543Smrg        switch (rl) {
421706f2543Smrg          case 0:
422706f2543Smrg            DECODE_PRINTF("FENI\n");
423706f2543Smrg            break;
424706f2543Smrg          case 1:
425706f2543Smrg            DECODE_PRINTF("FDISI\n");
426706f2543Smrg            break;
427706f2543Smrg          case 2:
428706f2543Smrg            DECODE_PRINTF("FCLEX\n");
429706f2543Smrg            break;
430706f2543Smrg          case 3:
431706f2543Smrg            DECODE_PRINTF("FINIT\n");
432706f2543Smrg            break;
433706f2543Smrg        }
434706f2543Smrg    } else {
435706f2543Smrg        DECODE_PRINTF2("ESC_DB %0x\n", (mod << 6) + (rh << 3) + (rl));
436706f2543Smrg    }
437706f2543Smrg#endif /* DEBUG */
438706f2543Smrg    switch (mod) {
439706f2543Smrg      case 0:
440706f2543Smrg        destoffset = decode_rm00_address(rl);
441706f2543Smrg        break;
442706f2543Smrg      case 1:
443706f2543Smrg        destoffset = decode_rm01_address(rl);
444706f2543Smrg        break;
445706f2543Smrg      case 2:
446706f2543Smrg        destoffset = decode_rm10_address(rl);
447706f2543Smrg        break;
448706f2543Smrg      case 3:                   /* register to register */
449706f2543Smrg        break;
450706f2543Smrg    }
451706f2543Smrg#ifdef X86EMU_FPU_PRESENT
452706f2543Smrg    /* execute */
453706f2543Smrg    switch (mod) {
454706f2543Smrg      case 3:
455706f2543Smrg        switch (rh) {
456706f2543Smrg          case 4:
457706f2543Smrg            switch (rl) {
458706f2543Smrg              case 0:
459706f2543Smrg                x86emu_fpu_R_feni();
460706f2543Smrg                break;
461706f2543Smrg              case 1:
462706f2543Smrg                x86emu_fpu_R_fdisi();
463706f2543Smrg                break;
464706f2543Smrg              case 2:
465706f2543Smrg                x86emu_fpu_R_fclex();
466706f2543Smrg                break;
467706f2543Smrg              case 3:
468706f2543Smrg                x86emu_fpu_R_finit();
469706f2543Smrg                break;
470706f2543Smrg              default:
471706f2543Smrg                x86emu_fpu_illegal();
472706f2543Smrg                break;
473706f2543Smrg            }
474706f2543Smrg            break;
475706f2543Smrg          default:
476706f2543Smrg            x86emu_fpu_illegal();
477706f2543Smrg            break;
478706f2543Smrg        }
479706f2543Smrg        break;
480706f2543Smrg      default:
481706f2543Smrg        switch (rh) {
482706f2543Smrg          case 0:
483706f2543Smrg            x86emu_fpu_M_fild(X86EMU_FPU_SHORT, destoffset);
484706f2543Smrg            break;
485706f2543Smrg          case 1:
486706f2543Smrg            x86emu_fpu_illegal();
487706f2543Smrg            break;
488706f2543Smrg          case 2:
489706f2543Smrg            x86emu_fpu_M_fist(X86EMU_FPU_SHORT, destoffset);
490706f2543Smrg            break;
491706f2543Smrg          case 3:
492706f2543Smrg            x86emu_fpu_M_fistp(X86EMU_FPU_SHORT, destoffset);
493706f2543Smrg            break;
494706f2543Smrg          case 4:
495706f2543Smrg            x86emu_fpu_illegal();
496706f2543Smrg            break;
497706f2543Smrg          case 5:
498706f2543Smrg            x86emu_fpu_M_fld(X86EMU_FPU_LDBL, destoffset);
499706f2543Smrg            break;
500706f2543Smrg                      case 6:
501706f2543Smrg            x86emu_fpu_illegal();
502706f2543Smrg            break;
503706f2543Smrg          case 7:
504706f2543Smrg            x86emu_fpu_M_fstp(X86EMU_FPU_LDBL, destoffset);
505706f2543Smrg            break;
506706f2543Smrg        }
507706f2543Smrg    }
508706f2543Smrg#else
509706f2543Smrg    (void)destoffset;
510706f2543Smrg#endif
511706f2543Smrg    DECODE_CLEAR_SEGOVR();
512706f2543Smrg    END_OF_INSTR_NO_TRACE();
513706f2543Smrg}
514706f2543Smrg
515706f2543Smrg#ifdef DEBUG
516706f2543Smrgchar *x86emu_fpu_op_dc_tab[] = {
517706f2543Smrg    "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
518706f2543Smrg    "FCOMP\tQWORD PTR ",
519706f2543Smrg    "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
520706f2543Smrg    "FDIVR\tQWORD PTR ",
521706f2543Smrg
522706f2543Smrg    "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
523706f2543Smrg    "FCOMP\tQWORD PTR ",
524706f2543Smrg    "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
525706f2543Smrg    "FDIVR\tQWORD PTR ",
526706f2543Smrg
527706f2543Smrg    "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
528706f2543Smrg    "FCOMP\tQWORD PTR ",
529706f2543Smrg    "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
530706f2543Smrg    "FDIVR\tQWORD PTR ",
531706f2543Smrg
532706f2543Smrg    "FADD\t", "FMUL\t", "FCOM\t", "FCOMP\t",
533706f2543Smrg    "FSUBR\t", "FSUB\t", "FDIVR\t", "FDIV\t",
534706f2543Smrg};
535706f2543Smrg#endif /* DEBUG */
536706f2543Smrg
537706f2543Smrg/* opcode=0xdc */
538706f2543Smrgvoid x86emuOp_esc_coprocess_dc(u8 X86EMU_UNUSED(op1))
539706f2543Smrg{
540706f2543Smrg    int mod, rl, rh;
541706f2543Smrg    uint destoffset = 0;
542706f2543Smrg    u8 stkelem = 0;
543706f2543Smrg
544706f2543Smrg    START_OF_INSTR();
545706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
546706f2543Smrg    DECODE_PRINTINSTR32(x86emu_fpu_op_dc_tab, mod, rh, rl);
547706f2543Smrg    switch (mod) {
548706f2543Smrg      case 0:
549706f2543Smrg        destoffset = decode_rm00_address(rl);
550706f2543Smrg        DECODE_PRINTF("\n");
551706f2543Smrg        break;
552706f2543Smrg      case 1:
553706f2543Smrg        destoffset = decode_rm01_address(rl);
554706f2543Smrg        DECODE_PRINTF("\n");
555706f2543Smrg        break;
556706f2543Smrg      case 2:
557706f2543Smrg        destoffset = decode_rm10_address(rl);
558706f2543Smrg        DECODE_PRINTF("\n");
559706f2543Smrg        break;
560706f2543Smrg      case 3:                   /* register to register */
561706f2543Smrg		stkelem = (u8)rl;
562706f2543Smrg        DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
563706f2543Smrg        break;
564706f2543Smrg    }
565706f2543Smrg#ifdef X86EMU_FPU_PRESENT
566706f2543Smrg    /* execute */
567706f2543Smrg    switch (mod) {
568706f2543Smrg      case 3:
569706f2543Smrg        switch (rh) {
570706f2543Smrg          case 0:
571706f2543Smrg            x86emu_fpu_R_fadd(stkelem, X86EMU_FPU_STKTOP);
572706f2543Smrg            break;
573706f2543Smrg          case 1:
574706f2543Smrg            x86emu_fpu_R_fmul(stkelem, X86EMU_FPU_STKTOP);
575706f2543Smrg            break;
576706f2543Smrg          case 2:
577706f2543Smrg            x86emu_fpu_R_fcom(stkelem, X86EMU_FPU_STKTOP);
578706f2543Smrg            break;
579706f2543Smrg          case 3:
580706f2543Smrg            x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
581706f2543Smrg            break;
582706f2543Smrg          case 4:
583706f2543Smrg            x86emu_fpu_R_fsubr(stkelem, X86EMU_FPU_STKTOP);
584706f2543Smrg            break;
585706f2543Smrg          case 5:
586706f2543Smrg            x86emu_fpu_R_fsub(stkelem, X86EMU_FPU_STKTOP);
587706f2543Smrg            break;
588706f2543Smrg          case 6:
589706f2543Smrg            x86emu_fpu_R_fdivr(stkelem, X86EMU_FPU_STKTOP);
590706f2543Smrg            break;
591706f2543Smrg          case 7:
592706f2543Smrg            x86emu_fpu_R_fdiv(stkelem, X86EMU_FPU_STKTOP);
593706f2543Smrg            break;
594706f2543Smrg        }
595706f2543Smrg        break;
596706f2543Smrg      default:
597706f2543Smrg        switch (rh) {
598706f2543Smrg          case 0:
599706f2543Smrg            x86emu_fpu_M_fadd(X86EMU_FPU_DOUBLE, destoffset);
600706f2543Smrg            break;
601706f2543Smrg          case 1:
602706f2543Smrg            x86emu_fpu_M_fmul(X86EMU_FPU_DOUBLE, destoffset);
603706f2543Smrg            break;
604706f2543Smrg          case 2:
605706f2543Smrg            x86emu_fpu_M_fcom(X86EMU_FPU_DOUBLE, destoffset);
606706f2543Smrg            break;
607706f2543Smrg          case 3:
608706f2543Smrg            x86emu_fpu_M_fcomp(X86EMU_FPU_DOUBLE, destoffset);
609706f2543Smrg            break;
610706f2543Smrg          case 4:
611706f2543Smrg            x86emu_fpu_M_fsub(X86EMU_FPU_DOUBLE, destoffset);
612706f2543Smrg            break;
613706f2543Smrg          case 5:
614706f2543Smrg            x86emu_fpu_M_fsubr(X86EMU_FPU_DOUBLE, destoffset);
615706f2543Smrg            break;
616706f2543Smrg          case 6:
617706f2543Smrg            x86emu_fpu_M_fdiv(X86EMU_FPU_DOUBLE, destoffset);
618706f2543Smrg            break;
619706f2543Smrg          case 7:
620706f2543Smrg            x86emu_fpu_M_fdivr(X86EMU_FPU_DOUBLE, destoffset);
621706f2543Smrg            break;
622706f2543Smrg        }
623706f2543Smrg    }
624706f2543Smrg#else
625706f2543Smrg    (void)destoffset;
626706f2543Smrg    (void)stkelem;
627706f2543Smrg#endif
628706f2543Smrg    DECODE_CLEAR_SEGOVR();
629706f2543Smrg    END_OF_INSTR_NO_TRACE();
630706f2543Smrg}
631706f2543Smrg
632706f2543Smrg#ifdef DEBUG
633706f2543Smrg
634706f2543Smrgstatic char *x86emu_fpu_op_dd_tab[] = {
635706f2543Smrg    "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
636706f2543Smrg    "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
637706f2543Smrg
638706f2543Smrg    "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
639706f2543Smrg    "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
640706f2543Smrg
641706f2543Smrg    "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
642706f2543Smrg    "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
643706f2543Smrg
644706f2543Smrg    "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
645706f2543Smrg    "ESC_DD\t2C,", "ESC_DD\t2D,", "ESC_DD\t2E,", "ESC_DD\t2F,",
646706f2543Smrg};
647706f2543Smrg
648706f2543Smrg#endif /* DEBUG */
649706f2543Smrg
650706f2543Smrg/* opcode=0xdd */
651706f2543Smrgvoid x86emuOp_esc_coprocess_dd(u8 X86EMU_UNUSED(op1))
652706f2543Smrg{
653706f2543Smrg    int mod, rl, rh;
654706f2543Smrg    uint destoffset = 0;
655706f2543Smrg    u8 stkelem = 0;
656706f2543Smrg
657706f2543Smrg    START_OF_INSTR();
658706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
659706f2543Smrg    DECODE_PRINTINSTR32(x86emu_fpu_op_dd_tab, mod, rh, rl);
660706f2543Smrg    switch (mod) {
661706f2543Smrg      case 0:
662706f2543Smrg        destoffset = decode_rm00_address(rl);
663706f2543Smrg        DECODE_PRINTF("\n");
664706f2543Smrg        break;
665706f2543Smrg      case 1:
666706f2543Smrg        destoffset = decode_rm01_address(rl);
667706f2543Smrg        DECODE_PRINTF("\n");
668706f2543Smrg        break;
669706f2543Smrg      case 2:
670706f2543Smrg        destoffset = decode_rm10_address(rl);
671706f2543Smrg        DECODE_PRINTF("\n");
672706f2543Smrg        break;
673706f2543Smrg      case 3:                   /* register to register */
674706f2543Smrg		stkelem = (u8)rl;
675706f2543Smrg        DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
676706f2543Smrg        break;
677706f2543Smrg    }
678706f2543Smrg#ifdef X86EMU_FPU_PRESENT
679706f2543Smrg    switch (mod) {
680706f2543Smrg      case 3:
681706f2543Smrg        switch (rh) {
682706f2543Smrg          case 0:
683706f2543Smrg            x86emu_fpu_R_ffree(stkelem);
684706f2543Smrg            break;
685706f2543Smrg          case 1:
686706f2543Smrg            x86emu_fpu_R_fxch(stkelem);
687706f2543Smrg            break;
688706f2543Smrg          case 2:
689706f2543Smrg            x86emu_fpu_R_fst(stkelem);  /* register version */
690706f2543Smrg            break;
691706f2543Smrg          case 3:
692706f2543Smrg            x86emu_fpu_R_fstp(stkelem); /* register version */
693706f2543Smrg            break;
694706f2543Smrg          default:
695706f2543Smrg            x86emu_fpu_illegal();
696706f2543Smrg            break;
697706f2543Smrg        }
698706f2543Smrg        break;
699706f2543Smrg      default:
700706f2543Smrg        switch (rh) {
701706f2543Smrg          case 0:
702706f2543Smrg            x86emu_fpu_M_fld(X86EMU_FPU_DOUBLE, destoffset);
703706f2543Smrg            break;
704706f2543Smrg          case 1:
705706f2543Smrg            x86emu_fpu_illegal();
706706f2543Smrg            break;
707706f2543Smrg          case 2:
708706f2543Smrg            x86emu_fpu_M_fst(X86EMU_FPU_DOUBLE, destoffset);
709706f2543Smrg            break;
710706f2543Smrg          case 3:
711706f2543Smrg            x86emu_fpu_M_fstp(X86EMU_FPU_DOUBLE, destoffset);
712706f2543Smrg            break;
713706f2543Smrg          case 4:
714706f2543Smrg            x86emu_fpu_M_frstor(X86EMU_FPU_WORD, destoffset);
715706f2543Smrg            break;
716706f2543Smrg          case 5:
717706f2543Smrg            x86emu_fpu_illegal();
718706f2543Smrg            break;
719706f2543Smrg          case 6:
720706f2543Smrg            x86emu_fpu_M_fsave(X86EMU_FPU_WORD, destoffset);
721706f2543Smrg            break;
722706f2543Smrg          case 7:
723706f2543Smrg            x86emu_fpu_M_fstsw(X86EMU_FPU_WORD, destoffset);
724706f2543Smrg            break;
725706f2543Smrg        }
726706f2543Smrg    }
727706f2543Smrg#else
728706f2543Smrg    (void)destoffset;
729706f2543Smrg    (void)stkelem;
730706f2543Smrg#endif
731706f2543Smrg    DECODE_CLEAR_SEGOVR();
732706f2543Smrg    END_OF_INSTR_NO_TRACE();
733706f2543Smrg}
734706f2543Smrg
735706f2543Smrg#ifdef DEBUG
736706f2543Smrg
737706f2543Smrgstatic char *x86emu_fpu_op_de_tab[] =
738706f2543Smrg{
739706f2543Smrg    "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
740706f2543Smrg    "FICOMP\tWORD PTR ",
741706f2543Smrg    "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
742706f2543Smrg    "FIDIVR\tWORD PTR ",
743706f2543Smrg
744706f2543Smrg    "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
745706f2543Smrg    "FICOMP\tWORD PTR ",
746706f2543Smrg    "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
747706f2543Smrg    "FIDIVR\tWORD PTR ",
748706f2543Smrg
749706f2543Smrg    "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
750706f2543Smrg    "FICOMP\tWORD PTR ",
751706f2543Smrg    "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
752706f2543Smrg    "FIDIVR\tWORD PTR ",
753706f2543Smrg
754706f2543Smrg    "FADDP\t", "FMULP\t", "FCOMP\t", "FCOMPP\t",
755706f2543Smrg    "FSUBRP\t", "FSUBP\t", "FDIVRP\t", "FDIVP\t",
756706f2543Smrg};
757706f2543Smrg
758706f2543Smrg#endif /* DEBUG */
759706f2543Smrg
760706f2543Smrg/* opcode=0xde */
761706f2543Smrgvoid x86emuOp_esc_coprocess_de(u8 X86EMU_UNUSED(op1))
762706f2543Smrg{
763706f2543Smrg    int mod, rl, rh;
764706f2543Smrg    uint destoffset = 0;
765706f2543Smrg    u8 stkelem = 0;
766706f2543Smrg
767706f2543Smrg    START_OF_INSTR();
768706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
769706f2543Smrg    DECODE_PRINTINSTR32(x86emu_fpu_op_de_tab, mod, rh, rl);
770706f2543Smrg    switch (mod) {
771706f2543Smrg      case 0:
772706f2543Smrg        destoffset = decode_rm00_address(rl);
773706f2543Smrg        DECODE_PRINTF("\n");
774706f2543Smrg        break;
775706f2543Smrg      case 1:
776706f2543Smrg        destoffset = decode_rm01_address(rl);
777706f2543Smrg        DECODE_PRINTF("\n");
778706f2543Smrg        break;
779706f2543Smrg      case 2:
780706f2543Smrg        destoffset = decode_rm10_address(rl);
781706f2543Smrg        DECODE_PRINTF("\n");
782706f2543Smrg        break;
783706f2543Smrg      case 3:                   /* register to register */
784706f2543Smrg		stkelem = (u8)rl;
785706f2543Smrg        DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
786706f2543Smrg        break;
787706f2543Smrg    }
788706f2543Smrg#ifdef X86EMU_FPU_PRESENT
789706f2543Smrg    switch (mod) {
790706f2543Smrg      case 3:
791706f2543Smrg        switch (rh) {
792706f2543Smrg          case 0:
793706f2543Smrg            x86emu_fpu_R_faddp(stkelem, X86EMU_FPU_STKTOP);
794706f2543Smrg            break;
795706f2543Smrg          case 1:
796706f2543Smrg            x86emu_fpu_R_fmulp(stkelem, X86EMU_FPU_STKTOP);
797706f2543Smrg            break;
798706f2543Smrg          case 2:
799706f2543Smrg            x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
800706f2543Smrg            break;
801706f2543Smrg          case 3:
802706f2543Smrg            if (stkelem == 1)
803706f2543Smrg              x86emu_fpu_R_fcompp(stkelem, X86EMU_FPU_STKTOP);
804706f2543Smrg            else
805706f2543Smrg              x86emu_fpu_illegal();
806706f2543Smrg            break;
807706f2543Smrg          case 4:
808706f2543Smrg            x86emu_fpu_R_fsubrp(stkelem, X86EMU_FPU_STKTOP);
809706f2543Smrg            break;
810706f2543Smrg          case 5:
811706f2543Smrg            x86emu_fpu_R_fsubp(stkelem, X86EMU_FPU_STKTOP);
812706f2543Smrg            break;
813706f2543Smrg          case 6:
814706f2543Smrg            x86emu_fpu_R_fdivrp(stkelem, X86EMU_FPU_STKTOP);
815706f2543Smrg            break;
816706f2543Smrg          case 7:
817706f2543Smrg            x86emu_fpu_R_fdivp(stkelem, X86EMU_FPU_STKTOP);
818706f2543Smrg            break;
819706f2543Smrg        }
820706f2543Smrg        break;
821706f2543Smrg      default:
822706f2543Smrg        switch (rh) {
823706f2543Smrg          case 0:
824706f2543Smrg            x86emu_fpu_M_fiadd(X86EMU_FPU_WORD, destoffset);
825706f2543Smrg            break;
826706f2543Smrg          case 1:
827706f2543Smrg            x86emu_fpu_M_fimul(X86EMU_FPU_WORD, destoffset);
828706f2543Smrg            break;
829706f2543Smrg          case 2:
830706f2543Smrg            x86emu_fpu_M_ficom(X86EMU_FPU_WORD, destoffset);
831706f2543Smrg            break;
832706f2543Smrg          case 3:
833706f2543Smrg            x86emu_fpu_M_ficomp(X86EMU_FPU_WORD, destoffset);
834706f2543Smrg            break;
835706f2543Smrg          case 4:
836706f2543Smrg            x86emu_fpu_M_fisub(X86EMU_FPU_WORD, destoffset);
837706f2543Smrg            break;
838706f2543Smrg          case 5:
839706f2543Smrg            x86emu_fpu_M_fisubr(X86EMU_FPU_WORD, destoffset);
840706f2543Smrg            break;
841706f2543Smrg          case 6:
842706f2543Smrg            x86emu_fpu_M_fidiv(X86EMU_FPU_WORD, destoffset);
843706f2543Smrg            break;
844706f2543Smrg          case 7:
845706f2543Smrg            x86emu_fpu_M_fidivr(X86EMU_FPU_WORD, destoffset);
846706f2543Smrg            break;
847706f2543Smrg        }
848706f2543Smrg    }
849706f2543Smrg#else
850706f2543Smrg    (void)destoffset;
851706f2543Smrg    (void)stkelem;
852706f2543Smrg#endif
853706f2543Smrg    DECODE_CLEAR_SEGOVR();
854706f2543Smrg    END_OF_INSTR_NO_TRACE();
855706f2543Smrg}
856706f2543Smrg
857706f2543Smrg#ifdef DEBUG
858706f2543Smrg
859706f2543Smrgstatic char *x86emu_fpu_op_df_tab[] = {
860706f2543Smrg    /* mod == 00 */
861706f2543Smrg    "FILD\tWORD PTR ", "ESC_DF\t39\n", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
862706f2543Smrg    "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
863706f2543Smrg    "FISTP\tQWORD PTR ",
864706f2543Smrg
865706f2543Smrg    /* mod == 01 */
866706f2543Smrg    "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
867706f2543Smrg    "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
868706f2543Smrg    "FISTP\tQWORD PTR ",
869706f2543Smrg
870706f2543Smrg    /* mod == 10 */
871706f2543Smrg    "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
872706f2543Smrg    "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
873706f2543Smrg    "FISTP\tQWORD PTR ",
874706f2543Smrg
875706f2543Smrg    /* mod == 11 */
876706f2543Smrg    "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
877706f2543Smrg    "ESC_DF\t3C,", "ESC_DF\t3D,", "ESC_DF\t3E,", "ESC_DF\t3F,"
878706f2543Smrg};
879706f2543Smrg
880706f2543Smrg#endif /* DEBUG */
881706f2543Smrg
882706f2543Smrg/* opcode=0xdf */
883706f2543Smrgvoid x86emuOp_esc_coprocess_df(u8 X86EMU_UNUSED(op1))
884706f2543Smrg{
885706f2543Smrg    int mod, rl, rh;
886706f2543Smrg    uint destoffset = 0;
887706f2543Smrg    u8 stkelem = 0;
888706f2543Smrg
889706f2543Smrg    START_OF_INSTR();
890706f2543Smrg    FETCH_DECODE_MODRM(mod, rh, rl);
891706f2543Smrg    DECODE_PRINTINSTR32(x86emu_fpu_op_df_tab, mod, rh, rl);
892706f2543Smrg    switch (mod) {
893706f2543Smrg      case 0:
894706f2543Smrg        destoffset = decode_rm00_address(rl);
895706f2543Smrg        DECODE_PRINTF("\n");
896706f2543Smrg        break;
897706f2543Smrg      case 1:
898706f2543Smrg        destoffset = decode_rm01_address(rl);
899706f2543Smrg        DECODE_PRINTF("\n");
900706f2543Smrg        break;
901706f2543Smrg      case 2:
902706f2543Smrg        destoffset = decode_rm10_address(rl);
903706f2543Smrg        DECODE_PRINTF("\n");
904706f2543Smrg        break;
905706f2543Smrg      case 3:                   /* register to register */
906706f2543Smrg		stkelem = (u8)rl;
907706f2543Smrg        DECODE_PRINTF2("\tST(%d)\n", stkelem);
908706f2543Smrg        break;
909706f2543Smrg    }
910706f2543Smrg#ifdef X86EMU_FPU_PRESENT
911706f2543Smrg    switch (mod) {
912706f2543Smrg      case 3:
913706f2543Smrg        switch (rh) {
914706f2543Smrg          case 0:
915706f2543Smrg            x86emu_fpu_R_ffree(stkelem);
916706f2543Smrg            break;
917706f2543Smrg          case 1:
918706f2543Smrg            x86emu_fpu_R_fxch(stkelem);
919706f2543Smrg            break;
920706f2543Smrg          case 2:
921706f2543Smrg            x86emu_fpu_R_fst(stkelem);  /* register version */
922706f2543Smrg            break;
923706f2543Smrg          case 3:
924706f2543Smrg            x86emu_fpu_R_fstp(stkelem); /* register version */
925706f2543Smrg            break;
926706f2543Smrg          default:
927706f2543Smrg            x86emu_fpu_illegal();
928706f2543Smrg            break;
929706f2543Smrg        }
930706f2543Smrg        break;
931706f2543Smrg      default:
932706f2543Smrg        switch (rh) {
933706f2543Smrg          case 0:
934706f2543Smrg            x86emu_fpu_M_fild(X86EMU_FPU_WORD, destoffset);
935706f2543Smrg            break;
936706f2543Smrg          case 1:
937706f2543Smrg            x86emu_fpu_illegal();
938706f2543Smrg            break;
939706f2543Smrg          case 2:
940706f2543Smrg            x86emu_fpu_M_fist(X86EMU_FPU_WORD, destoffset);
941706f2543Smrg            break;
942706f2543Smrg          case 3:
943706f2543Smrg            x86emu_fpu_M_fistp(X86EMU_FPU_WORD, destoffset);
944706f2543Smrg            break;
945706f2543Smrg          case 4:
946706f2543Smrg            x86emu_fpu_M_fbld(X86EMU_FPU_BSD, destoffset);
947706f2543Smrg            break;
948706f2543Smrg          case 5:
949706f2543Smrg            x86emu_fpu_M_fild(X86EMU_FPU_LONG, destoffset);
950706f2543Smrg            break;
951706f2543Smrg          case 6:
952706f2543Smrg            x86emu_fpu_M_fbstp(X86EMU_FPU_BSD, destoffset);
953706f2543Smrg            break;
954706f2543Smrg          case 7:
955706f2543Smrg            x86emu_fpu_M_fistp(X86EMU_FPU_LONG, destoffset);
956706f2543Smrg            break;
957706f2543Smrg        }
958706f2543Smrg    }
959706f2543Smrg#else
960706f2543Smrg    (void)destoffset;
961706f2543Smrg    (void)stkelem;
962706f2543Smrg#endif
963706f2543Smrg    DECODE_CLEAR_SEGOVR();
964706f2543Smrg    END_OF_INSTR_NO_TRACE();
965706f2543Smrg}
966