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