105b261ecSmrg/**************************************************************************** 205b261ecSmrg* 305b261ecSmrg* Realmode X86 Emulator Library 405b261ecSmrg* 505b261ecSmrg* Copyright (C) 1996-1999 SciTech Software, Inc. 605b261ecSmrg* Copyright (C) David Mosberger-Tang 705b261ecSmrg* Copyright (C) 1999 Egbert Eich 805b261ecSmrg* 905b261ecSmrg* ======================================================================== 1005b261ecSmrg* 1105b261ecSmrg* Permission to use, copy, modify, distribute, and sell this software and 1205b261ecSmrg* its documentation for any purpose is hereby granted without fee, 1305b261ecSmrg* provided that the above copyright notice appear in all copies and that 1405b261ecSmrg* both that copyright notice and this permission notice appear in 1505b261ecSmrg* supporting documentation, and that the name of the authors not be used 1605b261ecSmrg* in advertising or publicity pertaining to distribution of the software 1705b261ecSmrg* without specific, written prior permission. The authors makes no 1805b261ecSmrg* representations about the suitability of this software for any purpose. 1905b261ecSmrg* It is provided "as is" without express or implied warranty. 2005b261ecSmrg* 2105b261ecSmrg* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 2205b261ecSmrg* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 2305b261ecSmrg* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 2405b261ecSmrg* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 2505b261ecSmrg* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 2605b261ecSmrg* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2705b261ecSmrg* PERFORMANCE OF THIS SOFTWARE. 2805b261ecSmrg* 2905b261ecSmrg* ======================================================================== 3005b261ecSmrg* 3105b261ecSmrg* Language: ANSI C 3205b261ecSmrg* Environment: Any 3305b261ecSmrg* Developer: Kendall Bennett 3405b261ecSmrg* 3505b261ecSmrg* Description: This file contains the code to implement the decoding and 3605b261ecSmrg* emulation of the FPU instructions. 3705b261ecSmrg* 3805b261ecSmrg****************************************************************************/ 3905b261ecSmrg 4005b261ecSmrg#include "x86emu/x86emui.h" 4105b261ecSmrg 4205b261ecSmrg/*----------------------------- Implementation ----------------------------*/ 4305b261ecSmrg 4405b261ecSmrg/* opcode=0xd8 */ 4535c4bbdfSmrgvoid 4635c4bbdfSmrgx86emuOp_esc_coprocess_d8(u8 X86EMU_UNUSED(op1)) 4705b261ecSmrg{ 4805b261ecSmrg START_OF_INSTR(); 4905b261ecSmrg DECODE_PRINTF("ESC D8\n"); 5005b261ecSmrg DECODE_CLEAR_SEGOVR(); 5105b261ecSmrg END_OF_INSTR_NO_TRACE(); 5205b261ecSmrg} 5305b261ecSmrg 5405b261ecSmrg#ifdef DEBUG 5505b261ecSmrg 5635c4bbdfSmrgstatic const char *x86emu_fpu_op_d9_tab[] = { 5705b261ecSmrg "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ", 5805b261ecSmrg "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t", 5905b261ecSmrg 6005b261ecSmrg "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ", 6105b261ecSmrg "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t", 6205b261ecSmrg 6305b261ecSmrg "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ", 6405b261ecSmrg "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t", 6505b261ecSmrg}; 6605b261ecSmrg 6735c4bbdfSmrgstatic const char *x86emu_fpu_op_d9_tab1[] = { 6805b261ecSmrg "FLD\t", "FLD\t", "FLD\t", "FLD\t", 6905b261ecSmrg "FLD\t", "FLD\t", "FLD\t", "FLD\t", 7005b261ecSmrg 7105b261ecSmrg "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t", 7205b261ecSmrg "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t", 7305b261ecSmrg 7405b261ecSmrg "FNOP", "ESC_D9", "ESC_D9", "ESC_D9", 7505b261ecSmrg "ESC_D9", "ESC_D9", "ESC_D9", "ESC_D9", 7605b261ecSmrg 7705b261ecSmrg "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t", 7805b261ecSmrg "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t", 7905b261ecSmrg 8005b261ecSmrg "FCHS", "FABS", "ESC_D9", "ESC_D9", 8105b261ecSmrg "FTST", "FXAM", "ESC_D9", "ESC_D9", 8205b261ecSmrg 8305b261ecSmrg "FLD1", "FLDL2T", "FLDL2E", "FLDPI", 8405b261ecSmrg "FLDLG2", "FLDLN2", "FLDZ", "ESC_D9", 8505b261ecSmrg 8605b261ecSmrg "F2XM1", "FYL2X", "FPTAN", "FPATAN", 8705b261ecSmrg "FXTRACT", "ESC_D9", "FDECSTP", "FINCSTP", 8805b261ecSmrg 8905b261ecSmrg "FPREM", "FYL2XP1", "FSQRT", "ESC_D9", 9005b261ecSmrg "FRNDINT", "FSCALE", "ESC_D9", "ESC_D9", 9105b261ecSmrg}; 9205b261ecSmrg 9335c4bbdfSmrg#endif /* DEBUG */ 9405b261ecSmrg 9505b261ecSmrg/* opcode=0xd9 */ 9635c4bbdfSmrgvoid 9735c4bbdfSmrgx86emuOp_esc_coprocess_d9(u8 X86EMU_UNUSED(op1)) 9805b261ecSmrg{ 9905b261ecSmrg int mod, rl, rh; 10005b261ecSmrg uint destoffset = 0; 10105b261ecSmrg u8 stkelem = 0; 10205b261ecSmrg 10305b261ecSmrg START_OF_INSTR(); 10405b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 10505b261ecSmrg#ifdef DEBUG 10605b261ecSmrg if (mod != 3) { 10705b261ecSmrg DECODE_PRINTINSTR32(x86emu_fpu_op_d9_tab, mod, rh, rl); 10835c4bbdfSmrg } 10935c4bbdfSmrg else { 11005b261ecSmrg DECODE_PRINTF(x86emu_fpu_op_d9_tab1[(rh << 3) + rl]); 11105b261ecSmrg } 11205b261ecSmrg#endif 11305b261ecSmrg switch (mod) { 11435c4bbdfSmrg case 0: 11505b261ecSmrg destoffset = decode_rm00_address(rl); 11605b261ecSmrg DECODE_PRINTF("\n"); 11705b261ecSmrg break; 11835c4bbdfSmrg case 1: 11905b261ecSmrg destoffset = decode_rm01_address(rl); 12005b261ecSmrg DECODE_PRINTF("\n"); 12105b261ecSmrg break; 12235c4bbdfSmrg case 2: 12305b261ecSmrg destoffset = decode_rm10_address(rl); 12405b261ecSmrg DECODE_PRINTF("\n"); 12505b261ecSmrg break; 12635c4bbdfSmrg case 3: /* register to register */ 12735c4bbdfSmrg stkelem = (u8) rl; 12835c4bbdfSmrg if (rh < 4) { 12935c4bbdfSmrg DECODE_PRINTF2("ST(%d)\n", stkelem); 13035c4bbdfSmrg } 13135c4bbdfSmrg else { 13235c4bbdfSmrg DECODE_PRINTF("\n"); 13335c4bbdfSmrg } 13405b261ecSmrg break; 13505b261ecSmrg } 13605b261ecSmrg#ifdef X86EMU_FPU_PRESENT 13705b261ecSmrg /* execute */ 13805b261ecSmrg switch (mod) { 13935c4bbdfSmrg case 3: 14005b261ecSmrg switch (rh) { 14135c4bbdfSmrg case 0: 14205b261ecSmrg x86emu_fpu_R_fld(X86EMU_FPU_STKTOP, stkelem); 14305b261ecSmrg break; 14435c4bbdfSmrg case 1: 14505b261ecSmrg x86emu_fpu_R_fxch(X86EMU_FPU_STKTOP, stkelem); 14605b261ecSmrg break; 14735c4bbdfSmrg case 2: 14805b261ecSmrg switch (rl) { 14935c4bbdfSmrg case 0: 15005b261ecSmrg x86emu_fpu_R_nop(); 15105b261ecSmrg break; 15235c4bbdfSmrg default: 15305b261ecSmrg x86emu_fpu_illegal(); 15405b261ecSmrg break; 15505b261ecSmrg } 15635c4bbdfSmrg case 3: 15705b261ecSmrg x86emu_fpu_R_fstp(X86EMU_FPU_STKTOP, stkelem); 15805b261ecSmrg break; 15935c4bbdfSmrg case 4: 16005b261ecSmrg switch (rl) { 16105b261ecSmrg case 0: 16205b261ecSmrg x86emu_fpu_R_fchs(X86EMU_FPU_STKTOP); 16305b261ecSmrg break; 16405b261ecSmrg case 1: 16505b261ecSmrg x86emu_fpu_R_fabs(X86EMU_FPU_STKTOP); 16605b261ecSmrg break; 16705b261ecSmrg case 4: 16805b261ecSmrg x86emu_fpu_R_ftst(X86EMU_FPU_STKTOP); 16905b261ecSmrg break; 17005b261ecSmrg case 5: 17105b261ecSmrg x86emu_fpu_R_fxam(X86EMU_FPU_STKTOP); 17205b261ecSmrg break; 17305b261ecSmrg default: 17405b261ecSmrg /* 2,3,6,7 */ 17505b261ecSmrg x86emu_fpu_illegal(); 17605b261ecSmrg break; 17705b261ecSmrg } 17805b261ecSmrg break; 17905b261ecSmrg 18035c4bbdfSmrg case 5: 18105b261ecSmrg switch (rl) { 18235c4bbdfSmrg case 0: 18305b261ecSmrg x86emu_fpu_R_fld1(X86EMU_FPU_STKTOP); 18405b261ecSmrg break; 18535c4bbdfSmrg case 1: 18605b261ecSmrg x86emu_fpu_R_fldl2t(X86EMU_FPU_STKTOP); 18705b261ecSmrg break; 18835c4bbdfSmrg case 2: 18905b261ecSmrg x86emu_fpu_R_fldl2e(X86EMU_FPU_STKTOP); 19005b261ecSmrg break; 19135c4bbdfSmrg case 3: 19205b261ecSmrg x86emu_fpu_R_fldpi(X86EMU_FPU_STKTOP); 19305b261ecSmrg break; 19435c4bbdfSmrg case 4: 19505b261ecSmrg x86emu_fpu_R_fldlg2(X86EMU_FPU_STKTOP); 19605b261ecSmrg break; 19735c4bbdfSmrg case 5: 19805b261ecSmrg x86emu_fpu_R_fldln2(X86EMU_FPU_STKTOP); 19905b261ecSmrg break; 20035c4bbdfSmrg case 6: 20105b261ecSmrg x86emu_fpu_R_fldz(X86EMU_FPU_STKTOP); 20205b261ecSmrg break; 20335c4bbdfSmrg default: 20405b261ecSmrg /* 7 */ 20505b261ecSmrg x86emu_fpu_illegal(); 20605b261ecSmrg break; 20705b261ecSmrg } 20805b261ecSmrg break; 20905b261ecSmrg 21035c4bbdfSmrg case 6: 21105b261ecSmrg switch (rl) { 21235c4bbdfSmrg case 0: 21305b261ecSmrg x86emu_fpu_R_f2xm1(X86EMU_FPU_STKTOP); 21405b261ecSmrg break; 21535c4bbdfSmrg case 1: 21605b261ecSmrg x86emu_fpu_R_fyl2x(X86EMU_FPU_STKTOP); 21705b261ecSmrg break; 21835c4bbdfSmrg case 2: 21905b261ecSmrg x86emu_fpu_R_fptan(X86EMU_FPU_STKTOP); 22005b261ecSmrg break; 22135c4bbdfSmrg case 3: 22205b261ecSmrg x86emu_fpu_R_fpatan(X86EMU_FPU_STKTOP); 22305b261ecSmrg break; 22435c4bbdfSmrg case 4: 22505b261ecSmrg x86emu_fpu_R_fxtract(X86EMU_FPU_STKTOP); 22605b261ecSmrg break; 22735c4bbdfSmrg case 5: 22805b261ecSmrg x86emu_fpu_illegal(); 22905b261ecSmrg break; 23035c4bbdfSmrg case 6: 23105b261ecSmrg x86emu_fpu_R_decstp(); 23205b261ecSmrg break; 23335c4bbdfSmrg case 7: 23405b261ecSmrg x86emu_fpu_R_incstp(); 23505b261ecSmrg break; 23605b261ecSmrg } 23705b261ecSmrg break; 23805b261ecSmrg 23935c4bbdfSmrg case 7: 24005b261ecSmrg switch (rl) { 24135c4bbdfSmrg case 0: 24205b261ecSmrg x86emu_fpu_R_fprem(X86EMU_FPU_STKTOP); 24305b261ecSmrg break; 24435c4bbdfSmrg case 1: 24505b261ecSmrg x86emu_fpu_R_fyl2xp1(X86EMU_FPU_STKTOP); 24605b261ecSmrg break; 24735c4bbdfSmrg case 2: 24805b261ecSmrg x86emu_fpu_R_fsqrt(X86EMU_FPU_STKTOP); 24905b261ecSmrg break; 25035c4bbdfSmrg case 3: 25105b261ecSmrg x86emu_fpu_illegal(); 25205b261ecSmrg break; 25335c4bbdfSmrg case 4: 25405b261ecSmrg x86emu_fpu_R_frndint(X86EMU_FPU_STKTOP); 25505b261ecSmrg break; 25635c4bbdfSmrg case 5: 25705b261ecSmrg x86emu_fpu_R_fscale(X86EMU_FPU_STKTOP); 25805b261ecSmrg break; 25935c4bbdfSmrg case 6: 26035c4bbdfSmrg case 7: 26135c4bbdfSmrg default: 26205b261ecSmrg x86emu_fpu_illegal(); 26305b261ecSmrg break; 26405b261ecSmrg } 26505b261ecSmrg break; 26605b261ecSmrg 26735c4bbdfSmrg default: 26805b261ecSmrg switch (rh) { 26935c4bbdfSmrg case 0: 27005b261ecSmrg x86emu_fpu_M_fld(X86EMU_FPU_FLOAT, destoffset); 27105b261ecSmrg break; 27235c4bbdfSmrg case 1: 27305b261ecSmrg x86emu_fpu_illegal(); 27405b261ecSmrg break; 27535c4bbdfSmrg case 2: 27605b261ecSmrg x86emu_fpu_M_fst(X86EMU_FPU_FLOAT, destoffset); 27705b261ecSmrg break; 27835c4bbdfSmrg case 3: 27905b261ecSmrg x86emu_fpu_M_fstp(X86EMU_FPU_FLOAT, destoffset); 28005b261ecSmrg break; 28135c4bbdfSmrg case 4: 28205b261ecSmrg x86emu_fpu_M_fldenv(X86EMU_FPU_WORD, destoffset); 28305b261ecSmrg break; 28435c4bbdfSmrg case 5: 28505b261ecSmrg x86emu_fpu_M_fldcw(X86EMU_FPU_WORD, destoffset); 28605b261ecSmrg break; 28735c4bbdfSmrg case 6: 28805b261ecSmrg x86emu_fpu_M_fstenv(X86EMU_FPU_WORD, destoffset); 28905b261ecSmrg break; 29035c4bbdfSmrg case 7: 29105b261ecSmrg x86emu_fpu_M_fstcw(X86EMU_FPU_WORD, destoffset); 29205b261ecSmrg break; 29305b261ecSmrg } 29405b261ecSmrg } 29505b261ecSmrg } 29605b261ecSmrg#else 29735c4bbdfSmrg (void) destoffset; 29835c4bbdfSmrg (void) stkelem; 29935c4bbdfSmrg#endif /* X86EMU_FPU_PRESENT */ 30005b261ecSmrg DECODE_CLEAR_SEGOVR(); 30105b261ecSmrg END_OF_INSTR_NO_TRACE(); 30205b261ecSmrg} 30305b261ecSmrg 30405b261ecSmrg#ifdef DEBUG 30505b261ecSmrg 30635c4bbdfSmrgstatic const char *x86emu_fpu_op_da_tab[] = { 30705b261ecSmrg "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ", 30805b261ecSmrg "FICOMP\tDWORD PTR ", 30905b261ecSmrg "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ", 31005b261ecSmrg "FIDIVR\tDWORD PTR ", 31105b261ecSmrg 31205b261ecSmrg "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ", 31305b261ecSmrg "FICOMP\tDWORD PTR ", 31405b261ecSmrg "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ", 31505b261ecSmrg "FIDIVR\tDWORD PTR ", 31635c4bbdfSmrg 31705b261ecSmrg "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ", 31805b261ecSmrg "FICOMP\tDWORD PTR ", 31905b261ecSmrg "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ", 32005b261ecSmrg "FIDIVR\tDWORD PTR ", 32105b261ecSmrg 32205b261ecSmrg "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ", 32305b261ecSmrg "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ", 32405b261ecSmrg}; 32505b261ecSmrg 32635c4bbdfSmrg#endif /* DEBUG */ 32705b261ecSmrg 32805b261ecSmrg/* opcode=0xda */ 32935c4bbdfSmrgvoid 33035c4bbdfSmrgx86emuOp_esc_coprocess_da(u8 X86EMU_UNUSED(op1)) 33105b261ecSmrg{ 33205b261ecSmrg int mod, rl, rh; 33305b261ecSmrg uint destoffset = 0; 33405b261ecSmrg u8 stkelem = 0; 33505b261ecSmrg 33605b261ecSmrg START_OF_INSTR(); 33705b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 33805b261ecSmrg DECODE_PRINTINSTR32(x86emu_fpu_op_da_tab, mod, rh, rl); 33905b261ecSmrg switch (mod) { 34035c4bbdfSmrg case 0: 34105b261ecSmrg destoffset = decode_rm00_address(rl); 34205b261ecSmrg DECODE_PRINTF("\n"); 34305b261ecSmrg break; 34435c4bbdfSmrg case 1: 34505b261ecSmrg destoffset = decode_rm01_address(rl); 34605b261ecSmrg DECODE_PRINTF("\n"); 34705b261ecSmrg break; 34835c4bbdfSmrg case 2: 34905b261ecSmrg destoffset = decode_rm10_address(rl); 35005b261ecSmrg DECODE_PRINTF("\n"); 35105b261ecSmrg break; 35235c4bbdfSmrg case 3: /* register to register */ 35335c4bbdfSmrg stkelem = (u8) rl; 35405b261ecSmrg DECODE_PRINTF2("\tST(%d),ST\n", stkelem); 35505b261ecSmrg break; 35605b261ecSmrg } 35705b261ecSmrg#ifdef X86EMU_FPU_PRESENT 35805b261ecSmrg switch (mod) { 35935c4bbdfSmrg case 3: 36005b261ecSmrg x86emu_fpu_illegal(); 36105b261ecSmrg break; 36235c4bbdfSmrg default: 36305b261ecSmrg switch (rh) { 36435c4bbdfSmrg case 0: 36505b261ecSmrg x86emu_fpu_M_iadd(X86EMU_FPU_SHORT, destoffset); 36605b261ecSmrg break; 36735c4bbdfSmrg case 1: 36805b261ecSmrg x86emu_fpu_M_imul(X86EMU_FPU_SHORT, destoffset); 36905b261ecSmrg break; 37035c4bbdfSmrg case 2: 37105b261ecSmrg x86emu_fpu_M_icom(X86EMU_FPU_SHORT, destoffset); 37205b261ecSmrg break; 37335c4bbdfSmrg case 3: 37405b261ecSmrg x86emu_fpu_M_icomp(X86EMU_FPU_SHORT, destoffset); 37505b261ecSmrg break; 37635c4bbdfSmrg case 4: 37705b261ecSmrg x86emu_fpu_M_isub(X86EMU_FPU_SHORT, destoffset); 37805b261ecSmrg break; 37935c4bbdfSmrg case 5: 38005b261ecSmrg x86emu_fpu_M_isubr(X86EMU_FPU_SHORT, destoffset); 38105b261ecSmrg break; 38235c4bbdfSmrg case 6: 38305b261ecSmrg x86emu_fpu_M_idiv(X86EMU_FPU_SHORT, destoffset); 38405b261ecSmrg break; 38535c4bbdfSmrg case 7: 38605b261ecSmrg x86emu_fpu_M_idivr(X86EMU_FPU_SHORT, destoffset); 38705b261ecSmrg break; 38805b261ecSmrg } 38905b261ecSmrg } 39005b261ecSmrg#else 39135c4bbdfSmrg (void) destoffset; 39235c4bbdfSmrg (void) stkelem; 39305b261ecSmrg#endif 39405b261ecSmrg DECODE_CLEAR_SEGOVR(); 39505b261ecSmrg END_OF_INSTR_NO_TRACE(); 39605b261ecSmrg} 39705b261ecSmrg 39805b261ecSmrg#ifdef DEBUG 39905b261ecSmrg 40035c4bbdfSmrgstatic const char *x86emu_fpu_op_db_tab[] = { 40105b261ecSmrg "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ", 40205b261ecSmrg "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ", 40305b261ecSmrg 40405b261ecSmrg "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ", 40505b261ecSmrg "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ", 40605b261ecSmrg 40705b261ecSmrg "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ", 40805b261ecSmrg "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ", 40905b261ecSmrg}; 41005b261ecSmrg 41135c4bbdfSmrg#endif /* DEBUG */ 41205b261ecSmrg 41305b261ecSmrg/* opcode=0xdb */ 41435c4bbdfSmrgvoid 41535c4bbdfSmrgx86emuOp_esc_coprocess_db(u8 X86EMU_UNUSED(op1)) 41605b261ecSmrg{ 41705b261ecSmrg int mod, rl, rh; 41805b261ecSmrg uint destoffset = 0; 41905b261ecSmrg 42005b261ecSmrg START_OF_INSTR(); 42105b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 42205b261ecSmrg#ifdef DEBUG 42305b261ecSmrg if (mod != 3) { 42405b261ecSmrg DECODE_PRINTINSTR32(x86emu_fpu_op_db_tab, mod, rh, rl); 42535c4bbdfSmrg } 42635c4bbdfSmrg else if (rh == 4) { /* === 11 10 0 nnn */ 42705b261ecSmrg switch (rl) { 42835c4bbdfSmrg case 0: 42905b261ecSmrg DECODE_PRINTF("FENI\n"); 43005b261ecSmrg break; 43135c4bbdfSmrg case 1: 43205b261ecSmrg DECODE_PRINTF("FDISI\n"); 43305b261ecSmrg break; 43435c4bbdfSmrg case 2: 43505b261ecSmrg DECODE_PRINTF("FCLEX\n"); 43605b261ecSmrg break; 43735c4bbdfSmrg case 3: 43805b261ecSmrg DECODE_PRINTF("FINIT\n"); 43905b261ecSmrg break; 44005b261ecSmrg } 44135c4bbdfSmrg } 44235c4bbdfSmrg else { 44305b261ecSmrg DECODE_PRINTF2("ESC_DB %0x\n", (mod << 6) + (rh << 3) + (rl)); 44405b261ecSmrg } 44535c4bbdfSmrg#endif /* DEBUG */ 44605b261ecSmrg switch (mod) { 44735c4bbdfSmrg case 0: 44805b261ecSmrg destoffset = decode_rm00_address(rl); 44905b261ecSmrg break; 45035c4bbdfSmrg case 1: 45105b261ecSmrg destoffset = decode_rm01_address(rl); 45205b261ecSmrg break; 45335c4bbdfSmrg case 2: 45405b261ecSmrg destoffset = decode_rm10_address(rl); 45505b261ecSmrg break; 45635c4bbdfSmrg case 3: /* register to register */ 45705b261ecSmrg break; 45805b261ecSmrg } 45905b261ecSmrg#ifdef X86EMU_FPU_PRESENT 46005b261ecSmrg /* execute */ 46105b261ecSmrg switch (mod) { 46235c4bbdfSmrg case 3: 46305b261ecSmrg switch (rh) { 46435c4bbdfSmrg case 4: 46505b261ecSmrg switch (rl) { 46635c4bbdfSmrg case 0: 46705b261ecSmrg x86emu_fpu_R_feni(); 46805b261ecSmrg break; 46935c4bbdfSmrg case 1: 47005b261ecSmrg x86emu_fpu_R_fdisi(); 47105b261ecSmrg break; 47235c4bbdfSmrg case 2: 47305b261ecSmrg x86emu_fpu_R_fclex(); 47405b261ecSmrg break; 47535c4bbdfSmrg case 3: 47605b261ecSmrg x86emu_fpu_R_finit(); 47705b261ecSmrg break; 47835c4bbdfSmrg default: 47905b261ecSmrg x86emu_fpu_illegal(); 48005b261ecSmrg break; 48105b261ecSmrg } 48205b261ecSmrg break; 48335c4bbdfSmrg default: 48405b261ecSmrg x86emu_fpu_illegal(); 48505b261ecSmrg break; 48605b261ecSmrg } 48705b261ecSmrg break; 48835c4bbdfSmrg default: 48905b261ecSmrg switch (rh) { 49035c4bbdfSmrg case 0: 49105b261ecSmrg x86emu_fpu_M_fild(X86EMU_FPU_SHORT, destoffset); 49205b261ecSmrg break; 49335c4bbdfSmrg case 1: 49405b261ecSmrg x86emu_fpu_illegal(); 49505b261ecSmrg break; 49635c4bbdfSmrg case 2: 49705b261ecSmrg x86emu_fpu_M_fist(X86EMU_FPU_SHORT, destoffset); 49805b261ecSmrg break; 49935c4bbdfSmrg case 3: 50005b261ecSmrg x86emu_fpu_M_fistp(X86EMU_FPU_SHORT, destoffset); 50105b261ecSmrg break; 50235c4bbdfSmrg case 4: 50305b261ecSmrg x86emu_fpu_illegal(); 50405b261ecSmrg break; 50535c4bbdfSmrg case 5: 50605b261ecSmrg x86emu_fpu_M_fld(X86EMU_FPU_LDBL, destoffset); 50705b261ecSmrg break; 50835c4bbdfSmrg case 6: 50905b261ecSmrg x86emu_fpu_illegal(); 51005b261ecSmrg break; 51135c4bbdfSmrg case 7: 51205b261ecSmrg x86emu_fpu_M_fstp(X86EMU_FPU_LDBL, destoffset); 51305b261ecSmrg break; 51405b261ecSmrg } 51505b261ecSmrg } 51605b261ecSmrg#else 51735c4bbdfSmrg (void) destoffset; 51805b261ecSmrg#endif 51905b261ecSmrg DECODE_CLEAR_SEGOVR(); 52005b261ecSmrg END_OF_INSTR_NO_TRACE(); 52105b261ecSmrg} 52205b261ecSmrg 52305b261ecSmrg#ifdef DEBUG 52435c4bbdfSmrgstatic const char *x86emu_fpu_op_dc_tab[] = { 52505b261ecSmrg "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ", 52605b261ecSmrg "FCOMP\tQWORD PTR ", 52705b261ecSmrg "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ", 52805b261ecSmrg "FDIVR\tQWORD PTR ", 52905b261ecSmrg 53005b261ecSmrg "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ", 53105b261ecSmrg "FCOMP\tQWORD PTR ", 53205b261ecSmrg "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ", 53305b261ecSmrg "FDIVR\tQWORD PTR ", 53405b261ecSmrg 53505b261ecSmrg "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ", 53605b261ecSmrg "FCOMP\tQWORD PTR ", 53705b261ecSmrg "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ", 53805b261ecSmrg "FDIVR\tQWORD PTR ", 53905b261ecSmrg 54005b261ecSmrg "FADD\t", "FMUL\t", "FCOM\t", "FCOMP\t", 54105b261ecSmrg "FSUBR\t", "FSUB\t", "FDIVR\t", "FDIV\t", 54205b261ecSmrg}; 54335c4bbdfSmrg#endif /* DEBUG */ 54405b261ecSmrg 54505b261ecSmrg/* opcode=0xdc */ 54635c4bbdfSmrgvoid 54735c4bbdfSmrgx86emuOp_esc_coprocess_dc(u8 X86EMU_UNUSED(op1)) 54805b261ecSmrg{ 54905b261ecSmrg int mod, rl, rh; 55005b261ecSmrg uint destoffset = 0; 55105b261ecSmrg u8 stkelem = 0; 55205b261ecSmrg 55305b261ecSmrg START_OF_INSTR(); 55405b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 55505b261ecSmrg DECODE_PRINTINSTR32(x86emu_fpu_op_dc_tab, mod, rh, rl); 55605b261ecSmrg switch (mod) { 55735c4bbdfSmrg case 0: 55805b261ecSmrg destoffset = decode_rm00_address(rl); 55905b261ecSmrg DECODE_PRINTF("\n"); 56005b261ecSmrg break; 56135c4bbdfSmrg case 1: 56205b261ecSmrg destoffset = decode_rm01_address(rl); 56305b261ecSmrg DECODE_PRINTF("\n"); 56405b261ecSmrg break; 56535c4bbdfSmrg case 2: 56605b261ecSmrg destoffset = decode_rm10_address(rl); 56705b261ecSmrg DECODE_PRINTF("\n"); 56805b261ecSmrg break; 56935c4bbdfSmrg case 3: /* register to register */ 57035c4bbdfSmrg stkelem = (u8) rl; 57105b261ecSmrg DECODE_PRINTF2("\tST(%d),ST\n", stkelem); 57205b261ecSmrg break; 57305b261ecSmrg } 57405b261ecSmrg#ifdef X86EMU_FPU_PRESENT 57505b261ecSmrg /* execute */ 57605b261ecSmrg switch (mod) { 57735c4bbdfSmrg case 3: 57805b261ecSmrg switch (rh) { 57935c4bbdfSmrg case 0: 58005b261ecSmrg x86emu_fpu_R_fadd(stkelem, X86EMU_FPU_STKTOP); 58105b261ecSmrg break; 58235c4bbdfSmrg case 1: 58305b261ecSmrg x86emu_fpu_R_fmul(stkelem, X86EMU_FPU_STKTOP); 58405b261ecSmrg break; 58535c4bbdfSmrg case 2: 58605b261ecSmrg x86emu_fpu_R_fcom(stkelem, X86EMU_FPU_STKTOP); 58705b261ecSmrg break; 58835c4bbdfSmrg case 3: 58905b261ecSmrg x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP); 59005b261ecSmrg break; 59135c4bbdfSmrg case 4: 59205b261ecSmrg x86emu_fpu_R_fsubr(stkelem, X86EMU_FPU_STKTOP); 59305b261ecSmrg break; 59435c4bbdfSmrg case 5: 59505b261ecSmrg x86emu_fpu_R_fsub(stkelem, X86EMU_FPU_STKTOP); 59605b261ecSmrg break; 59735c4bbdfSmrg case 6: 59805b261ecSmrg x86emu_fpu_R_fdivr(stkelem, X86EMU_FPU_STKTOP); 59905b261ecSmrg break; 60035c4bbdfSmrg case 7: 60105b261ecSmrg x86emu_fpu_R_fdiv(stkelem, X86EMU_FPU_STKTOP); 60205b261ecSmrg break; 60305b261ecSmrg } 60405b261ecSmrg break; 60535c4bbdfSmrg default: 60605b261ecSmrg switch (rh) { 60735c4bbdfSmrg case 0: 60805b261ecSmrg x86emu_fpu_M_fadd(X86EMU_FPU_DOUBLE, destoffset); 60905b261ecSmrg break; 61035c4bbdfSmrg case 1: 61105b261ecSmrg x86emu_fpu_M_fmul(X86EMU_FPU_DOUBLE, destoffset); 61205b261ecSmrg break; 61335c4bbdfSmrg case 2: 61405b261ecSmrg x86emu_fpu_M_fcom(X86EMU_FPU_DOUBLE, destoffset); 61505b261ecSmrg break; 61635c4bbdfSmrg case 3: 61705b261ecSmrg x86emu_fpu_M_fcomp(X86EMU_FPU_DOUBLE, destoffset); 61805b261ecSmrg break; 61935c4bbdfSmrg case 4: 62005b261ecSmrg x86emu_fpu_M_fsub(X86EMU_FPU_DOUBLE, destoffset); 62105b261ecSmrg break; 62235c4bbdfSmrg case 5: 62305b261ecSmrg x86emu_fpu_M_fsubr(X86EMU_FPU_DOUBLE, destoffset); 62405b261ecSmrg break; 62535c4bbdfSmrg case 6: 62605b261ecSmrg x86emu_fpu_M_fdiv(X86EMU_FPU_DOUBLE, destoffset); 62705b261ecSmrg break; 62835c4bbdfSmrg case 7: 62905b261ecSmrg x86emu_fpu_M_fdivr(X86EMU_FPU_DOUBLE, destoffset); 63005b261ecSmrg break; 63105b261ecSmrg } 63205b261ecSmrg } 63305b261ecSmrg#else 63435c4bbdfSmrg (void) destoffset; 63535c4bbdfSmrg (void) stkelem; 63605b261ecSmrg#endif 63705b261ecSmrg DECODE_CLEAR_SEGOVR(); 63805b261ecSmrg END_OF_INSTR_NO_TRACE(); 63905b261ecSmrg} 64005b261ecSmrg 64105b261ecSmrg#ifdef DEBUG 64205b261ecSmrg 64335c4bbdfSmrgstatic const char *x86emu_fpu_op_dd_tab[] = { 64405b261ecSmrg "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ", 64505b261ecSmrg "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t", 64605b261ecSmrg 64705b261ecSmrg "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ", 64805b261ecSmrg "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t", 64905b261ecSmrg 65005b261ecSmrg "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ", 65105b261ecSmrg "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t", 65205b261ecSmrg 65305b261ecSmrg "FFREE\t", "FXCH\t", "FST\t", "FSTP\t", 65405b261ecSmrg "ESC_DD\t2C,", "ESC_DD\t2D,", "ESC_DD\t2E,", "ESC_DD\t2F,", 65505b261ecSmrg}; 65605b261ecSmrg 65735c4bbdfSmrg#endif /* DEBUG */ 65805b261ecSmrg 65905b261ecSmrg/* opcode=0xdd */ 66035c4bbdfSmrgvoid 66135c4bbdfSmrgx86emuOp_esc_coprocess_dd(u8 X86EMU_UNUSED(op1)) 66205b261ecSmrg{ 66305b261ecSmrg int mod, rl, rh; 66405b261ecSmrg uint destoffset = 0; 66505b261ecSmrg u8 stkelem = 0; 66605b261ecSmrg 66705b261ecSmrg START_OF_INSTR(); 66805b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 66905b261ecSmrg DECODE_PRINTINSTR32(x86emu_fpu_op_dd_tab, mod, rh, rl); 67005b261ecSmrg switch (mod) { 67135c4bbdfSmrg case 0: 67205b261ecSmrg destoffset = decode_rm00_address(rl); 67305b261ecSmrg DECODE_PRINTF("\n"); 67405b261ecSmrg break; 67535c4bbdfSmrg case 1: 67605b261ecSmrg destoffset = decode_rm01_address(rl); 67705b261ecSmrg DECODE_PRINTF("\n"); 67805b261ecSmrg break; 67935c4bbdfSmrg case 2: 68005b261ecSmrg destoffset = decode_rm10_address(rl); 68105b261ecSmrg DECODE_PRINTF("\n"); 68205b261ecSmrg break; 68335c4bbdfSmrg case 3: /* register to register */ 68435c4bbdfSmrg stkelem = (u8) rl; 68505b261ecSmrg DECODE_PRINTF2("\tST(%d),ST\n", stkelem); 68605b261ecSmrg break; 68705b261ecSmrg } 68805b261ecSmrg#ifdef X86EMU_FPU_PRESENT 68905b261ecSmrg switch (mod) { 69035c4bbdfSmrg case 3: 69105b261ecSmrg switch (rh) { 69235c4bbdfSmrg case 0: 69305b261ecSmrg x86emu_fpu_R_ffree(stkelem); 69405b261ecSmrg break; 69535c4bbdfSmrg case 1: 69605b261ecSmrg x86emu_fpu_R_fxch(stkelem); 69705b261ecSmrg break; 69835c4bbdfSmrg case 2: 69905b261ecSmrg x86emu_fpu_R_fst(stkelem); /* register version */ 70005b261ecSmrg break; 70135c4bbdfSmrg case 3: 70205b261ecSmrg x86emu_fpu_R_fstp(stkelem); /* register version */ 70305b261ecSmrg break; 70435c4bbdfSmrg default: 70505b261ecSmrg x86emu_fpu_illegal(); 70605b261ecSmrg break; 70705b261ecSmrg } 70805b261ecSmrg break; 70935c4bbdfSmrg default: 71005b261ecSmrg switch (rh) { 71135c4bbdfSmrg case 0: 71205b261ecSmrg x86emu_fpu_M_fld(X86EMU_FPU_DOUBLE, destoffset); 71305b261ecSmrg break; 71435c4bbdfSmrg case 1: 71505b261ecSmrg x86emu_fpu_illegal(); 71605b261ecSmrg break; 71735c4bbdfSmrg case 2: 71805b261ecSmrg x86emu_fpu_M_fst(X86EMU_FPU_DOUBLE, destoffset); 71905b261ecSmrg break; 72035c4bbdfSmrg case 3: 72105b261ecSmrg x86emu_fpu_M_fstp(X86EMU_FPU_DOUBLE, destoffset); 72205b261ecSmrg break; 72335c4bbdfSmrg case 4: 72405b261ecSmrg x86emu_fpu_M_frstor(X86EMU_FPU_WORD, destoffset); 72505b261ecSmrg break; 72635c4bbdfSmrg case 5: 72705b261ecSmrg x86emu_fpu_illegal(); 72805b261ecSmrg break; 72935c4bbdfSmrg case 6: 73005b261ecSmrg x86emu_fpu_M_fsave(X86EMU_FPU_WORD, destoffset); 73105b261ecSmrg break; 73235c4bbdfSmrg case 7: 73305b261ecSmrg x86emu_fpu_M_fstsw(X86EMU_FPU_WORD, destoffset); 73405b261ecSmrg break; 73505b261ecSmrg } 73605b261ecSmrg } 73705b261ecSmrg#else 73835c4bbdfSmrg (void) destoffset; 73935c4bbdfSmrg (void) stkelem; 74005b261ecSmrg#endif 74105b261ecSmrg DECODE_CLEAR_SEGOVR(); 74205b261ecSmrg END_OF_INSTR_NO_TRACE(); 74305b261ecSmrg} 74405b261ecSmrg 74505b261ecSmrg#ifdef DEBUG 74605b261ecSmrg 74735c4bbdfSmrgstatic const char *x86emu_fpu_op_de_tab[] = { 74805b261ecSmrg "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ", 74905b261ecSmrg "FICOMP\tWORD PTR ", 75005b261ecSmrg "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ", 75105b261ecSmrg "FIDIVR\tWORD PTR ", 75205b261ecSmrg 75305b261ecSmrg "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ", 75405b261ecSmrg "FICOMP\tWORD PTR ", 75505b261ecSmrg "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ", 75605b261ecSmrg "FIDIVR\tWORD PTR ", 75705b261ecSmrg 75805b261ecSmrg "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ", 75905b261ecSmrg "FICOMP\tWORD PTR ", 76005b261ecSmrg "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ", 76105b261ecSmrg "FIDIVR\tWORD PTR ", 76205b261ecSmrg 76305b261ecSmrg "FADDP\t", "FMULP\t", "FCOMP\t", "FCOMPP\t", 76405b261ecSmrg "FSUBRP\t", "FSUBP\t", "FDIVRP\t", "FDIVP\t", 76505b261ecSmrg}; 76605b261ecSmrg 76735c4bbdfSmrg#endif /* DEBUG */ 76805b261ecSmrg 76905b261ecSmrg/* opcode=0xde */ 77035c4bbdfSmrgvoid 77135c4bbdfSmrgx86emuOp_esc_coprocess_de(u8 X86EMU_UNUSED(op1)) 77205b261ecSmrg{ 77305b261ecSmrg int mod, rl, rh; 77405b261ecSmrg uint destoffset = 0; 77505b261ecSmrg u8 stkelem = 0; 77605b261ecSmrg 77705b261ecSmrg START_OF_INSTR(); 77805b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 77905b261ecSmrg DECODE_PRINTINSTR32(x86emu_fpu_op_de_tab, mod, rh, rl); 78005b261ecSmrg switch (mod) { 78135c4bbdfSmrg case 0: 78205b261ecSmrg destoffset = decode_rm00_address(rl); 78305b261ecSmrg DECODE_PRINTF("\n"); 78405b261ecSmrg break; 78535c4bbdfSmrg case 1: 78605b261ecSmrg destoffset = decode_rm01_address(rl); 78705b261ecSmrg DECODE_PRINTF("\n"); 78805b261ecSmrg break; 78935c4bbdfSmrg case 2: 79005b261ecSmrg destoffset = decode_rm10_address(rl); 79105b261ecSmrg DECODE_PRINTF("\n"); 79205b261ecSmrg break; 79335c4bbdfSmrg case 3: /* register to register */ 79435c4bbdfSmrg stkelem = (u8) rl; 79505b261ecSmrg DECODE_PRINTF2("\tST(%d),ST\n", stkelem); 79605b261ecSmrg break; 79705b261ecSmrg } 79805b261ecSmrg#ifdef X86EMU_FPU_PRESENT 79905b261ecSmrg switch (mod) { 80035c4bbdfSmrg case 3: 80105b261ecSmrg switch (rh) { 80235c4bbdfSmrg case 0: 80305b261ecSmrg x86emu_fpu_R_faddp(stkelem, X86EMU_FPU_STKTOP); 80405b261ecSmrg break; 80535c4bbdfSmrg case 1: 80605b261ecSmrg x86emu_fpu_R_fmulp(stkelem, X86EMU_FPU_STKTOP); 80705b261ecSmrg break; 80835c4bbdfSmrg case 2: 80905b261ecSmrg x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP); 81005b261ecSmrg break; 81135c4bbdfSmrg case 3: 81205b261ecSmrg if (stkelem == 1) 81335c4bbdfSmrg x86emu_fpu_R_fcompp(stkelem, X86EMU_FPU_STKTOP); 81405b261ecSmrg else 81535c4bbdfSmrg x86emu_fpu_illegal(); 81605b261ecSmrg break; 81735c4bbdfSmrg case 4: 81805b261ecSmrg x86emu_fpu_R_fsubrp(stkelem, X86EMU_FPU_STKTOP); 81905b261ecSmrg break; 82035c4bbdfSmrg case 5: 82105b261ecSmrg x86emu_fpu_R_fsubp(stkelem, X86EMU_FPU_STKTOP); 82205b261ecSmrg break; 82335c4bbdfSmrg case 6: 82405b261ecSmrg x86emu_fpu_R_fdivrp(stkelem, X86EMU_FPU_STKTOP); 82505b261ecSmrg break; 82635c4bbdfSmrg case 7: 82705b261ecSmrg x86emu_fpu_R_fdivp(stkelem, X86EMU_FPU_STKTOP); 82805b261ecSmrg break; 82905b261ecSmrg } 83005b261ecSmrg break; 83135c4bbdfSmrg default: 83205b261ecSmrg switch (rh) { 83335c4bbdfSmrg case 0: 83405b261ecSmrg x86emu_fpu_M_fiadd(X86EMU_FPU_WORD, destoffset); 83505b261ecSmrg break; 83635c4bbdfSmrg case 1: 83705b261ecSmrg x86emu_fpu_M_fimul(X86EMU_FPU_WORD, destoffset); 83805b261ecSmrg break; 83935c4bbdfSmrg case 2: 84005b261ecSmrg x86emu_fpu_M_ficom(X86EMU_FPU_WORD, destoffset); 84105b261ecSmrg break; 84235c4bbdfSmrg case 3: 84305b261ecSmrg x86emu_fpu_M_ficomp(X86EMU_FPU_WORD, destoffset); 84405b261ecSmrg break; 84535c4bbdfSmrg case 4: 84605b261ecSmrg x86emu_fpu_M_fisub(X86EMU_FPU_WORD, destoffset); 84705b261ecSmrg break; 84835c4bbdfSmrg case 5: 84905b261ecSmrg x86emu_fpu_M_fisubr(X86EMU_FPU_WORD, destoffset); 85005b261ecSmrg break; 85135c4bbdfSmrg case 6: 85205b261ecSmrg x86emu_fpu_M_fidiv(X86EMU_FPU_WORD, destoffset); 85305b261ecSmrg break; 85435c4bbdfSmrg case 7: 85505b261ecSmrg x86emu_fpu_M_fidivr(X86EMU_FPU_WORD, destoffset); 85605b261ecSmrg break; 85705b261ecSmrg } 85805b261ecSmrg } 85905b261ecSmrg#else 86035c4bbdfSmrg (void) destoffset; 86135c4bbdfSmrg (void) stkelem; 86205b261ecSmrg#endif 86305b261ecSmrg DECODE_CLEAR_SEGOVR(); 86405b261ecSmrg END_OF_INSTR_NO_TRACE(); 86505b261ecSmrg} 86605b261ecSmrg 86705b261ecSmrg#ifdef DEBUG 86805b261ecSmrg 86935c4bbdfSmrgstatic const char *x86emu_fpu_op_df_tab[] = { 87005b261ecSmrg /* mod == 00 */ 87105b261ecSmrg "FILD\tWORD PTR ", "ESC_DF\t39\n", "FIST\tWORD PTR ", "FISTP\tWORD PTR ", 87205b261ecSmrg "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ", 87305b261ecSmrg "FISTP\tQWORD PTR ", 87405b261ecSmrg 87505b261ecSmrg /* mod == 01 */ 87605b261ecSmrg "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ", 87705b261ecSmrg "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ", 87805b261ecSmrg "FISTP\tQWORD PTR ", 87905b261ecSmrg 88005b261ecSmrg /* mod == 10 */ 88105b261ecSmrg "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ", 88205b261ecSmrg "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ", 88305b261ecSmrg "FISTP\tQWORD PTR ", 88405b261ecSmrg 88505b261ecSmrg /* mod == 11 */ 88605b261ecSmrg "FFREE\t", "FXCH\t", "FST\t", "FSTP\t", 88705b261ecSmrg "ESC_DF\t3C,", "ESC_DF\t3D,", "ESC_DF\t3E,", "ESC_DF\t3F," 88805b261ecSmrg}; 88905b261ecSmrg 89035c4bbdfSmrg#endif /* DEBUG */ 89105b261ecSmrg 89205b261ecSmrg/* opcode=0xdf */ 89335c4bbdfSmrgvoid 89435c4bbdfSmrgx86emuOp_esc_coprocess_df(u8 X86EMU_UNUSED(op1)) 89505b261ecSmrg{ 89605b261ecSmrg int mod, rl, rh; 89705b261ecSmrg uint destoffset = 0; 89805b261ecSmrg u8 stkelem = 0; 89905b261ecSmrg 90005b261ecSmrg START_OF_INSTR(); 90105b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 90205b261ecSmrg DECODE_PRINTINSTR32(x86emu_fpu_op_df_tab, mod, rh, rl); 90305b261ecSmrg switch (mod) { 90435c4bbdfSmrg case 0: 90505b261ecSmrg destoffset = decode_rm00_address(rl); 90605b261ecSmrg DECODE_PRINTF("\n"); 90705b261ecSmrg break; 90835c4bbdfSmrg case 1: 90905b261ecSmrg destoffset = decode_rm01_address(rl); 91005b261ecSmrg DECODE_PRINTF("\n"); 91105b261ecSmrg break; 91235c4bbdfSmrg case 2: 91305b261ecSmrg destoffset = decode_rm10_address(rl); 91405b261ecSmrg DECODE_PRINTF("\n"); 91505b261ecSmrg break; 91635c4bbdfSmrg case 3: /* register to register */ 91735c4bbdfSmrg stkelem = (u8) rl; 91805b261ecSmrg DECODE_PRINTF2("\tST(%d)\n", stkelem); 91905b261ecSmrg break; 92005b261ecSmrg } 92105b261ecSmrg#ifdef X86EMU_FPU_PRESENT 92205b261ecSmrg switch (mod) { 92335c4bbdfSmrg case 3: 92405b261ecSmrg switch (rh) { 92535c4bbdfSmrg case 0: 92605b261ecSmrg x86emu_fpu_R_ffree(stkelem); 92705b261ecSmrg break; 92835c4bbdfSmrg case 1: 92905b261ecSmrg x86emu_fpu_R_fxch(stkelem); 93005b261ecSmrg break; 93135c4bbdfSmrg case 2: 93205b261ecSmrg x86emu_fpu_R_fst(stkelem); /* register version */ 93305b261ecSmrg break; 93435c4bbdfSmrg case 3: 93505b261ecSmrg x86emu_fpu_R_fstp(stkelem); /* register version */ 93605b261ecSmrg break; 93735c4bbdfSmrg default: 93805b261ecSmrg x86emu_fpu_illegal(); 93905b261ecSmrg break; 94005b261ecSmrg } 94105b261ecSmrg break; 94235c4bbdfSmrg default: 94305b261ecSmrg switch (rh) { 94435c4bbdfSmrg case 0: 94505b261ecSmrg x86emu_fpu_M_fild(X86EMU_FPU_WORD, destoffset); 94605b261ecSmrg break; 94735c4bbdfSmrg case 1: 94805b261ecSmrg x86emu_fpu_illegal(); 94905b261ecSmrg break; 95035c4bbdfSmrg case 2: 95105b261ecSmrg x86emu_fpu_M_fist(X86EMU_FPU_WORD, destoffset); 95205b261ecSmrg break; 95335c4bbdfSmrg case 3: 95405b261ecSmrg x86emu_fpu_M_fistp(X86EMU_FPU_WORD, destoffset); 95505b261ecSmrg break; 95635c4bbdfSmrg case 4: 95705b261ecSmrg x86emu_fpu_M_fbld(X86EMU_FPU_BSD, destoffset); 95805b261ecSmrg break; 95935c4bbdfSmrg case 5: 96005b261ecSmrg x86emu_fpu_M_fild(X86EMU_FPU_LONG, destoffset); 96105b261ecSmrg break; 96235c4bbdfSmrg case 6: 96305b261ecSmrg x86emu_fpu_M_fbstp(X86EMU_FPU_BSD, destoffset); 96405b261ecSmrg break; 96535c4bbdfSmrg case 7: 96605b261ecSmrg x86emu_fpu_M_fistp(X86EMU_FPU_LONG, destoffset); 96705b261ecSmrg break; 96805b261ecSmrg } 96905b261ecSmrg } 97005b261ecSmrg#else 97135c4bbdfSmrg (void) destoffset; 97235c4bbdfSmrg (void) stkelem; 97305b261ecSmrg#endif 97405b261ecSmrg DECODE_CLEAR_SEGOVR(); 97505b261ecSmrg END_OF_INSTR_NO_TRACE(); 97605b261ecSmrg} 977