1ece92f85SJason Jin /**************************************************************************** 2ece92f85SJason Jin * Realmode X86 Emulator Library 3ece92f85SJason Jin * 4*4c2e3da8SKumar Gala * Copyright (C) 2007 Freescale Semiconductor, Inc. 5ece92f85SJason Jin * Jason Jin <Jason.jin@freescale.com> 6ece92f85SJason Jin * 7ece92f85SJason Jin * Copyright (C) 1991-2004 SciTech Software, Inc. 8ece92f85SJason Jin * Copyright (C) David Mosberger-Tang 9ece92f85SJason Jin * Copyright (C) 1999 Egbert Eich 10ece92f85SJason Jin * 11ece92f85SJason Jin * ======================================================================== 12ece92f85SJason Jin * 13ece92f85SJason Jin * Permission to use, copy, modify, distribute, and sell this software and 14ece92f85SJason Jin * its documentation for any purpose is hereby granted without fee, 15ece92f85SJason Jin * provided that the above copyright notice appear in all copies and that 16ece92f85SJason Jin * both that copyright notice and this permission notice appear in 17ece92f85SJason Jin * supporting documentation, and that the name of the authors not be used 18ece92f85SJason Jin * in advertising or publicity pertaining to distribution of the software 19ece92f85SJason Jin * without specific, written prior permission. The authors makes no 20ece92f85SJason Jin * representations about the suitability of this software for any purpose. 21ece92f85SJason Jin * It is provided "as is" without express or implied warranty. 22ece92f85SJason Jin * 23ece92f85SJason Jin * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 24ece92f85SJason Jin * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 25ece92f85SJason Jin * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 26ece92f85SJason Jin * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 27ece92f85SJason Jin * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 28ece92f85SJason Jin * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 29ece92f85SJason Jin * PERFORMANCE OF THIS SOFTWARE. 30ece92f85SJason Jin * 31ece92f85SJason Jin * ======================================================================== 32ece92f85SJason Jin * 33ece92f85SJason Jin * Language: ANSI C 34ece92f85SJason Jin * Environment: Any 35ece92f85SJason Jin * Developer: Kendall Bennett 36ece92f85SJason Jin * 37ece92f85SJason Jin * Description: This file includes subroutines to implement the decoding 38ece92f85SJason Jin * and emulation of all the x86 processor instructions. 39ece92f85SJason Jin * 40ece92f85SJason Jin * There are approximately 250 subroutines in here, which correspond 41ece92f85SJason Jin * to the 256 byte-"opcodes" found on the 8086. The table which 42ece92f85SJason Jin * dispatches this is found in the files optab.[ch]. 43ece92f85SJason Jin * 44ece92f85SJason Jin * Each opcode proc has a comment preceeding it which gives it's table 45ece92f85SJason Jin * address. Several opcodes are missing (undefined) in the table. 46ece92f85SJason Jin * 47ece92f85SJason Jin * Each proc includes information for decoding (DECODE_PRINTF and 48ece92f85SJason Jin * DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc 49ece92f85SJason Jin * functions (START_OF_INSTR, END_OF_INSTR). 50ece92f85SJason Jin * 51ece92f85SJason Jin * Many of the procedures are *VERY* similar in coding. This has 52ece92f85SJason Jin * allowed for a very large amount of code to be generated in a fairly 53ece92f85SJason Jin * short amount of time (i.e. cut, paste, and modify). The result is 54ece92f85SJason Jin * that much of the code below could have been folded into subroutines 55ece92f85SJason Jin * for a large reduction in size of this file. The downside would be 56ece92f85SJason Jin * that there would be a penalty in execution speed. The file could 57ece92f85SJason Jin * also have been *MUCH* larger by inlining certain functions which 58ece92f85SJason Jin * were called. This could have resulted even faster execution. The 59ece92f85SJason Jin * prime directive I used to decide whether to inline the code or to 60ece92f85SJason Jin * modularize it, was basically: 1) no unnecessary subroutine calls, 61ece92f85SJason Jin * 2) no routines more than about 200 lines in size, and 3) modularize 62ece92f85SJason Jin * any code that I might not get right the first time. The fetch_* 63ece92f85SJason Jin * subroutines fall into the latter category. The The decode_* fall 64ece92f85SJason Jin * into the second category. The coding of the "switch(mod){ .... }" 65ece92f85SJason Jin * in many of the subroutines below falls into the first category. 66ece92f85SJason Jin * Especially, the coding of {add,and,or,sub,...}_{byte,word} 67ece92f85SJason Jin * subroutines are an especially glaring case of the third guideline. 68ece92f85SJason Jin * Since so much of the code is cloned from other modules (compare 69ece92f85SJason Jin * opcode #00 to opcode #01), making the basic operations subroutine 70ece92f85SJason Jin * calls is especially important; otherwise mistakes in coding an 71ece92f85SJason Jin * "add" would represent a nightmare in maintenance. 72ece92f85SJason Jin * 73ece92f85SJason Jin * Jason ported this file to u-boot. place all the function pointer in 74ece92f85SJason Jin * the got2 sector. Removed some opcode. 75ece92f85SJason Jin * 76ece92f85SJason Jin ****************************************************************************/ 77ece92f85SJason Jin 7878cff50eSMichal Simek #include <common.h> 795b4de930SMichal Simek #include "x86emu/x86emui.h" 805b4de930SMichal Simek 81ece92f85SJason Jin /*----------------------------- Implementation ----------------------------*/ 82ece92f85SJason Jin 83ece92f85SJason Jin /* constant arrays to do several instructions in just one function */ 84ece92f85SJason Jin 85ece92f85SJason Jin #ifdef DEBUG 86ece92f85SJason Jin static char *x86emu_GenOpName[8] = { 87ece92f85SJason Jin "ADD", "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP"}; 88ece92f85SJason Jin #endif 89ece92f85SJason Jin 90ece92f85SJason Jin /* used by several opcodes */ 9130c6a241SAnatolij Gustschin static u8 (*genop_byte_operation[])(u8 d, u8 s) __attribute__ ((section(GOT2_TYPE))) = 92ece92f85SJason Jin { 93ece92f85SJason Jin add_byte, /* 00 */ 94ece92f85SJason Jin or_byte, /* 01 */ 95ece92f85SJason Jin adc_byte, /* 02 */ 96ece92f85SJason Jin sbb_byte, /* 03 */ 97ece92f85SJason Jin and_byte, /* 04 */ 98ece92f85SJason Jin sub_byte, /* 05 */ 99ece92f85SJason Jin xor_byte, /* 06 */ 100ece92f85SJason Jin cmp_byte, /* 07 */ 101ece92f85SJason Jin }; 102ece92f85SJason Jin 10330c6a241SAnatolij Gustschin static u16 (*genop_word_operation[])(u16 d, u16 s) __attribute__ ((section(GOT2_TYPE))) = 104ece92f85SJason Jin { 105ece92f85SJason Jin add_word, /*00 */ 106ece92f85SJason Jin or_word, /*01 */ 107ece92f85SJason Jin adc_word, /*02 */ 108ece92f85SJason Jin sbb_word, /*03 */ 109ece92f85SJason Jin and_word, /*04 */ 110ece92f85SJason Jin sub_word, /*05 */ 111ece92f85SJason Jin xor_word, /*06 */ 112ece92f85SJason Jin cmp_word, /*07 */ 113ece92f85SJason Jin }; 114ece92f85SJason Jin 11530c6a241SAnatolij Gustschin static u32 (*genop_long_operation[])(u32 d, u32 s) __attribute__ ((section(GOT2_TYPE))) = 116ece92f85SJason Jin { 117ece92f85SJason Jin add_long, /*00 */ 118ece92f85SJason Jin or_long, /*01 */ 119ece92f85SJason Jin adc_long, /*02 */ 120ece92f85SJason Jin sbb_long, /*03 */ 121ece92f85SJason Jin and_long, /*04 */ 122ece92f85SJason Jin sub_long, /*05 */ 123ece92f85SJason Jin xor_long, /*06 */ 124ece92f85SJason Jin cmp_long, /*07 */ 125ece92f85SJason Jin }; 126ece92f85SJason Jin 127ece92f85SJason Jin /* used by opcodes 80, c0, d0, and d2. */ 12830c6a241SAnatolij Gustschin static u8(*opcD0_byte_operation[])(u8 d, u8 s) __attribute__ ((section(GOT2_TYPE))) = 129ece92f85SJason Jin { 130ece92f85SJason Jin rol_byte, 131ece92f85SJason Jin ror_byte, 132ece92f85SJason Jin rcl_byte, 133ece92f85SJason Jin rcr_byte, 134ece92f85SJason Jin shl_byte, 135ece92f85SJason Jin shr_byte, 136ece92f85SJason Jin shl_byte, /* sal_byte === shl_byte by definition */ 137ece92f85SJason Jin sar_byte, 138ece92f85SJason Jin }; 139ece92f85SJason Jin 140ece92f85SJason Jin /* used by opcodes c1, d1, and d3. */ 14130c6a241SAnatolij Gustschin static u16(*opcD1_word_operation[])(u16 s, u8 d) __attribute__ ((section(GOT2_TYPE))) = 142ece92f85SJason Jin { 143ece92f85SJason Jin rol_word, 144ece92f85SJason Jin ror_word, 145ece92f85SJason Jin rcl_word, 146ece92f85SJason Jin rcr_word, 147ece92f85SJason Jin shl_word, 148ece92f85SJason Jin shr_word, 149ece92f85SJason Jin shl_word, /* sal_byte === shl_byte by definition */ 150ece92f85SJason Jin sar_word, 151ece92f85SJason Jin }; 152ece92f85SJason Jin 153ece92f85SJason Jin /* used by opcodes c1, d1, and d3. */ 15430c6a241SAnatolij Gustschin static u32 (*opcD1_long_operation[])(u32 s, u8 d) __attribute__ ((section(GOT2_TYPE))) = 155ece92f85SJason Jin { 156ece92f85SJason Jin rol_long, 157ece92f85SJason Jin ror_long, 158ece92f85SJason Jin rcl_long, 159ece92f85SJason Jin rcr_long, 160ece92f85SJason Jin shl_long, 161ece92f85SJason Jin shr_long, 162ece92f85SJason Jin shl_long, /* sal_byte === shl_byte by definition */ 163ece92f85SJason Jin sar_long, 164ece92f85SJason Jin }; 165ece92f85SJason Jin 166ece92f85SJason Jin #ifdef DEBUG 167ece92f85SJason Jin 168ece92f85SJason Jin static char *opF6_names[8] = 169ece92f85SJason Jin { "TEST\t", "", "NOT\t", "NEG\t", "MUL\t", "IMUL\t", "DIV\t", "IDIV\t" }; 170ece92f85SJason Jin 171ece92f85SJason Jin #endif 172ece92f85SJason Jin 173ece92f85SJason Jin /**************************************************************************** 174ece92f85SJason Jin PARAMETERS: 175ece92f85SJason Jin op1 - Instruction op code 176ece92f85SJason Jin 177ece92f85SJason Jin REMARKS: 178ece92f85SJason Jin Handles illegal opcodes. 179ece92f85SJason Jin ****************************************************************************/ 180ece92f85SJason Jin void x86emuOp_illegal_op( 181ece92f85SJason Jin u8 op1) 182ece92f85SJason Jin { 183ece92f85SJason Jin START_OF_INSTR(); 184ece92f85SJason Jin if (M.x86.R_SP != 0) { 185ece92f85SJason Jin DECODE_PRINTF("ILLEGAL X86 OPCODE\n"); 186ece92f85SJason Jin TRACE_REGS(); 187ece92f85SJason Jin DB( printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n", 188ece92f85SJason Jin M.x86.R_CS, M.x86.R_IP-1,op1)); 189ece92f85SJason Jin HALT_SYS(); 190ece92f85SJason Jin } 191ece92f85SJason Jin else { 192ece92f85SJason Jin /* If we get here, it means the stack pointer is back to zero 193ece92f85SJason Jin * so we are just returning from an emulator service call 194ece92f85SJason Jin * so therte is no need to display an error message. We trap 195ece92f85SJason Jin * the emulator with an 0xF1 opcode to finish the service 196ece92f85SJason Jin * call. 197ece92f85SJason Jin */ 198ece92f85SJason Jin X86EMU_halt_sys(); 199ece92f85SJason Jin } 200ece92f85SJason Jin END_OF_INSTR(); 201ece92f85SJason Jin } 202ece92f85SJason Jin 203ece92f85SJason Jin /**************************************************************************** 204ece92f85SJason Jin REMARKS: 205ece92f85SJason Jin Handles opcodes 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38 206ece92f85SJason Jin ****************************************************************************/ 207ece92f85SJason Jin void x86emuOp_genop_byte_RM_R(u8 op1) 208ece92f85SJason Jin { 209ece92f85SJason Jin int mod, rl, rh; 210ece92f85SJason Jin uint destoffset; 211ece92f85SJason Jin u8 *destreg, *srcreg; 212ece92f85SJason Jin u8 destval; 213ece92f85SJason Jin 214ece92f85SJason Jin op1 = (op1 >> 3) & 0x7; 215ece92f85SJason Jin 216ece92f85SJason Jin START_OF_INSTR(); 217ece92f85SJason Jin DECODE_PRINTF(x86emu_GenOpName[op1]); 218ece92f85SJason Jin DECODE_PRINTF("\t"); 219ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 220ece92f85SJason Jin if(mod<3) 221ece92f85SJason Jin { destoffset = decode_rmXX_address(mod,rl); 222ece92f85SJason Jin DECODE_PRINTF(","); 223ece92f85SJason Jin destval = fetch_data_byte(destoffset); 224ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rh); 225ece92f85SJason Jin DECODE_PRINTF("\n"); 226ece92f85SJason Jin TRACE_AND_STEP(); 227ece92f85SJason Jin destval = genop_byte_operation[op1](destval, *srcreg); 228ece92f85SJason Jin store_data_byte(destoffset, destval); 229ece92f85SJason Jin } 230ece92f85SJason Jin else 231ece92f85SJason Jin { /* register to register */ 232ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl); 233ece92f85SJason Jin DECODE_PRINTF(","); 234ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rh); 235ece92f85SJason Jin DECODE_PRINTF("\n"); 236ece92f85SJason Jin TRACE_AND_STEP(); 237ece92f85SJason Jin *destreg = genop_byte_operation[op1](*destreg, *srcreg); 238ece92f85SJason Jin } 239ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 240ece92f85SJason Jin END_OF_INSTR(); 241ece92f85SJason Jin } 242ece92f85SJason Jin 243ece92f85SJason Jin /**************************************************************************** 244ece92f85SJason Jin REMARKS: 245ece92f85SJason Jin Handles opcodes 0x01, 0x09, 0x11, 0x19, 0x21, 0x29, 0x31, 0x39 246ece92f85SJason Jin ****************************************************************************/ 247ece92f85SJason Jin void x86emuOp_genop_word_RM_R(u8 op1) 248ece92f85SJason Jin { 249ece92f85SJason Jin int mod, rl, rh; 250ece92f85SJason Jin uint destoffset; 251ece92f85SJason Jin 252ece92f85SJason Jin op1 = (op1 >> 3) & 0x7; 253ece92f85SJason Jin 254ece92f85SJason Jin START_OF_INSTR(); 255ece92f85SJason Jin DECODE_PRINTF(x86emu_GenOpName[op1]); 256ece92f85SJason Jin DECODE_PRINTF("\t"); 257ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 258ece92f85SJason Jin 259ece92f85SJason Jin if(mod<3) { 260ece92f85SJason Jin destoffset = decode_rmXX_address(mod,rl); 261ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 262ece92f85SJason Jin u32 destval; 263ece92f85SJason Jin u32 *srcreg; 264ece92f85SJason Jin 265ece92f85SJason Jin DECODE_PRINTF(","); 266ece92f85SJason Jin destval = fetch_data_long(destoffset); 267ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rh); 268ece92f85SJason Jin DECODE_PRINTF("\n"); 269ece92f85SJason Jin TRACE_AND_STEP(); 270ece92f85SJason Jin destval = genop_long_operation[op1](destval, *srcreg); 271ece92f85SJason Jin store_data_long(destoffset, destval); 272ece92f85SJason Jin } else { 273ece92f85SJason Jin u16 destval; 274ece92f85SJason Jin u16 *srcreg; 275ece92f85SJason Jin 276ece92f85SJason Jin DECODE_PRINTF(","); 277ece92f85SJason Jin destval = fetch_data_word(destoffset); 278ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh); 279ece92f85SJason Jin DECODE_PRINTF("\n"); 280ece92f85SJason Jin TRACE_AND_STEP(); 281ece92f85SJason Jin destval = genop_word_operation[op1](destval, *srcreg); 282ece92f85SJason Jin store_data_word(destoffset, destval); 283ece92f85SJason Jin } 284ece92f85SJason Jin } else { /* register to register */ 285ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 286ece92f85SJason Jin u32 *destreg,*srcreg; 287ece92f85SJason Jin 288ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 289ece92f85SJason Jin DECODE_PRINTF(","); 290ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rh); 291ece92f85SJason Jin DECODE_PRINTF("\n"); 292ece92f85SJason Jin TRACE_AND_STEP(); 293ece92f85SJason Jin *destreg = genop_long_operation[op1](*destreg, *srcreg); 294ece92f85SJason Jin } else { 295ece92f85SJason Jin u16 *destreg,*srcreg; 296ece92f85SJason Jin 297ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 298ece92f85SJason Jin DECODE_PRINTF(","); 299ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh); 300ece92f85SJason Jin DECODE_PRINTF("\n"); 301ece92f85SJason Jin TRACE_AND_STEP(); 302ece92f85SJason Jin *destreg = genop_word_operation[op1](*destreg, *srcreg); 303ece92f85SJason Jin } 304ece92f85SJason Jin } 305ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 306ece92f85SJason Jin END_OF_INSTR(); 307ece92f85SJason Jin } 308ece92f85SJason Jin 309ece92f85SJason Jin /**************************************************************************** 310ece92f85SJason Jin REMARKS: 311ece92f85SJason Jin Handles opcodes 0x02, 0x0a, 0x12, 0x1a, 0x22, 0x2a, 0x32, 0x3a 312ece92f85SJason Jin ****************************************************************************/ 313ece92f85SJason Jin void x86emuOp_genop_byte_R_RM(u8 op1) 314ece92f85SJason Jin { 315ece92f85SJason Jin int mod, rl, rh; 316ece92f85SJason Jin u8 *destreg, *srcreg; 317ece92f85SJason Jin uint srcoffset; 318ece92f85SJason Jin u8 srcval; 319ece92f85SJason Jin 320ece92f85SJason Jin op1 = (op1 >> 3) & 0x7; 321ece92f85SJason Jin 322ece92f85SJason Jin START_OF_INSTR(); 323ece92f85SJason Jin DECODE_PRINTF(x86emu_GenOpName[op1]); 324ece92f85SJason Jin DECODE_PRINTF("\t"); 325ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 326ece92f85SJason Jin if (mod < 3) { 327ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rh); 328ece92f85SJason Jin DECODE_PRINTF(","); 329ece92f85SJason Jin srcoffset = decode_rmXX_address(mod,rl); 330ece92f85SJason Jin srcval = fetch_data_byte(srcoffset); 331ece92f85SJason Jin } else { /* register to register */ 332ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rh); 333ece92f85SJason Jin DECODE_PRINTF(","); 334ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rl); 335ece92f85SJason Jin srcval = *srcreg; 336ece92f85SJason Jin } 337ece92f85SJason Jin DECODE_PRINTF("\n"); 338ece92f85SJason Jin TRACE_AND_STEP(); 339ece92f85SJason Jin *destreg = genop_byte_operation[op1](*destreg, srcval); 340ece92f85SJason Jin 341ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 342ece92f85SJason Jin END_OF_INSTR(); 343ece92f85SJason Jin } 344ece92f85SJason Jin 345ece92f85SJason Jin /**************************************************************************** 346ece92f85SJason Jin REMARKS: 347ece92f85SJason Jin Handles opcodes 0x03, 0x0b, 0x13, 0x1b, 0x23, 0x2b, 0x33, 0x3b 348ece92f85SJason Jin ****************************************************************************/ 349ece92f85SJason Jin void x86emuOp_genop_word_R_RM(u8 op1) 350ece92f85SJason Jin { 351ece92f85SJason Jin int mod, rl, rh; 352ece92f85SJason Jin uint srcoffset; 353ece92f85SJason Jin u32 *destreg32, srcval; 354ece92f85SJason Jin u16 *destreg; 355ece92f85SJason Jin 356ece92f85SJason Jin op1 = (op1 >> 3) & 0x7; 357ece92f85SJason Jin 358ece92f85SJason Jin START_OF_INSTR(); 359ece92f85SJason Jin DECODE_PRINTF(x86emu_GenOpName[op1]); 360ece92f85SJason Jin DECODE_PRINTF("\t"); 361ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 362ece92f85SJason Jin if (mod < 3) { 363ece92f85SJason Jin srcoffset = decode_rmXX_address(mod,rl); 364ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 365ece92f85SJason Jin destreg32 = DECODE_RM_LONG_REGISTER(rh); 366ece92f85SJason Jin DECODE_PRINTF(","); 367ece92f85SJason Jin srcval = fetch_data_long(srcoffset); 368ece92f85SJason Jin DECODE_PRINTF("\n"); 369ece92f85SJason Jin TRACE_AND_STEP(); 370ece92f85SJason Jin *destreg32 = genop_long_operation[op1](*destreg32, srcval); 371ece92f85SJason Jin } else { 372ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh); 373ece92f85SJason Jin DECODE_PRINTF(","); 374ece92f85SJason Jin srcval = fetch_data_word(srcoffset); 375ece92f85SJason Jin DECODE_PRINTF("\n"); 376ece92f85SJason Jin TRACE_AND_STEP(); 377ece92f85SJason Jin *destreg = genop_word_operation[op1](*destreg, srcval); 378ece92f85SJason Jin } 379ece92f85SJason Jin } else { /* register to register */ 380ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 381ece92f85SJason Jin u32 *srcreg; 382ece92f85SJason Jin destreg32 = DECODE_RM_LONG_REGISTER(rh); 383ece92f85SJason Jin DECODE_PRINTF(","); 384ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl); 385ece92f85SJason Jin DECODE_PRINTF("\n"); 386ece92f85SJason Jin TRACE_AND_STEP(); 387ece92f85SJason Jin *destreg32 = genop_long_operation[op1](*destreg32, *srcreg); 388ece92f85SJason Jin } else { 389ece92f85SJason Jin u16 *srcreg; 390ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh); 391ece92f85SJason Jin DECODE_PRINTF(","); 392ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl); 393ece92f85SJason Jin DECODE_PRINTF("\n"); 394ece92f85SJason Jin TRACE_AND_STEP(); 395ece92f85SJason Jin *destreg = genop_word_operation[op1](*destreg, *srcreg); 396ece92f85SJason Jin } 397ece92f85SJason Jin } 398ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 399ece92f85SJason Jin END_OF_INSTR(); 400ece92f85SJason Jin } 401ece92f85SJason Jin 402ece92f85SJason Jin /**************************************************************************** 403ece92f85SJason Jin REMARKS: 404ece92f85SJason Jin Handles opcodes 0x04, 0x0c, 0x14, 0x1c, 0x24, 0x2c, 0x34, 0x3c 405ece92f85SJason Jin ****************************************************************************/ 406ece92f85SJason Jin void x86emuOp_genop_byte_AL_IMM(u8 op1) 407ece92f85SJason Jin { 408ece92f85SJason Jin u8 srcval; 409ece92f85SJason Jin 410ece92f85SJason Jin op1 = (op1 >> 3) & 0x7; 411ece92f85SJason Jin 412ece92f85SJason Jin START_OF_INSTR(); 413ece92f85SJason Jin DECODE_PRINTF(x86emu_GenOpName[op1]); 414ece92f85SJason Jin DECODE_PRINTF("\tAL,"); 415ece92f85SJason Jin srcval = fetch_byte_imm(); 416ece92f85SJason Jin DECODE_PRINTF2("%x\n", srcval); 417ece92f85SJason Jin TRACE_AND_STEP(); 418ece92f85SJason Jin M.x86.R_AL = genop_byte_operation[op1](M.x86.R_AL, srcval); 419ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 420ece92f85SJason Jin END_OF_INSTR(); 421ece92f85SJason Jin } 422ece92f85SJason Jin 423ece92f85SJason Jin /**************************************************************************** 424ece92f85SJason Jin REMARKS: 425ece92f85SJason Jin Handles opcodes 0x05, 0x0d, 0x15, 0x1d, 0x25, 0x2d, 0x35, 0x3d 426ece92f85SJason Jin ****************************************************************************/ 427ece92f85SJason Jin void x86emuOp_genop_word_AX_IMM(u8 op1) 428ece92f85SJason Jin { 429ece92f85SJason Jin u32 srcval; 430ece92f85SJason Jin 431ece92f85SJason Jin op1 = (op1 >> 3) & 0x7; 432ece92f85SJason Jin 433ece92f85SJason Jin START_OF_INSTR(); 434ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 435ece92f85SJason Jin DECODE_PRINTF(x86emu_GenOpName[op1]); 436ece92f85SJason Jin DECODE_PRINTF("\tEAX,"); 437ece92f85SJason Jin srcval = fetch_long_imm(); 438ece92f85SJason Jin } else { 439ece92f85SJason Jin DECODE_PRINTF(x86emu_GenOpName[op1]); 440ece92f85SJason Jin DECODE_PRINTF("\tAX,"); 441ece92f85SJason Jin srcval = fetch_word_imm(); 442ece92f85SJason Jin } 443ece92f85SJason Jin DECODE_PRINTF2("%x\n", srcval); 444ece92f85SJason Jin TRACE_AND_STEP(); 445ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 446ece92f85SJason Jin M.x86.R_EAX = genop_long_operation[op1](M.x86.R_EAX, srcval); 447ece92f85SJason Jin } else { 448ece92f85SJason Jin M.x86.R_AX = genop_word_operation[op1](M.x86.R_AX, (u16)srcval); 449ece92f85SJason Jin } 450ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 451ece92f85SJason Jin END_OF_INSTR(); 452ece92f85SJason Jin } 453ece92f85SJason Jin 454ece92f85SJason Jin /**************************************************************************** 455ece92f85SJason Jin REMARKS: 456ece92f85SJason Jin Handles opcode 0x06 457ece92f85SJason Jin ****************************************************************************/ 458ece92f85SJason Jin void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1)) 459ece92f85SJason Jin { 460ece92f85SJason Jin START_OF_INSTR(); 461ece92f85SJason Jin DECODE_PRINTF("PUSH\tES\n"); 462ece92f85SJason Jin TRACE_AND_STEP(); 463ece92f85SJason Jin push_word(M.x86.R_ES); 464ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 465ece92f85SJason Jin END_OF_INSTR(); 466ece92f85SJason Jin } 467ece92f85SJason Jin 468ece92f85SJason Jin /**************************************************************************** 469ece92f85SJason Jin REMARKS: 470ece92f85SJason Jin Handles opcode 0x07 471ece92f85SJason Jin ****************************************************************************/ 472ece92f85SJason Jin void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1)) 473ece92f85SJason Jin { 474ece92f85SJason Jin START_OF_INSTR(); 475ece92f85SJason Jin DECODE_PRINTF("POP\tES\n"); 476ece92f85SJason Jin TRACE_AND_STEP(); 477ece92f85SJason Jin M.x86.R_ES = pop_word(); 478ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 479ece92f85SJason Jin END_OF_INSTR(); 480ece92f85SJason Jin } 481ece92f85SJason Jin 482ece92f85SJason Jin /**************************************************************************** 483ece92f85SJason Jin REMARKS: 484ece92f85SJason Jin Handles opcode 0x0e 485ece92f85SJason Jin ****************************************************************************/ 486ece92f85SJason Jin void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1)) 487ece92f85SJason Jin { 488ece92f85SJason Jin START_OF_INSTR(); 489ece92f85SJason Jin DECODE_PRINTF("PUSH\tCS\n"); 490ece92f85SJason Jin TRACE_AND_STEP(); 491ece92f85SJason Jin push_word(M.x86.R_CS); 492ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 493ece92f85SJason Jin END_OF_INSTR(); 494ece92f85SJason Jin } 495ece92f85SJason Jin 496ece92f85SJason Jin /**************************************************************************** 497ece92f85SJason Jin REMARKS: 498ece92f85SJason Jin Handles opcode 0x0f. Escape for two-byte opcode (286 or better) 499ece92f85SJason Jin ****************************************************************************/ 500ece92f85SJason Jin void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1)) 501ece92f85SJason Jin { 502ece92f85SJason Jin u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++)); 503ece92f85SJason Jin INC_DECODED_INST_LEN(1); 504ece92f85SJason Jin (*x86emu_optab2[op2])(op2); 505ece92f85SJason Jin } 506ece92f85SJason Jin 507ece92f85SJason Jin /**************************************************************************** 508ece92f85SJason Jin REMARKS: 509ece92f85SJason Jin Handles opcode 0x16 510ece92f85SJason Jin ****************************************************************************/ 511ece92f85SJason Jin void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1)) 512ece92f85SJason Jin { 513ece92f85SJason Jin START_OF_INSTR(); 514ece92f85SJason Jin DECODE_PRINTF("PUSH\tSS\n"); 515ece92f85SJason Jin TRACE_AND_STEP(); 516ece92f85SJason Jin push_word(M.x86.R_SS); 517ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 518ece92f85SJason Jin END_OF_INSTR(); 519ece92f85SJason Jin } 520ece92f85SJason Jin 521ece92f85SJason Jin /**************************************************************************** 522ece92f85SJason Jin REMARKS: 523ece92f85SJason Jin Handles opcode 0x17 524ece92f85SJason Jin ****************************************************************************/ 525ece92f85SJason Jin void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1)) 526ece92f85SJason Jin { 527ece92f85SJason Jin START_OF_INSTR(); 528ece92f85SJason Jin DECODE_PRINTF("POP\tSS\n"); 529ece92f85SJason Jin TRACE_AND_STEP(); 530ece92f85SJason Jin M.x86.R_SS = pop_word(); 531ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 532ece92f85SJason Jin END_OF_INSTR(); 533ece92f85SJason Jin } 534ece92f85SJason Jin 535ece92f85SJason Jin /**************************************************************************** 536ece92f85SJason Jin REMARKS: 537ece92f85SJason Jin Handles opcode 0x1e 538ece92f85SJason Jin ****************************************************************************/ 539ece92f85SJason Jin void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1)) 540ece92f85SJason Jin { 541ece92f85SJason Jin START_OF_INSTR(); 542ece92f85SJason Jin DECODE_PRINTF("PUSH\tDS\n"); 543ece92f85SJason Jin TRACE_AND_STEP(); 544ece92f85SJason Jin push_word(M.x86.R_DS); 545ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 546ece92f85SJason Jin END_OF_INSTR(); 547ece92f85SJason Jin } 548ece92f85SJason Jin 549ece92f85SJason Jin /**************************************************************************** 550ece92f85SJason Jin REMARKS: 551ece92f85SJason Jin Handles opcode 0x1f 552ece92f85SJason Jin ****************************************************************************/ 553ece92f85SJason Jin void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1)) 554ece92f85SJason Jin { 555ece92f85SJason Jin START_OF_INSTR(); 556ece92f85SJason Jin DECODE_PRINTF("POP\tDS\n"); 557ece92f85SJason Jin TRACE_AND_STEP(); 558ece92f85SJason Jin M.x86.R_DS = pop_word(); 559ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 560ece92f85SJason Jin END_OF_INSTR(); 561ece92f85SJason Jin } 562ece92f85SJason Jin 563ece92f85SJason Jin /**************************************************************************** 564ece92f85SJason Jin REMARKS: 565ece92f85SJason Jin Handles opcode 0x26 566ece92f85SJason Jin ****************************************************************************/ 567ece92f85SJason Jin void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1)) 568ece92f85SJason Jin { 569ece92f85SJason Jin START_OF_INSTR(); 570ece92f85SJason Jin DECODE_PRINTF("ES:\n"); 571ece92f85SJason Jin TRACE_AND_STEP(); 572ece92f85SJason Jin M.x86.mode |= SYSMODE_SEGOVR_ES; 573ece92f85SJason Jin /* 574ece92f85SJason Jin * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 575ece92f85SJason Jin * opcode subroutines we do not want to do this. 576ece92f85SJason Jin */ 577ece92f85SJason Jin END_OF_INSTR(); 578ece92f85SJason Jin } 579ece92f85SJason Jin 580ece92f85SJason Jin /**************************************************************************** 581ece92f85SJason Jin REMARKS: 582ece92f85SJason Jin Handles opcode 0x27 583ece92f85SJason Jin ****************************************************************************/ 584ece92f85SJason Jin void x86emuOp_daa(u8 X86EMU_UNUSED(op1)) 585ece92f85SJason Jin { 586ece92f85SJason Jin START_OF_INSTR(); 587ece92f85SJason Jin DECODE_PRINTF("DAA\n"); 588ece92f85SJason Jin TRACE_AND_STEP(); 589ece92f85SJason Jin M.x86.R_AL = daa_byte(M.x86.R_AL); 590ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 591ece92f85SJason Jin END_OF_INSTR(); 592ece92f85SJason Jin } 593ece92f85SJason Jin 594ece92f85SJason Jin /**************************************************************************** 595ece92f85SJason Jin REMARKS: 596ece92f85SJason Jin Handles opcode 0x2e 597ece92f85SJason Jin ****************************************************************************/ 598ece92f85SJason Jin void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1)) 599ece92f85SJason Jin { 600ece92f85SJason Jin START_OF_INSTR(); 601ece92f85SJason Jin DECODE_PRINTF("CS:\n"); 602ece92f85SJason Jin TRACE_AND_STEP(); 603ece92f85SJason Jin M.x86.mode |= SYSMODE_SEGOVR_CS; 604ece92f85SJason Jin /* note no DECODE_CLEAR_SEGOVR here. */ 605ece92f85SJason Jin END_OF_INSTR(); 606ece92f85SJason Jin } 607ece92f85SJason Jin 608ece92f85SJason Jin /**************************************************************************** 609ece92f85SJason Jin REMARKS: 610ece92f85SJason Jin Handles opcode 0x2f 611ece92f85SJason Jin ****************************************************************************/ 612ece92f85SJason Jin void x86emuOp_das(u8 X86EMU_UNUSED(op1)) 613ece92f85SJason Jin { 614ece92f85SJason Jin START_OF_INSTR(); 615ece92f85SJason Jin DECODE_PRINTF("DAS\n"); 616ece92f85SJason Jin TRACE_AND_STEP(); 617ece92f85SJason Jin M.x86.R_AL = das_byte(M.x86.R_AL); 618ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 619ece92f85SJason Jin END_OF_INSTR(); 620ece92f85SJason Jin } 621ece92f85SJason Jin 622ece92f85SJason Jin /**************************************************************************** 623ece92f85SJason Jin REMARKS: 624ece92f85SJason Jin Handles opcode 0x36 625ece92f85SJason Jin ****************************************************************************/ 626ece92f85SJason Jin void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1)) 627ece92f85SJason Jin { 628ece92f85SJason Jin START_OF_INSTR(); 629ece92f85SJason Jin DECODE_PRINTF("SS:\n"); 630ece92f85SJason Jin TRACE_AND_STEP(); 631ece92f85SJason Jin M.x86.mode |= SYSMODE_SEGOVR_SS; 632ece92f85SJason Jin /* no DECODE_CLEAR_SEGOVR ! */ 633ece92f85SJason Jin END_OF_INSTR(); 634ece92f85SJason Jin } 635ece92f85SJason Jin 636ece92f85SJason Jin /**************************************************************************** 637ece92f85SJason Jin REMARKS: 638ece92f85SJason Jin Handles opcode 0x37 639ece92f85SJason Jin ****************************************************************************/ 640ece92f85SJason Jin void x86emuOp_aaa(u8 X86EMU_UNUSED(op1)) 641ece92f85SJason Jin { 642ece92f85SJason Jin START_OF_INSTR(); 643ece92f85SJason Jin DECODE_PRINTF("AAA\n"); 644ece92f85SJason Jin TRACE_AND_STEP(); 645ece92f85SJason Jin M.x86.R_AX = aaa_word(M.x86.R_AX); 646ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 647ece92f85SJason Jin END_OF_INSTR(); 648ece92f85SJason Jin } 649ece92f85SJason Jin 650ece92f85SJason Jin /**************************************************************************** 651ece92f85SJason Jin REMARKS: 652ece92f85SJason Jin Handles opcode 0x3e 653ece92f85SJason Jin ****************************************************************************/ 654ece92f85SJason Jin void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1)) 655ece92f85SJason Jin { 656ece92f85SJason Jin START_OF_INSTR(); 657ece92f85SJason Jin DECODE_PRINTF("DS:\n"); 658ece92f85SJason Jin TRACE_AND_STEP(); 659ece92f85SJason Jin M.x86.mode |= SYSMODE_SEGOVR_DS; 660ece92f85SJason Jin /* NO DECODE_CLEAR_SEGOVR! */ 661ece92f85SJason Jin END_OF_INSTR(); 662ece92f85SJason Jin } 663ece92f85SJason Jin 664ece92f85SJason Jin /**************************************************************************** 665ece92f85SJason Jin REMARKS: 666ece92f85SJason Jin Handles opcode 0x3f 667ece92f85SJason Jin ****************************************************************************/ 668ece92f85SJason Jin void x86emuOp_aas(u8 X86EMU_UNUSED(op1)) 669ece92f85SJason Jin { 670ece92f85SJason Jin START_OF_INSTR(); 671ece92f85SJason Jin DECODE_PRINTF("AAS\n"); 672ece92f85SJason Jin TRACE_AND_STEP(); 673ece92f85SJason Jin M.x86.R_AX = aas_word(M.x86.R_AX); 674ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 675ece92f85SJason Jin END_OF_INSTR(); 676ece92f85SJason Jin } 677ece92f85SJason Jin 678ece92f85SJason Jin /**************************************************************************** 679ece92f85SJason Jin REMARKS: 680ece92f85SJason Jin Handles opcode 0x40 - 0x47 681ece92f85SJason Jin ****************************************************************************/ 682ece92f85SJason Jin void x86emuOp_inc_register(u8 op1) 683ece92f85SJason Jin { 684ece92f85SJason Jin START_OF_INSTR(); 685ece92f85SJason Jin op1 &= 0x7; 686ece92f85SJason Jin DECODE_PRINTF("INC\t"); 687ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 688ece92f85SJason Jin u32 *reg; 689ece92f85SJason Jin reg = DECODE_RM_LONG_REGISTER(op1); 690ece92f85SJason Jin DECODE_PRINTF("\n"); 691ece92f85SJason Jin TRACE_AND_STEP(); 692ece92f85SJason Jin *reg = inc_long(*reg); 693ece92f85SJason Jin } else { 694ece92f85SJason Jin u16 *reg; 695ece92f85SJason Jin reg = DECODE_RM_WORD_REGISTER(op1); 696ece92f85SJason Jin DECODE_PRINTF("\n"); 697ece92f85SJason Jin TRACE_AND_STEP(); 698ece92f85SJason Jin *reg = inc_word(*reg); 699ece92f85SJason Jin } 700ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 701ece92f85SJason Jin END_OF_INSTR(); 702ece92f85SJason Jin } 703ece92f85SJason Jin 704ece92f85SJason Jin /**************************************************************************** 705ece92f85SJason Jin REMARKS: 706ece92f85SJason Jin Handles opcode 0x48 - 0x4F 707ece92f85SJason Jin ****************************************************************************/ 708ece92f85SJason Jin void x86emuOp_dec_register(u8 op1) 709ece92f85SJason Jin { 710ece92f85SJason Jin START_OF_INSTR(); 711ece92f85SJason Jin op1 &= 0x7; 712ece92f85SJason Jin DECODE_PRINTF("DEC\t"); 713ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 714ece92f85SJason Jin u32 *reg; 715ece92f85SJason Jin reg = DECODE_RM_LONG_REGISTER(op1); 716ece92f85SJason Jin DECODE_PRINTF("\n"); 717ece92f85SJason Jin TRACE_AND_STEP(); 718ece92f85SJason Jin *reg = dec_long(*reg); 719ece92f85SJason Jin } else { 720ece92f85SJason Jin u16 *reg; 721ece92f85SJason Jin reg = DECODE_RM_WORD_REGISTER(op1); 722ece92f85SJason Jin DECODE_PRINTF("\n"); 723ece92f85SJason Jin TRACE_AND_STEP(); 724ece92f85SJason Jin *reg = dec_word(*reg); 725ece92f85SJason Jin } 726ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 727ece92f85SJason Jin END_OF_INSTR(); 728ece92f85SJason Jin } 729ece92f85SJason Jin 730ece92f85SJason Jin /**************************************************************************** 731ece92f85SJason Jin REMARKS: 732ece92f85SJason Jin Handles opcode 0x50 - 0x57 733ece92f85SJason Jin ****************************************************************************/ 734ece92f85SJason Jin void x86emuOp_push_register(u8 op1) 735ece92f85SJason Jin { 736ece92f85SJason Jin START_OF_INSTR(); 737ece92f85SJason Jin op1 &= 0x7; 738ece92f85SJason Jin DECODE_PRINTF("PUSH\t"); 739ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 740ece92f85SJason Jin u32 *reg; 741ece92f85SJason Jin reg = DECODE_RM_LONG_REGISTER(op1); 742ece92f85SJason Jin DECODE_PRINTF("\n"); 743ece92f85SJason Jin TRACE_AND_STEP(); 744ece92f85SJason Jin push_long(*reg); 745ece92f85SJason Jin } else { 746ece92f85SJason Jin u16 *reg; 747ece92f85SJason Jin reg = DECODE_RM_WORD_REGISTER(op1); 748ece92f85SJason Jin DECODE_PRINTF("\n"); 749ece92f85SJason Jin TRACE_AND_STEP(); 750ece92f85SJason Jin push_word(*reg); 751ece92f85SJason Jin } 752ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 753ece92f85SJason Jin END_OF_INSTR(); 754ece92f85SJason Jin } 755ece92f85SJason Jin 756ece92f85SJason Jin /**************************************************************************** 757ece92f85SJason Jin REMARKS: 758ece92f85SJason Jin Handles opcode 0x58 - 0x5F 759ece92f85SJason Jin ****************************************************************************/ 760ece92f85SJason Jin void x86emuOp_pop_register(u8 op1) 761ece92f85SJason Jin { 762ece92f85SJason Jin START_OF_INSTR(); 763ece92f85SJason Jin op1 &= 0x7; 764ece92f85SJason Jin DECODE_PRINTF("POP\t"); 765ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 766ece92f85SJason Jin u32 *reg; 767ece92f85SJason Jin reg = DECODE_RM_LONG_REGISTER(op1); 768ece92f85SJason Jin DECODE_PRINTF("\n"); 769ece92f85SJason Jin TRACE_AND_STEP(); 770ece92f85SJason Jin *reg = pop_long(); 771ece92f85SJason Jin } else { 772ece92f85SJason Jin u16 *reg; 773ece92f85SJason Jin reg = DECODE_RM_WORD_REGISTER(op1); 774ece92f85SJason Jin DECODE_PRINTF("\n"); 775ece92f85SJason Jin TRACE_AND_STEP(); 776ece92f85SJason Jin *reg = pop_word(); 777ece92f85SJason Jin } 778ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 779ece92f85SJason Jin END_OF_INSTR(); 780ece92f85SJason Jin } 781ece92f85SJason Jin 782ece92f85SJason Jin /**************************************************************************** 783ece92f85SJason Jin REMARKS: 784ece92f85SJason Jin Handles opcode 0x60 785ece92f85SJason Jin ****************************************************************************/ 786ece92f85SJason Jin void x86emuOp_push_all(u8 X86EMU_UNUSED(op1)) 787ece92f85SJason Jin { 788ece92f85SJason Jin START_OF_INSTR(); 789ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 790ece92f85SJason Jin DECODE_PRINTF("PUSHAD\n"); 791ece92f85SJason Jin } else { 792ece92f85SJason Jin DECODE_PRINTF("PUSHA\n"); 793ece92f85SJason Jin } 794ece92f85SJason Jin TRACE_AND_STEP(); 795ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 796ece92f85SJason Jin u32 old_sp = M.x86.R_ESP; 797ece92f85SJason Jin 798ece92f85SJason Jin push_long(M.x86.R_EAX); 799ece92f85SJason Jin push_long(M.x86.R_ECX); 800ece92f85SJason Jin push_long(M.x86.R_EDX); 801ece92f85SJason Jin push_long(M.x86.R_EBX); 802ece92f85SJason Jin push_long(old_sp); 803ece92f85SJason Jin push_long(M.x86.R_EBP); 804ece92f85SJason Jin push_long(M.x86.R_ESI); 805ece92f85SJason Jin push_long(M.x86.R_EDI); 806ece92f85SJason Jin } else { 807ece92f85SJason Jin u16 old_sp = M.x86.R_SP; 808ece92f85SJason Jin 809ece92f85SJason Jin push_word(M.x86.R_AX); 810ece92f85SJason Jin push_word(M.x86.R_CX); 811ece92f85SJason Jin push_word(M.x86.R_DX); 812ece92f85SJason Jin push_word(M.x86.R_BX); 813ece92f85SJason Jin push_word(old_sp); 814ece92f85SJason Jin push_word(M.x86.R_BP); 815ece92f85SJason Jin push_word(M.x86.R_SI); 816ece92f85SJason Jin push_word(M.x86.R_DI); 817ece92f85SJason Jin } 818ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 819ece92f85SJason Jin END_OF_INSTR(); 820ece92f85SJason Jin } 821ece92f85SJason Jin 822ece92f85SJason Jin /**************************************************************************** 823ece92f85SJason Jin REMARKS: 824ece92f85SJason Jin Handles opcode 0x61 825ece92f85SJason Jin ****************************************************************************/ 826ece92f85SJason Jin void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1)) 827ece92f85SJason Jin { 828ece92f85SJason Jin START_OF_INSTR(); 829ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 830ece92f85SJason Jin DECODE_PRINTF("POPAD\n"); 831ece92f85SJason Jin } else { 832ece92f85SJason Jin DECODE_PRINTF("POPA\n"); 833ece92f85SJason Jin } 834ece92f85SJason Jin TRACE_AND_STEP(); 835ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 836ece92f85SJason Jin M.x86.R_EDI = pop_long(); 837ece92f85SJason Jin M.x86.R_ESI = pop_long(); 838ece92f85SJason Jin M.x86.R_EBP = pop_long(); 839ece92f85SJason Jin M.x86.R_ESP += 4; /* skip ESP */ 840ece92f85SJason Jin M.x86.R_EBX = pop_long(); 841ece92f85SJason Jin M.x86.R_EDX = pop_long(); 842ece92f85SJason Jin M.x86.R_ECX = pop_long(); 843ece92f85SJason Jin M.x86.R_EAX = pop_long(); 844ece92f85SJason Jin } else { 845ece92f85SJason Jin M.x86.R_DI = pop_word(); 846ece92f85SJason Jin M.x86.R_SI = pop_word(); 847ece92f85SJason Jin M.x86.R_BP = pop_word(); 848ece92f85SJason Jin M.x86.R_SP += 2; /* skip SP */ 849ece92f85SJason Jin M.x86.R_BX = pop_word(); 850ece92f85SJason Jin M.x86.R_DX = pop_word(); 851ece92f85SJason Jin M.x86.R_CX = pop_word(); 852ece92f85SJason Jin M.x86.R_AX = pop_word(); 853ece92f85SJason Jin } 854ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 855ece92f85SJason Jin END_OF_INSTR(); 856ece92f85SJason Jin } 857ece92f85SJason Jin 858ece92f85SJason Jin /*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */ 859ece92f85SJason Jin /*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */ 860ece92f85SJason Jin 861ece92f85SJason Jin /**************************************************************************** 862ece92f85SJason Jin REMARKS: 863ece92f85SJason Jin Handles opcode 0x64 864ece92f85SJason Jin ****************************************************************************/ 865ece92f85SJason Jin void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1)) 866ece92f85SJason Jin { 867ece92f85SJason Jin START_OF_INSTR(); 868ece92f85SJason Jin DECODE_PRINTF("FS:\n"); 869ece92f85SJason Jin TRACE_AND_STEP(); 870ece92f85SJason Jin M.x86.mode |= SYSMODE_SEGOVR_FS; 871ece92f85SJason Jin /* 872ece92f85SJason Jin * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 873ece92f85SJason Jin * opcode subroutines we do not want to do this. 874ece92f85SJason Jin */ 875ece92f85SJason Jin END_OF_INSTR(); 876ece92f85SJason Jin } 877ece92f85SJason Jin 878ece92f85SJason Jin /**************************************************************************** 879ece92f85SJason Jin REMARKS: 880ece92f85SJason Jin Handles opcode 0x65 881ece92f85SJason Jin ****************************************************************************/ 882ece92f85SJason Jin void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1)) 883ece92f85SJason Jin { 884ece92f85SJason Jin START_OF_INSTR(); 885ece92f85SJason Jin DECODE_PRINTF("GS:\n"); 886ece92f85SJason Jin TRACE_AND_STEP(); 887ece92f85SJason Jin M.x86.mode |= SYSMODE_SEGOVR_GS; 888ece92f85SJason Jin /* 889ece92f85SJason Jin * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4 890ece92f85SJason Jin * opcode subroutines we do not want to do this. 891ece92f85SJason Jin */ 892ece92f85SJason Jin END_OF_INSTR(); 893ece92f85SJason Jin } 894ece92f85SJason Jin 895ece92f85SJason Jin /**************************************************************************** 896ece92f85SJason Jin REMARKS: 897ece92f85SJason Jin Handles opcode 0x66 - prefix for 32-bit register 898ece92f85SJason Jin ****************************************************************************/ 899ece92f85SJason Jin void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1)) 900ece92f85SJason Jin { 901ece92f85SJason Jin START_OF_INSTR(); 902ece92f85SJason Jin DECODE_PRINTF("DATA:\n"); 903ece92f85SJason Jin TRACE_AND_STEP(); 904ece92f85SJason Jin M.x86.mode |= SYSMODE_PREFIX_DATA; 905ece92f85SJason Jin /* note no DECODE_CLEAR_SEGOVR here. */ 906ece92f85SJason Jin END_OF_INSTR(); 907ece92f85SJason Jin } 908ece92f85SJason Jin 909ece92f85SJason Jin /**************************************************************************** 910ece92f85SJason Jin REMARKS: 911ece92f85SJason Jin Handles opcode 0x67 - prefix for 32-bit address 912ece92f85SJason Jin ****************************************************************************/ 913ece92f85SJason Jin void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1)) 914ece92f85SJason Jin { 915ece92f85SJason Jin START_OF_INSTR(); 916ece92f85SJason Jin DECODE_PRINTF("ADDR:\n"); 917ece92f85SJason Jin TRACE_AND_STEP(); 918ece92f85SJason Jin M.x86.mode |= SYSMODE_PREFIX_ADDR; 919ece92f85SJason Jin /* note no DECODE_CLEAR_SEGOVR here. */ 920ece92f85SJason Jin END_OF_INSTR(); 921ece92f85SJason Jin } 922ece92f85SJason Jin 923ece92f85SJason Jin /**************************************************************************** 924ece92f85SJason Jin REMARKS: 925ece92f85SJason Jin Handles opcode 0x68 926ece92f85SJason Jin ****************************************************************************/ 927ece92f85SJason Jin void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1)) 928ece92f85SJason Jin { 929ece92f85SJason Jin u32 imm; 930ece92f85SJason Jin 931ece92f85SJason Jin START_OF_INSTR(); 932ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 933ece92f85SJason Jin imm = fetch_long_imm(); 934ece92f85SJason Jin } else { 935ece92f85SJason Jin imm = fetch_word_imm(); 936ece92f85SJason Jin } 937ece92f85SJason Jin DECODE_PRINTF2("PUSH\t%x\n", imm); 938ece92f85SJason Jin TRACE_AND_STEP(); 939ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 940ece92f85SJason Jin push_long(imm); 941ece92f85SJason Jin } else { 942ece92f85SJason Jin push_word((u16)imm); 943ece92f85SJason Jin } 944ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 945ece92f85SJason Jin END_OF_INSTR(); 946ece92f85SJason Jin } 947ece92f85SJason Jin 948ece92f85SJason Jin /**************************************************************************** 949ece92f85SJason Jin REMARKS: 950ece92f85SJason Jin Handles opcode 0x69 951ece92f85SJason Jin ****************************************************************************/ 952ece92f85SJason Jin void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1)) 953ece92f85SJason Jin { 954ece92f85SJason Jin int mod, rl, rh; 955ece92f85SJason Jin uint srcoffset; 956ece92f85SJason Jin 957ece92f85SJason Jin START_OF_INSTR(); 958ece92f85SJason Jin DECODE_PRINTF("IMUL\t"); 959ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 960ece92f85SJason Jin if (mod < 3) { 961ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 962ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 963ece92f85SJason Jin u32 *destreg; 964ece92f85SJason Jin u32 srcval; 965ece92f85SJason Jin u32 res_lo,res_hi; 966ece92f85SJason Jin s32 imm; 967ece92f85SJason Jin 968ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh); 969ece92f85SJason Jin DECODE_PRINTF(","); 970ece92f85SJason Jin srcval = fetch_data_long(srcoffset); 971ece92f85SJason Jin imm = fetch_long_imm(); 972ece92f85SJason Jin DECODE_PRINTF2(",%d\n", (s32)imm); 973ece92f85SJason Jin TRACE_AND_STEP(); 974ece92f85SJason Jin imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 975ece92f85SJason Jin if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) || 976ece92f85SJason Jin (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) { 977ece92f85SJason Jin CLEAR_FLAG(F_CF); 978ece92f85SJason Jin CLEAR_FLAG(F_OF); 979ece92f85SJason Jin } else { 980ece92f85SJason Jin SET_FLAG(F_CF); 981ece92f85SJason Jin SET_FLAG(F_OF); 982ece92f85SJason Jin } 983ece92f85SJason Jin *destreg = (u32)res_lo; 984ece92f85SJason Jin } else { 985ece92f85SJason Jin u16 *destreg; 986ece92f85SJason Jin u16 srcval; 987ece92f85SJason Jin u32 res; 988ece92f85SJason Jin s16 imm; 989ece92f85SJason Jin 990ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh); 991ece92f85SJason Jin DECODE_PRINTF(","); 992ece92f85SJason Jin srcval = fetch_data_word(srcoffset); 993ece92f85SJason Jin imm = fetch_word_imm(); 994ece92f85SJason Jin DECODE_PRINTF2(",%d\n", (s32)imm); 995ece92f85SJason Jin TRACE_AND_STEP(); 996ece92f85SJason Jin res = (s16)srcval * (s16)imm; 997ece92f85SJason Jin if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) || 998ece92f85SJason Jin (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) { 999ece92f85SJason Jin CLEAR_FLAG(F_CF); 1000ece92f85SJason Jin CLEAR_FLAG(F_OF); 1001ece92f85SJason Jin } else { 1002ece92f85SJason Jin SET_FLAG(F_CF); 1003ece92f85SJason Jin SET_FLAG(F_OF); 1004ece92f85SJason Jin } 1005ece92f85SJason Jin *destreg = (u16)res; 1006ece92f85SJason Jin } 1007ece92f85SJason Jin } else { /* register to register */ 1008ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1009ece92f85SJason Jin u32 *destreg,*srcreg; 1010ece92f85SJason Jin u32 res_lo,res_hi; 1011ece92f85SJason Jin s32 imm; 1012ece92f85SJason Jin 1013ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh); 1014ece92f85SJason Jin DECODE_PRINTF(","); 1015ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl); 1016ece92f85SJason Jin imm = fetch_long_imm(); 1017ece92f85SJason Jin DECODE_PRINTF2(",%d\n", (s32)imm); 1018ece92f85SJason Jin TRACE_AND_STEP(); 1019ece92f85SJason Jin imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm); 1020ece92f85SJason Jin if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) || 1021ece92f85SJason Jin (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) { 1022ece92f85SJason Jin CLEAR_FLAG(F_CF); 1023ece92f85SJason Jin CLEAR_FLAG(F_OF); 1024ece92f85SJason Jin } else { 1025ece92f85SJason Jin SET_FLAG(F_CF); 1026ece92f85SJason Jin SET_FLAG(F_OF); 1027ece92f85SJason Jin } 1028ece92f85SJason Jin *destreg = (u32)res_lo; 1029ece92f85SJason Jin } else { 1030ece92f85SJason Jin u16 *destreg,*srcreg; 1031ece92f85SJason Jin u32 res; 1032ece92f85SJason Jin s16 imm; 1033ece92f85SJason Jin 1034ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh); 1035ece92f85SJason Jin DECODE_PRINTF(","); 1036ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl); 1037ece92f85SJason Jin imm = fetch_word_imm(); 1038ece92f85SJason Jin DECODE_PRINTF2(",%d\n", (s32)imm); 1039ece92f85SJason Jin res = (s16)*srcreg * (s16)imm; 1040ece92f85SJason Jin if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) || 1041ece92f85SJason Jin (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) { 1042ece92f85SJason Jin CLEAR_FLAG(F_CF); 1043ece92f85SJason Jin CLEAR_FLAG(F_OF); 1044ece92f85SJason Jin } else { 1045ece92f85SJason Jin SET_FLAG(F_CF); 1046ece92f85SJason Jin SET_FLAG(F_OF); 1047ece92f85SJason Jin } 1048ece92f85SJason Jin *destreg = (u16)res; 1049ece92f85SJason Jin } 1050ece92f85SJason Jin } 1051ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1052ece92f85SJason Jin END_OF_INSTR(); 1053ece92f85SJason Jin } 1054ece92f85SJason Jin 1055ece92f85SJason Jin /**************************************************************************** 1056ece92f85SJason Jin REMARKS: 1057ece92f85SJason Jin Handles opcode 0x6a 1058ece92f85SJason Jin ****************************************************************************/ 1059ece92f85SJason Jin void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1)) 1060ece92f85SJason Jin { 1061ece92f85SJason Jin s16 imm; 1062ece92f85SJason Jin 1063ece92f85SJason Jin START_OF_INSTR(); 1064ece92f85SJason Jin imm = (s8)fetch_byte_imm(); 1065ece92f85SJason Jin DECODE_PRINTF2("PUSH\t%d\n", imm); 1066ece92f85SJason Jin TRACE_AND_STEP(); 1067ece92f85SJason Jin push_word(imm); 1068ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1069ece92f85SJason Jin END_OF_INSTR(); 1070ece92f85SJason Jin } 1071ece92f85SJason Jin 1072ece92f85SJason Jin /**************************************************************************** 1073ece92f85SJason Jin REMARKS: 1074ece92f85SJason Jin Handles opcode 0x6b 1075ece92f85SJason Jin ****************************************************************************/ 1076ece92f85SJason Jin void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1)) 1077ece92f85SJason Jin { 1078ece92f85SJason Jin int mod, rl, rh; 1079ece92f85SJason Jin uint srcoffset; 1080ece92f85SJason Jin s8 imm; 1081ece92f85SJason Jin 1082ece92f85SJason Jin START_OF_INSTR(); 1083ece92f85SJason Jin DECODE_PRINTF("IMUL\t"); 1084ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1085ece92f85SJason Jin if (mod < 3) { 1086ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 1087ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1088ece92f85SJason Jin u32 *destreg; 1089ece92f85SJason Jin u32 srcval; 1090ece92f85SJason Jin u32 res_lo,res_hi; 1091ece92f85SJason Jin 1092ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh); 1093ece92f85SJason Jin DECODE_PRINTF(","); 1094ece92f85SJason Jin srcval = fetch_data_long(srcoffset); 1095ece92f85SJason Jin imm = fetch_byte_imm(); 1096ece92f85SJason Jin DECODE_PRINTF2(",%d\n", (s32)imm); 1097ece92f85SJason Jin TRACE_AND_STEP(); 1098ece92f85SJason Jin imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm); 1099ece92f85SJason Jin if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) || 1100ece92f85SJason Jin (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) { 1101ece92f85SJason Jin CLEAR_FLAG(F_CF); 1102ece92f85SJason Jin CLEAR_FLAG(F_OF); 1103ece92f85SJason Jin } else { 1104ece92f85SJason Jin SET_FLAG(F_CF); 1105ece92f85SJason Jin SET_FLAG(F_OF); 1106ece92f85SJason Jin } 1107ece92f85SJason Jin *destreg = (u32)res_lo; 1108ece92f85SJason Jin } else { 1109ece92f85SJason Jin u16 *destreg; 1110ece92f85SJason Jin u16 srcval; 1111ece92f85SJason Jin u32 res; 1112ece92f85SJason Jin 1113ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh); 1114ece92f85SJason Jin DECODE_PRINTF(","); 1115ece92f85SJason Jin srcval = fetch_data_word(srcoffset); 1116ece92f85SJason Jin imm = fetch_byte_imm(); 1117ece92f85SJason Jin DECODE_PRINTF2(",%d\n", (s32)imm); 1118ece92f85SJason Jin TRACE_AND_STEP(); 1119ece92f85SJason Jin res = (s16)srcval * (s16)imm; 1120ece92f85SJason Jin if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) || 1121ece92f85SJason Jin (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) { 1122ece92f85SJason Jin CLEAR_FLAG(F_CF); 1123ece92f85SJason Jin CLEAR_FLAG(F_OF); 1124ece92f85SJason Jin } else { 1125ece92f85SJason Jin SET_FLAG(F_CF); 1126ece92f85SJason Jin SET_FLAG(F_OF); 1127ece92f85SJason Jin } 1128ece92f85SJason Jin *destreg = (u16)res; 1129ece92f85SJason Jin } 1130ece92f85SJason Jin } else { /* register to register */ 1131ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1132ece92f85SJason Jin u32 *destreg,*srcreg; 1133ece92f85SJason Jin u32 res_lo,res_hi; 1134ece92f85SJason Jin 1135ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh); 1136ece92f85SJason Jin DECODE_PRINTF(","); 1137ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl); 1138ece92f85SJason Jin imm = fetch_byte_imm(); 1139ece92f85SJason Jin DECODE_PRINTF2(",%d\n", (s32)imm); 1140ece92f85SJason Jin TRACE_AND_STEP(); 1141ece92f85SJason Jin imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm); 1142ece92f85SJason Jin if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) || 1143ece92f85SJason Jin (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) { 1144ece92f85SJason Jin CLEAR_FLAG(F_CF); 1145ece92f85SJason Jin CLEAR_FLAG(F_OF); 1146ece92f85SJason Jin } else { 1147ece92f85SJason Jin SET_FLAG(F_CF); 1148ece92f85SJason Jin SET_FLAG(F_OF); 1149ece92f85SJason Jin } 1150ece92f85SJason Jin *destreg = (u32)res_lo; 1151ece92f85SJason Jin } else { 1152ece92f85SJason Jin u16 *destreg,*srcreg; 1153ece92f85SJason Jin u32 res; 1154ece92f85SJason Jin 1155ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh); 1156ece92f85SJason Jin DECODE_PRINTF(","); 1157ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl); 1158ece92f85SJason Jin imm = fetch_byte_imm(); 1159ece92f85SJason Jin DECODE_PRINTF2(",%d\n", (s32)imm); 1160ece92f85SJason Jin TRACE_AND_STEP(); 1161ece92f85SJason Jin res = (s16)*srcreg * (s16)imm; 1162ece92f85SJason Jin if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) || 1163ece92f85SJason Jin (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) { 1164ece92f85SJason Jin CLEAR_FLAG(F_CF); 1165ece92f85SJason Jin CLEAR_FLAG(F_OF); 1166ece92f85SJason Jin } else { 1167ece92f85SJason Jin SET_FLAG(F_CF); 1168ece92f85SJason Jin SET_FLAG(F_OF); 1169ece92f85SJason Jin } 1170ece92f85SJason Jin *destreg = (u16)res; 1171ece92f85SJason Jin } 1172ece92f85SJason Jin } 1173ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1174ece92f85SJason Jin END_OF_INSTR(); 1175ece92f85SJason Jin } 1176ece92f85SJason Jin 1177ece92f85SJason Jin /**************************************************************************** 1178ece92f85SJason Jin REMARKS: 1179ece92f85SJason Jin Handles opcode 0x6c 1180ece92f85SJason Jin ****************************************************************************/ 1181ece92f85SJason Jin void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1)) 1182ece92f85SJason Jin { 1183ece92f85SJason Jin START_OF_INSTR(); 1184ece92f85SJason Jin DECODE_PRINTF("INSB\n"); 1185ece92f85SJason Jin ins(1); 1186ece92f85SJason Jin TRACE_AND_STEP(); 1187ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1188ece92f85SJason Jin END_OF_INSTR(); 1189ece92f85SJason Jin } 1190ece92f85SJason Jin 1191ece92f85SJason Jin /**************************************************************************** 1192ece92f85SJason Jin REMARKS: 1193ece92f85SJason Jin Handles opcode 0x6d 1194ece92f85SJason Jin ****************************************************************************/ 1195ece92f85SJason Jin void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1)) 1196ece92f85SJason Jin { 1197ece92f85SJason Jin START_OF_INSTR(); 1198ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1199ece92f85SJason Jin DECODE_PRINTF("INSD\n"); 1200ece92f85SJason Jin ins(4); 1201ece92f85SJason Jin } else { 1202ece92f85SJason Jin DECODE_PRINTF("INSW\n"); 1203ece92f85SJason Jin ins(2); 1204ece92f85SJason Jin } 1205ece92f85SJason Jin TRACE_AND_STEP(); 1206ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1207ece92f85SJason Jin END_OF_INSTR(); 1208ece92f85SJason Jin } 1209ece92f85SJason Jin 1210ece92f85SJason Jin /**************************************************************************** 1211ece92f85SJason Jin REMARKS: 1212ece92f85SJason Jin Handles opcode 0x6e 1213ece92f85SJason Jin ****************************************************************************/ 1214ece92f85SJason Jin void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1)) 1215ece92f85SJason Jin { 1216ece92f85SJason Jin START_OF_INSTR(); 1217ece92f85SJason Jin DECODE_PRINTF("OUTSB\n"); 1218ece92f85SJason Jin outs(1); 1219ece92f85SJason Jin TRACE_AND_STEP(); 1220ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1221ece92f85SJason Jin END_OF_INSTR(); 1222ece92f85SJason Jin } 1223ece92f85SJason Jin 1224ece92f85SJason Jin /**************************************************************************** 1225ece92f85SJason Jin REMARKS: 1226ece92f85SJason Jin Handles opcode 0x6f 1227ece92f85SJason Jin ****************************************************************************/ 1228ece92f85SJason Jin void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1)) 1229ece92f85SJason Jin { 1230ece92f85SJason Jin START_OF_INSTR(); 1231ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1232ece92f85SJason Jin DECODE_PRINTF("OUTSD\n"); 1233ece92f85SJason Jin outs(4); 1234ece92f85SJason Jin } else { 1235ece92f85SJason Jin DECODE_PRINTF("OUTSW\n"); 1236ece92f85SJason Jin outs(2); 1237ece92f85SJason Jin } 1238ece92f85SJason Jin TRACE_AND_STEP(); 1239ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1240ece92f85SJason Jin END_OF_INSTR(); 1241ece92f85SJason Jin } 1242ece92f85SJason Jin 1243ece92f85SJason Jin /**************************************************************************** 1244ece92f85SJason Jin REMARKS: 1245ece92f85SJason Jin Handles opcode 0x70 - 0x7F 1246ece92f85SJason Jin ****************************************************************************/ 1247ece92f85SJason Jin int x86emu_check_jump_condition(u8 op); 1248ece92f85SJason Jin 1249ece92f85SJason Jin void x86emuOp_jump_near_cond(u8 op1) 1250ece92f85SJason Jin { 1251ece92f85SJason Jin s8 offset; 1252ece92f85SJason Jin u16 target; 1253ece92f85SJason Jin int cond; 1254ece92f85SJason Jin 1255ece92f85SJason Jin /* jump to byte offset if overflow flag is set */ 1256ece92f85SJason Jin START_OF_INSTR(); 1257ece92f85SJason Jin cond = x86emu_check_jump_condition(op1 & 0xF); 1258ece92f85SJason Jin offset = (s8)fetch_byte_imm(); 1259ece92f85SJason Jin target = (u16)(M.x86.R_IP + (s16)offset); 1260ece92f85SJason Jin DECODE_PRINTF2("%x\n", target); 1261ece92f85SJason Jin TRACE_AND_STEP(); 1262ece92f85SJason Jin if (cond) 1263ece92f85SJason Jin M.x86.R_IP = target; 1264ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1265ece92f85SJason Jin END_OF_INSTR(); 1266ece92f85SJason Jin } 1267ece92f85SJason Jin 1268ece92f85SJason Jin /**************************************************************************** 1269ece92f85SJason Jin REMARKS: 1270ece92f85SJason Jin Handles opcode 0x80 1271ece92f85SJason Jin ****************************************************************************/ 1272ece92f85SJason Jin void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 1273ece92f85SJason Jin { 1274ece92f85SJason Jin int mod, rl, rh; 1275ece92f85SJason Jin u8 *destreg; 1276ece92f85SJason Jin uint destoffset; 1277ece92f85SJason Jin u8 imm; 1278ece92f85SJason Jin u8 destval; 1279ece92f85SJason Jin 1280ece92f85SJason Jin /* 1281ece92f85SJason Jin * Weirdo special case instruction format. Part of the opcode 1282ece92f85SJason Jin * held below in "RH". Doubly nested case would result, except 1283ece92f85SJason Jin * that the decoded instruction 1284ece92f85SJason Jin */ 1285ece92f85SJason Jin START_OF_INSTR(); 1286ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1287ece92f85SJason Jin #ifdef DEBUG 1288ece92f85SJason Jin if (DEBUG_DECODE()) { 1289ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more 1290ece92f85SJason Jin general, so that it is important to leave the strings 1291ece92f85SJason Jin in the same format, even though the result is that the 1292ece92f85SJason Jin above test is done twice. */ 1293ece92f85SJason Jin 1294ece92f85SJason Jin switch (rh) { 1295ece92f85SJason Jin case 0: 1296ece92f85SJason Jin DECODE_PRINTF("ADD\t"); 1297ece92f85SJason Jin break; 1298ece92f85SJason Jin case 1: 1299ece92f85SJason Jin DECODE_PRINTF("OR\t"); 1300ece92f85SJason Jin break; 1301ece92f85SJason Jin case 2: 1302ece92f85SJason Jin DECODE_PRINTF("ADC\t"); 1303ece92f85SJason Jin break; 1304ece92f85SJason Jin case 3: 1305ece92f85SJason Jin DECODE_PRINTF("SBB\t"); 1306ece92f85SJason Jin break; 1307ece92f85SJason Jin case 4: 1308ece92f85SJason Jin DECODE_PRINTF("AND\t"); 1309ece92f85SJason Jin break; 1310ece92f85SJason Jin case 5: 1311ece92f85SJason Jin DECODE_PRINTF("SUB\t"); 1312ece92f85SJason Jin break; 1313ece92f85SJason Jin case 6: 1314ece92f85SJason Jin DECODE_PRINTF("XOR\t"); 1315ece92f85SJason Jin break; 1316ece92f85SJason Jin case 7: 1317ece92f85SJason Jin DECODE_PRINTF("CMP\t"); 1318ece92f85SJason Jin break; 1319ece92f85SJason Jin } 1320ece92f85SJason Jin } 1321ece92f85SJason Jin #endif 1322ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing 1323ece92f85SJason Jin mode. */ 1324ece92f85SJason Jin if (mod < 3) { 1325ece92f85SJason Jin DECODE_PRINTF("BYTE PTR "); 1326ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 1327ece92f85SJason Jin DECODE_PRINTF(","); 1328ece92f85SJason Jin destval = fetch_data_byte(destoffset); 1329ece92f85SJason Jin imm = fetch_byte_imm(); 1330ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm); 1331ece92f85SJason Jin TRACE_AND_STEP(); 1332ece92f85SJason Jin destval = (*genop_byte_operation[rh]) (destval, imm); 1333ece92f85SJason Jin if (rh != 7) 1334ece92f85SJason Jin store_data_byte(destoffset, destval); 1335ece92f85SJason Jin } else { /* register to register */ 1336ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl); 1337ece92f85SJason Jin DECODE_PRINTF(","); 1338ece92f85SJason Jin imm = fetch_byte_imm(); 1339ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm); 1340ece92f85SJason Jin TRACE_AND_STEP(); 1341ece92f85SJason Jin destval = (*genop_byte_operation[rh]) (*destreg, imm); 1342ece92f85SJason Jin if (rh != 7) 1343ece92f85SJason Jin *destreg = destval; 1344ece92f85SJason Jin } 1345ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1346ece92f85SJason Jin END_OF_INSTR(); 1347ece92f85SJason Jin } 1348ece92f85SJason Jin 1349ece92f85SJason Jin /**************************************************************************** 1350ece92f85SJason Jin REMARKS: 1351ece92f85SJason Jin Handles opcode 0x81 1352ece92f85SJason Jin ****************************************************************************/ 1353ece92f85SJason Jin void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 1354ece92f85SJason Jin { 1355ece92f85SJason Jin int mod, rl, rh; 1356ece92f85SJason Jin uint destoffset; 1357ece92f85SJason Jin 1358ece92f85SJason Jin /* 1359ece92f85SJason Jin * Weirdo special case instruction format. Part of the opcode 1360ece92f85SJason Jin * held below in "RH". Doubly nested case would result, except 1361ece92f85SJason Jin * that the decoded instruction 1362ece92f85SJason Jin */ 1363ece92f85SJason Jin START_OF_INSTR(); 1364ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1365ece92f85SJason Jin #ifdef DEBUG 1366ece92f85SJason Jin if (DEBUG_DECODE()) { 1367ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more 1368ece92f85SJason Jin general, so that it is important to leave the strings 1369ece92f85SJason Jin in the same format, even though the result is that the 1370ece92f85SJason Jin above test is done twice. */ 1371ece92f85SJason Jin 1372ece92f85SJason Jin switch (rh) { 1373ece92f85SJason Jin case 0: 1374ece92f85SJason Jin DECODE_PRINTF("ADD\t"); 1375ece92f85SJason Jin break; 1376ece92f85SJason Jin case 1: 1377ece92f85SJason Jin DECODE_PRINTF("OR\t"); 1378ece92f85SJason Jin break; 1379ece92f85SJason Jin case 2: 1380ece92f85SJason Jin DECODE_PRINTF("ADC\t"); 1381ece92f85SJason Jin break; 1382ece92f85SJason Jin case 3: 1383ece92f85SJason Jin DECODE_PRINTF("SBB\t"); 1384ece92f85SJason Jin break; 1385ece92f85SJason Jin case 4: 1386ece92f85SJason Jin DECODE_PRINTF("AND\t"); 1387ece92f85SJason Jin break; 1388ece92f85SJason Jin case 5: 1389ece92f85SJason Jin DECODE_PRINTF("SUB\t"); 1390ece92f85SJason Jin break; 1391ece92f85SJason Jin case 6: 1392ece92f85SJason Jin DECODE_PRINTF("XOR\t"); 1393ece92f85SJason Jin break; 1394ece92f85SJason Jin case 7: 1395ece92f85SJason Jin DECODE_PRINTF("CMP\t"); 1396ece92f85SJason Jin break; 1397ece92f85SJason Jin } 1398ece92f85SJason Jin } 1399ece92f85SJason Jin #endif 1400ece92f85SJason Jin /* 1401ece92f85SJason Jin * Know operation, decode the mod byte to find the addressing 1402ece92f85SJason Jin * mode. 1403ece92f85SJason Jin */ 1404ece92f85SJason Jin if (mod < 3) { 1405ece92f85SJason Jin DECODE_PRINTF("DWORD PTR "); 1406ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 1407ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1408ece92f85SJason Jin u32 destval,imm; 1409ece92f85SJason Jin 1410ece92f85SJason Jin DECODE_PRINTF(","); 1411ece92f85SJason Jin destval = fetch_data_long(destoffset); 1412ece92f85SJason Jin imm = fetch_long_imm(); 1413ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm); 1414ece92f85SJason Jin TRACE_AND_STEP(); 1415ece92f85SJason Jin destval = (*genop_long_operation[rh]) (destval, imm); 1416ece92f85SJason Jin if (rh != 7) 1417ece92f85SJason Jin store_data_long(destoffset, destval); 1418ece92f85SJason Jin } else { 1419ece92f85SJason Jin u16 destval,imm; 1420ece92f85SJason Jin 1421ece92f85SJason Jin DECODE_PRINTF(","); 1422ece92f85SJason Jin destval = fetch_data_word(destoffset); 1423ece92f85SJason Jin imm = fetch_word_imm(); 1424ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm); 1425ece92f85SJason Jin TRACE_AND_STEP(); 1426ece92f85SJason Jin destval = (*genop_word_operation[rh]) (destval, imm); 1427ece92f85SJason Jin if (rh != 7) 1428ece92f85SJason Jin store_data_word(destoffset, destval); 1429ece92f85SJason Jin } 1430ece92f85SJason Jin } else { /* register to register */ 1431ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1432ece92f85SJason Jin u32 *destreg; 1433ece92f85SJason Jin u32 destval,imm; 1434ece92f85SJason Jin 1435ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 1436ece92f85SJason Jin DECODE_PRINTF(","); 1437ece92f85SJason Jin imm = fetch_long_imm(); 1438ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm); 1439ece92f85SJason Jin TRACE_AND_STEP(); 1440ece92f85SJason Jin destval = (*genop_long_operation[rh]) (*destreg, imm); 1441ece92f85SJason Jin if (rh != 7) 1442ece92f85SJason Jin *destreg = destval; 1443ece92f85SJason Jin } else { 1444ece92f85SJason Jin u16 *destreg; 1445ece92f85SJason Jin u16 destval,imm; 1446ece92f85SJason Jin 1447ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 1448ece92f85SJason Jin DECODE_PRINTF(","); 1449ece92f85SJason Jin imm = fetch_word_imm(); 1450ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm); 1451ece92f85SJason Jin TRACE_AND_STEP(); 1452ece92f85SJason Jin destval = (*genop_word_operation[rh]) (*destreg, imm); 1453ece92f85SJason Jin if (rh != 7) 1454ece92f85SJason Jin *destreg = destval; 1455ece92f85SJason Jin } 1456ece92f85SJason Jin } 1457ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1458ece92f85SJason Jin END_OF_INSTR(); 1459ece92f85SJason Jin } 1460ece92f85SJason Jin 1461ece92f85SJason Jin /**************************************************************************** 1462ece92f85SJason Jin REMARKS: 1463ece92f85SJason Jin Handles opcode 0x82 1464ece92f85SJason Jin ****************************************************************************/ 1465ece92f85SJason Jin void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 1466ece92f85SJason Jin { 1467ece92f85SJason Jin int mod, rl, rh; 1468ece92f85SJason Jin u8 *destreg; 1469ece92f85SJason Jin uint destoffset; 1470ece92f85SJason Jin u8 imm; 1471ece92f85SJason Jin u8 destval; 1472ece92f85SJason Jin 1473ece92f85SJason Jin /* 1474ece92f85SJason Jin * Weirdo special case instruction format. Part of the opcode 1475ece92f85SJason Jin * held below in "RH". Doubly nested case would result, except 1476ece92f85SJason Jin * that the decoded instruction Similar to opcode 81, except that 1477ece92f85SJason Jin * the immediate byte is sign extended to a word length. 1478ece92f85SJason Jin */ 1479ece92f85SJason Jin START_OF_INSTR(); 1480ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1481ece92f85SJason Jin #ifdef DEBUG 1482ece92f85SJason Jin if (DEBUG_DECODE()) { 1483ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more 1484ece92f85SJason Jin general, so that it is important to leave the strings 1485ece92f85SJason Jin in the same format, even though the result is that the 1486ece92f85SJason Jin above test is done twice. */ 1487ece92f85SJason Jin switch (rh) { 1488ece92f85SJason Jin case 0: 1489ece92f85SJason Jin DECODE_PRINTF("ADD\t"); 1490ece92f85SJason Jin break; 1491ece92f85SJason Jin case 1: 1492ece92f85SJason Jin DECODE_PRINTF("OR\t"); 1493ece92f85SJason Jin break; 1494ece92f85SJason Jin case 2: 1495ece92f85SJason Jin DECODE_PRINTF("ADC\t"); 1496ece92f85SJason Jin break; 1497ece92f85SJason Jin case 3: 1498ece92f85SJason Jin DECODE_PRINTF("SBB\t"); 1499ece92f85SJason Jin break; 1500ece92f85SJason Jin case 4: 1501ece92f85SJason Jin DECODE_PRINTF("AND\t"); 1502ece92f85SJason Jin break; 1503ece92f85SJason Jin case 5: 1504ece92f85SJason Jin DECODE_PRINTF("SUB\t"); 1505ece92f85SJason Jin break; 1506ece92f85SJason Jin case 6: 1507ece92f85SJason Jin DECODE_PRINTF("XOR\t"); 1508ece92f85SJason Jin break; 1509ece92f85SJason Jin case 7: 1510ece92f85SJason Jin DECODE_PRINTF("CMP\t"); 1511ece92f85SJason Jin break; 1512ece92f85SJason Jin } 1513ece92f85SJason Jin } 1514ece92f85SJason Jin #endif 1515ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing 1516ece92f85SJason Jin mode. */ 1517ece92f85SJason Jin if (mod < 3) { 1518ece92f85SJason Jin DECODE_PRINTF("BYTE PTR "); 1519ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 1520ece92f85SJason Jin destval = fetch_data_byte(destoffset); 1521ece92f85SJason Jin imm = fetch_byte_imm(); 1522ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm); 1523ece92f85SJason Jin TRACE_AND_STEP(); 1524ece92f85SJason Jin destval = (*genop_byte_operation[rh]) (destval, imm); 1525ece92f85SJason Jin if (rh != 7) 1526ece92f85SJason Jin store_data_byte(destoffset, destval); 1527ece92f85SJason Jin } else { /* register to register */ 1528ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl); 1529ece92f85SJason Jin imm = fetch_byte_imm(); 1530ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm); 1531ece92f85SJason Jin TRACE_AND_STEP(); 1532ece92f85SJason Jin destval = (*genop_byte_operation[rh]) (*destreg, imm); 1533ece92f85SJason Jin if (rh != 7) 1534ece92f85SJason Jin *destreg = destval; 1535ece92f85SJason Jin } 1536ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1537ece92f85SJason Jin END_OF_INSTR(); 1538ece92f85SJason Jin } 1539ece92f85SJason Jin 1540ece92f85SJason Jin /**************************************************************************** 1541ece92f85SJason Jin REMARKS: 1542ece92f85SJason Jin Handles opcode 0x83 1543ece92f85SJason Jin ****************************************************************************/ 1544ece92f85SJason Jin void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 1545ece92f85SJason Jin { 1546ece92f85SJason Jin int mod, rl, rh; 1547ece92f85SJason Jin uint destoffset; 1548ece92f85SJason Jin 1549ece92f85SJason Jin /* 1550ece92f85SJason Jin * Weirdo special case instruction format. Part of the opcode 1551ece92f85SJason Jin * held below in "RH". Doubly nested case would result, except 1552ece92f85SJason Jin * that the decoded instruction Similar to opcode 81, except that 1553ece92f85SJason Jin * the immediate byte is sign extended to a word length. 1554ece92f85SJason Jin */ 1555ece92f85SJason Jin START_OF_INSTR(); 1556ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1557ece92f85SJason Jin #ifdef DEBUG 1558ece92f85SJason Jin if (DEBUG_DECODE()) { 1559ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more 1560ece92f85SJason Jin general, so that it is important to leave the strings 1561ece92f85SJason Jin in the same format, even though the result is that the 1562ece92f85SJason Jin above test is done twice. */ 1563ece92f85SJason Jin switch (rh) { 1564ece92f85SJason Jin case 0: 1565ece92f85SJason Jin DECODE_PRINTF("ADD\t"); 1566ece92f85SJason Jin break; 1567ece92f85SJason Jin case 1: 1568ece92f85SJason Jin DECODE_PRINTF("OR\t"); 1569ece92f85SJason Jin break; 1570ece92f85SJason Jin case 2: 1571ece92f85SJason Jin DECODE_PRINTF("ADC\t"); 1572ece92f85SJason Jin break; 1573ece92f85SJason Jin case 3: 1574ece92f85SJason Jin DECODE_PRINTF("SBB\t"); 1575ece92f85SJason Jin break; 1576ece92f85SJason Jin case 4: 1577ece92f85SJason Jin DECODE_PRINTF("AND\t"); 1578ece92f85SJason Jin break; 1579ece92f85SJason Jin case 5: 1580ece92f85SJason Jin DECODE_PRINTF("SUB\t"); 1581ece92f85SJason Jin break; 1582ece92f85SJason Jin case 6: 1583ece92f85SJason Jin DECODE_PRINTF("XOR\t"); 1584ece92f85SJason Jin break; 1585ece92f85SJason Jin case 7: 1586ece92f85SJason Jin DECODE_PRINTF("CMP\t"); 1587ece92f85SJason Jin break; 1588ece92f85SJason Jin } 1589ece92f85SJason Jin } 1590ece92f85SJason Jin #endif 1591ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing 1592ece92f85SJason Jin mode. */ 1593ece92f85SJason Jin if (mod < 3) { 1594ece92f85SJason Jin DECODE_PRINTF("DWORD PTR "); 1595ece92f85SJason Jin destoffset = decode_rmXX_address(mod,rl); 1596ece92f85SJason Jin 1597ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1598ece92f85SJason Jin u32 destval,imm; 1599ece92f85SJason Jin 1600ece92f85SJason Jin destval = fetch_data_long(destoffset); 1601ece92f85SJason Jin imm = (s8) fetch_byte_imm(); 1602ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm); 1603ece92f85SJason Jin TRACE_AND_STEP(); 1604ece92f85SJason Jin destval = (*genop_long_operation[rh]) (destval, imm); 1605ece92f85SJason Jin if (rh != 7) 1606ece92f85SJason Jin store_data_long(destoffset, destval); 1607ece92f85SJason Jin } else { 1608ece92f85SJason Jin u16 destval,imm; 1609ece92f85SJason Jin 1610ece92f85SJason Jin destval = fetch_data_word(destoffset); 1611ece92f85SJason Jin imm = (s8) fetch_byte_imm(); 1612ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm); 1613ece92f85SJason Jin TRACE_AND_STEP(); 1614ece92f85SJason Jin destval = (*genop_word_operation[rh]) (destval, imm); 1615ece92f85SJason Jin if (rh != 7) 1616ece92f85SJason Jin store_data_word(destoffset, destval); 1617ece92f85SJason Jin } 1618ece92f85SJason Jin } else { /* register to register */ 1619ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1620ece92f85SJason Jin u32 *destreg; 1621ece92f85SJason Jin u32 destval,imm; 1622ece92f85SJason Jin 1623ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 1624ece92f85SJason Jin imm = (s8) fetch_byte_imm(); 1625ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm); 1626ece92f85SJason Jin TRACE_AND_STEP(); 1627ece92f85SJason Jin destval = (*genop_long_operation[rh]) (*destreg, imm); 1628ece92f85SJason Jin if (rh != 7) 1629ece92f85SJason Jin *destreg = destval; 1630ece92f85SJason Jin } else { 1631ece92f85SJason Jin u16 *destreg; 1632ece92f85SJason Jin u16 destval,imm; 1633ece92f85SJason Jin 1634ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 1635ece92f85SJason Jin imm = (s8) fetch_byte_imm(); 1636ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm); 1637ece92f85SJason Jin TRACE_AND_STEP(); 1638ece92f85SJason Jin destval = (*genop_word_operation[rh]) (*destreg, imm); 1639ece92f85SJason Jin if (rh != 7) 1640ece92f85SJason Jin *destreg = destval; 1641ece92f85SJason Jin } 1642ece92f85SJason Jin } 1643ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1644ece92f85SJason Jin END_OF_INSTR(); 1645ece92f85SJason Jin } 1646ece92f85SJason Jin 1647ece92f85SJason Jin /**************************************************************************** 1648ece92f85SJason Jin REMARKS: 1649ece92f85SJason Jin Handles opcode 0x84 1650ece92f85SJason Jin ****************************************************************************/ 1651ece92f85SJason Jin void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1)) 1652ece92f85SJason Jin { 1653ece92f85SJason Jin int mod, rl, rh; 1654ece92f85SJason Jin u8 *destreg, *srcreg; 1655ece92f85SJason Jin uint destoffset; 1656ece92f85SJason Jin u8 destval; 1657ece92f85SJason Jin 1658ece92f85SJason Jin START_OF_INSTR(); 1659ece92f85SJason Jin DECODE_PRINTF("TEST\t"); 1660ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1661ece92f85SJason Jin if (mod < 3) { 1662ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 1663ece92f85SJason Jin DECODE_PRINTF(","); 1664ece92f85SJason Jin destval = fetch_data_byte(destoffset); 1665ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rh); 1666ece92f85SJason Jin DECODE_PRINTF("\n"); 1667ece92f85SJason Jin TRACE_AND_STEP(); 1668ece92f85SJason Jin test_byte(destval, *srcreg); 1669ece92f85SJason Jin } else { /* register to register */ 1670ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl); 1671ece92f85SJason Jin DECODE_PRINTF(","); 1672ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rh); 1673ece92f85SJason Jin DECODE_PRINTF("\n"); 1674ece92f85SJason Jin TRACE_AND_STEP(); 1675ece92f85SJason Jin test_byte(*destreg, *srcreg); 1676ece92f85SJason Jin } 1677ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1678ece92f85SJason Jin END_OF_INSTR(); 1679ece92f85SJason Jin } 1680ece92f85SJason Jin 1681ece92f85SJason Jin /**************************************************************************** 1682ece92f85SJason Jin REMARKS: 1683ece92f85SJason Jin Handles opcode 0x85 1684ece92f85SJason Jin ****************************************************************************/ 1685ece92f85SJason Jin void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1)) 1686ece92f85SJason Jin { 1687ece92f85SJason Jin int mod, rl, rh; 1688ece92f85SJason Jin uint destoffset; 1689ece92f85SJason Jin 1690ece92f85SJason Jin START_OF_INSTR(); 1691ece92f85SJason Jin DECODE_PRINTF("TEST\t"); 1692ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1693ece92f85SJason Jin if (mod < 3) { 1694ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 1695ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1696ece92f85SJason Jin u32 destval; 1697ece92f85SJason Jin u32 *srcreg; 1698ece92f85SJason Jin 1699ece92f85SJason Jin DECODE_PRINTF(","); 1700ece92f85SJason Jin destval = fetch_data_long(destoffset); 1701ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rh); 1702ece92f85SJason Jin DECODE_PRINTF("\n"); 1703ece92f85SJason Jin TRACE_AND_STEP(); 1704ece92f85SJason Jin test_long(destval, *srcreg); 1705ece92f85SJason Jin } else { 1706ece92f85SJason Jin u16 destval; 1707ece92f85SJason Jin u16 *srcreg; 1708ece92f85SJason Jin 1709ece92f85SJason Jin DECODE_PRINTF(","); 1710ece92f85SJason Jin destval = fetch_data_word(destoffset); 1711ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh); 1712ece92f85SJason Jin DECODE_PRINTF("\n"); 1713ece92f85SJason Jin TRACE_AND_STEP(); 1714ece92f85SJason Jin test_word(destval, *srcreg); 1715ece92f85SJason Jin } 1716ece92f85SJason Jin } else { /* register to register */ 1717ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1718ece92f85SJason Jin u32 *destreg,*srcreg; 1719ece92f85SJason Jin 1720ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 1721ece92f85SJason Jin DECODE_PRINTF(","); 1722ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rh); 1723ece92f85SJason Jin DECODE_PRINTF("\n"); 1724ece92f85SJason Jin TRACE_AND_STEP(); 1725ece92f85SJason Jin test_long(*destreg, *srcreg); 1726ece92f85SJason Jin } else { 1727ece92f85SJason Jin u16 *destreg,*srcreg; 1728ece92f85SJason Jin 1729ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 1730ece92f85SJason Jin DECODE_PRINTF(","); 1731ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh); 1732ece92f85SJason Jin DECODE_PRINTF("\n"); 1733ece92f85SJason Jin TRACE_AND_STEP(); 1734ece92f85SJason Jin test_word(*destreg, *srcreg); 1735ece92f85SJason Jin } 1736ece92f85SJason Jin } 1737ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1738ece92f85SJason Jin END_OF_INSTR(); 1739ece92f85SJason Jin } 1740ece92f85SJason Jin 1741ece92f85SJason Jin /**************************************************************************** 1742ece92f85SJason Jin REMARKS: 1743ece92f85SJason Jin Handles opcode 0x86 1744ece92f85SJason Jin ****************************************************************************/ 1745ece92f85SJason Jin void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1)) 1746ece92f85SJason Jin { 1747ece92f85SJason Jin int mod, rl, rh; 1748ece92f85SJason Jin u8 *destreg, *srcreg; 1749ece92f85SJason Jin uint destoffset; 1750ece92f85SJason Jin u8 destval; 1751ece92f85SJason Jin u8 tmp; 1752ece92f85SJason Jin 1753ece92f85SJason Jin START_OF_INSTR(); 1754ece92f85SJason Jin DECODE_PRINTF("XCHG\t"); 1755ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1756ece92f85SJason Jin if (mod < 3) { 1757ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 1758ece92f85SJason Jin DECODE_PRINTF(","); 1759ece92f85SJason Jin destval = fetch_data_byte(destoffset); 1760ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rh); 1761ece92f85SJason Jin DECODE_PRINTF("\n"); 1762ece92f85SJason Jin TRACE_AND_STEP(); 1763ece92f85SJason Jin tmp = *srcreg; 1764ece92f85SJason Jin *srcreg = destval; 1765ece92f85SJason Jin destval = tmp; 1766ece92f85SJason Jin store_data_byte(destoffset, destval); 1767ece92f85SJason Jin } else { /* register to register */ 1768ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl); 1769ece92f85SJason Jin DECODE_PRINTF(","); 1770ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rh); 1771ece92f85SJason Jin DECODE_PRINTF("\n"); 1772ece92f85SJason Jin TRACE_AND_STEP(); 1773ece92f85SJason Jin tmp = *srcreg; 1774ece92f85SJason Jin *srcreg = *destreg; 1775ece92f85SJason Jin *destreg = tmp; 1776ece92f85SJason Jin } 1777ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1778ece92f85SJason Jin END_OF_INSTR(); 1779ece92f85SJason Jin } 1780ece92f85SJason Jin 1781ece92f85SJason Jin /**************************************************************************** 1782ece92f85SJason Jin REMARKS: 1783ece92f85SJason Jin Handles opcode 0x87 1784ece92f85SJason Jin ****************************************************************************/ 1785ece92f85SJason Jin void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1)) 1786ece92f85SJason Jin { 1787ece92f85SJason Jin int mod, rl, rh; 1788ece92f85SJason Jin uint destoffset; 1789ece92f85SJason Jin 1790ece92f85SJason Jin START_OF_INSTR(); 1791ece92f85SJason Jin DECODE_PRINTF("XCHG\t"); 1792ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1793ece92f85SJason Jin if (mod < 3) { 1794ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 1795ece92f85SJason Jin DECODE_PRINTF(","); 1796ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1797ece92f85SJason Jin u32 *srcreg; 1798ece92f85SJason Jin u32 destval,tmp; 1799ece92f85SJason Jin 1800ece92f85SJason Jin destval = fetch_data_long(destoffset); 1801ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rh); 1802ece92f85SJason Jin DECODE_PRINTF("\n"); 1803ece92f85SJason Jin TRACE_AND_STEP(); 1804ece92f85SJason Jin tmp = *srcreg; 1805ece92f85SJason Jin *srcreg = destval; 1806ece92f85SJason Jin destval = tmp; 1807ece92f85SJason Jin store_data_long(destoffset, destval); 1808ece92f85SJason Jin } else { 1809ece92f85SJason Jin u16 *srcreg; 1810ece92f85SJason Jin u16 destval,tmp; 1811ece92f85SJason Jin 1812ece92f85SJason Jin destval = fetch_data_word(destoffset); 1813ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh); 1814ece92f85SJason Jin DECODE_PRINTF("\n"); 1815ece92f85SJason Jin TRACE_AND_STEP(); 1816ece92f85SJason Jin tmp = *srcreg; 1817ece92f85SJason Jin *srcreg = destval; 1818ece92f85SJason Jin destval = tmp; 1819ece92f85SJason Jin store_data_word(destoffset, destval); 1820ece92f85SJason Jin } 1821ece92f85SJason Jin } else { /* register to register */ 1822ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1823ece92f85SJason Jin u32 *destreg,*srcreg; 1824ece92f85SJason Jin u32 tmp; 1825ece92f85SJason Jin 1826ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 1827ece92f85SJason Jin DECODE_PRINTF(","); 1828ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rh); 1829ece92f85SJason Jin DECODE_PRINTF("\n"); 1830ece92f85SJason Jin TRACE_AND_STEP(); 1831ece92f85SJason Jin tmp = *srcreg; 1832ece92f85SJason Jin *srcreg = *destreg; 1833ece92f85SJason Jin *destreg = tmp; 1834ece92f85SJason Jin } else { 1835ece92f85SJason Jin u16 *destreg,*srcreg; 1836ece92f85SJason Jin u16 tmp; 1837ece92f85SJason Jin 1838ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 1839ece92f85SJason Jin DECODE_PRINTF(","); 1840ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh); 1841ece92f85SJason Jin DECODE_PRINTF("\n"); 1842ece92f85SJason Jin TRACE_AND_STEP(); 1843ece92f85SJason Jin tmp = *srcreg; 1844ece92f85SJason Jin *srcreg = *destreg; 1845ece92f85SJason Jin *destreg = tmp; 1846ece92f85SJason Jin } 1847ece92f85SJason Jin } 1848ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1849ece92f85SJason Jin END_OF_INSTR(); 1850ece92f85SJason Jin } 1851ece92f85SJason Jin 1852ece92f85SJason Jin /**************************************************************************** 1853ece92f85SJason Jin REMARKS: 1854ece92f85SJason Jin Handles opcode 0x88 1855ece92f85SJason Jin ****************************************************************************/ 1856ece92f85SJason Jin void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1)) 1857ece92f85SJason Jin { 1858ece92f85SJason Jin int mod, rl, rh; 1859ece92f85SJason Jin u8 *destreg, *srcreg; 1860ece92f85SJason Jin uint destoffset; 1861ece92f85SJason Jin 1862ece92f85SJason Jin START_OF_INSTR(); 1863ece92f85SJason Jin DECODE_PRINTF("MOV\t"); 1864ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1865ece92f85SJason Jin if (mod < 3) { 1866ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 1867ece92f85SJason Jin DECODE_PRINTF(","); 1868ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rh); 1869ece92f85SJason Jin DECODE_PRINTF("\n"); 1870ece92f85SJason Jin TRACE_AND_STEP(); 1871ece92f85SJason Jin store_data_byte(destoffset, *srcreg); 1872ece92f85SJason Jin } else { /* register to register */ 1873ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl); 1874ece92f85SJason Jin DECODE_PRINTF(","); 1875ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rh); 1876ece92f85SJason Jin DECODE_PRINTF("\n"); 1877ece92f85SJason Jin TRACE_AND_STEP(); 1878ece92f85SJason Jin *destreg = *srcreg; 1879ece92f85SJason Jin } 1880ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1881ece92f85SJason Jin END_OF_INSTR(); 1882ece92f85SJason Jin } 1883ece92f85SJason Jin 1884ece92f85SJason Jin /**************************************************************************** 1885ece92f85SJason Jin REMARKS: 1886ece92f85SJason Jin Handles opcode 0x89 1887ece92f85SJason Jin ****************************************************************************/ 1888ece92f85SJason Jin void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1)) 1889ece92f85SJason Jin { 1890ece92f85SJason Jin int mod, rl, rh; 1891ece92f85SJason Jin uint destoffset; 1892ece92f85SJason Jin 1893ece92f85SJason Jin START_OF_INSTR(); 1894ece92f85SJason Jin DECODE_PRINTF("MOV\t"); 1895ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1896ece92f85SJason Jin if (mod < 3) { 1897ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 1898ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1899ece92f85SJason Jin u32 *srcreg; 1900ece92f85SJason Jin 1901ece92f85SJason Jin DECODE_PRINTF(","); 1902ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rh); 1903ece92f85SJason Jin DECODE_PRINTF("\n"); 1904ece92f85SJason Jin TRACE_AND_STEP(); 1905ece92f85SJason Jin store_data_long(destoffset, *srcreg); 1906ece92f85SJason Jin } else { 1907ece92f85SJason Jin u16 *srcreg; 1908ece92f85SJason Jin 1909ece92f85SJason Jin DECODE_PRINTF(","); 1910ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh); 1911ece92f85SJason Jin DECODE_PRINTF("\n"); 1912ece92f85SJason Jin TRACE_AND_STEP(); 1913ece92f85SJason Jin store_data_word(destoffset, *srcreg); 1914ece92f85SJason Jin } 1915ece92f85SJason Jin } else { /* register to register */ 1916ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1917ece92f85SJason Jin u32 *destreg,*srcreg; 1918ece92f85SJason Jin 1919ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 1920ece92f85SJason Jin DECODE_PRINTF(","); 1921ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rh); 1922ece92f85SJason Jin DECODE_PRINTF("\n"); 1923ece92f85SJason Jin TRACE_AND_STEP(); 1924ece92f85SJason Jin *destreg = *srcreg; 1925ece92f85SJason Jin } else { 1926ece92f85SJason Jin u16 *destreg,*srcreg; 1927ece92f85SJason Jin 1928ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 1929ece92f85SJason Jin DECODE_PRINTF(","); 1930ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh); 1931ece92f85SJason Jin DECODE_PRINTF("\n"); 1932ece92f85SJason Jin TRACE_AND_STEP(); 1933ece92f85SJason Jin *destreg = *srcreg; 1934ece92f85SJason Jin } 1935ece92f85SJason Jin } 1936ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1937ece92f85SJason Jin END_OF_INSTR(); 1938ece92f85SJason Jin } 1939ece92f85SJason Jin 1940ece92f85SJason Jin /**************************************************************************** 1941ece92f85SJason Jin REMARKS: 1942ece92f85SJason Jin Handles opcode 0x8a 1943ece92f85SJason Jin ****************************************************************************/ 1944ece92f85SJason Jin void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1)) 1945ece92f85SJason Jin { 1946ece92f85SJason Jin int mod, rl, rh; 1947ece92f85SJason Jin u8 *destreg, *srcreg; 1948ece92f85SJason Jin uint srcoffset; 1949ece92f85SJason Jin u8 srcval; 1950ece92f85SJason Jin 1951ece92f85SJason Jin START_OF_INSTR(); 1952ece92f85SJason Jin DECODE_PRINTF("MOV\t"); 1953ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1954ece92f85SJason Jin if (mod < 3) { 1955ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rh); 1956ece92f85SJason Jin DECODE_PRINTF(","); 1957ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 1958ece92f85SJason Jin srcval = fetch_data_byte(srcoffset); 1959ece92f85SJason Jin DECODE_PRINTF("\n"); 1960ece92f85SJason Jin TRACE_AND_STEP(); 1961ece92f85SJason Jin *destreg = srcval; 1962ece92f85SJason Jin } else { /* register to register */ 1963ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rh); 1964ece92f85SJason Jin DECODE_PRINTF(","); 1965ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rl); 1966ece92f85SJason Jin DECODE_PRINTF("\n"); 1967ece92f85SJason Jin TRACE_AND_STEP(); 1968ece92f85SJason Jin *destreg = *srcreg; 1969ece92f85SJason Jin } 1970ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1971ece92f85SJason Jin END_OF_INSTR(); 1972ece92f85SJason Jin } 1973ece92f85SJason Jin 1974ece92f85SJason Jin /**************************************************************************** 1975ece92f85SJason Jin REMARKS: 1976ece92f85SJason Jin Handles opcode 0x8b 1977ece92f85SJason Jin ****************************************************************************/ 1978ece92f85SJason Jin void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1)) 1979ece92f85SJason Jin { 1980ece92f85SJason Jin int mod, rl, rh; 1981ece92f85SJason Jin uint srcoffset; 1982ece92f85SJason Jin 1983ece92f85SJason Jin START_OF_INSTR(); 1984ece92f85SJason Jin DECODE_PRINTF("MOV\t"); 1985ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1986ece92f85SJason Jin if (mod < 3) { 1987ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1988ece92f85SJason Jin u32 *destreg; 1989ece92f85SJason Jin u32 srcval; 1990ece92f85SJason Jin 1991ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh); 1992ece92f85SJason Jin DECODE_PRINTF(","); 1993ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 1994ece92f85SJason Jin srcval = fetch_data_long(srcoffset); 1995ece92f85SJason Jin DECODE_PRINTF("\n"); 1996ece92f85SJason Jin TRACE_AND_STEP(); 1997ece92f85SJason Jin *destreg = srcval; 1998ece92f85SJason Jin } else { 1999ece92f85SJason Jin u16 *destreg; 2000ece92f85SJason Jin u16 srcval; 2001ece92f85SJason Jin 2002ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh); 2003ece92f85SJason Jin DECODE_PRINTF(","); 2004ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 2005ece92f85SJason Jin srcval = fetch_data_word(srcoffset); 2006ece92f85SJason Jin DECODE_PRINTF("\n"); 2007ece92f85SJason Jin TRACE_AND_STEP(); 2008ece92f85SJason Jin *destreg = srcval; 2009ece92f85SJason Jin } 2010ece92f85SJason Jin } else { /* register to register */ 2011ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2012ece92f85SJason Jin u32 *destreg, *srcreg; 2013ece92f85SJason Jin 2014ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh); 2015ece92f85SJason Jin DECODE_PRINTF(","); 2016ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl); 2017ece92f85SJason Jin DECODE_PRINTF("\n"); 2018ece92f85SJason Jin TRACE_AND_STEP(); 2019ece92f85SJason Jin *destreg = *srcreg; 2020ece92f85SJason Jin } else { 2021ece92f85SJason Jin u16 *destreg, *srcreg; 2022ece92f85SJason Jin 2023ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh); 2024ece92f85SJason Jin DECODE_PRINTF(","); 2025ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl); 2026ece92f85SJason Jin DECODE_PRINTF("\n"); 2027ece92f85SJason Jin TRACE_AND_STEP(); 2028ece92f85SJason Jin *destreg = *srcreg; 2029ece92f85SJason Jin } 2030ece92f85SJason Jin } 2031ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2032ece92f85SJason Jin END_OF_INSTR(); 2033ece92f85SJason Jin } 2034ece92f85SJason Jin 2035ece92f85SJason Jin /**************************************************************************** 2036ece92f85SJason Jin REMARKS: 2037ece92f85SJason Jin Handles opcode 0x8c 2038ece92f85SJason Jin ****************************************************************************/ 2039ece92f85SJason Jin void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1)) 2040ece92f85SJason Jin { 2041ece92f85SJason Jin int mod, rl, rh; 2042ece92f85SJason Jin u16 *destreg, *srcreg; 2043ece92f85SJason Jin uint destoffset; 2044ece92f85SJason Jin u16 destval; 2045ece92f85SJason Jin 2046ece92f85SJason Jin START_OF_INSTR(); 2047ece92f85SJason Jin DECODE_PRINTF("MOV\t"); 2048ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 2049ece92f85SJason Jin if (mod < 3) { 2050ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 2051ece92f85SJason Jin DECODE_PRINTF(","); 2052ece92f85SJason Jin srcreg = decode_rm_seg_register(rh); 2053ece92f85SJason Jin DECODE_PRINTF("\n"); 2054ece92f85SJason Jin TRACE_AND_STEP(); 2055ece92f85SJason Jin destval = *srcreg; 2056ece92f85SJason Jin store_data_word(destoffset, destval); 2057ece92f85SJason Jin } else { /* register to register */ 2058ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 2059ece92f85SJason Jin DECODE_PRINTF(","); 2060ece92f85SJason Jin srcreg = decode_rm_seg_register(rh); 2061ece92f85SJason Jin DECODE_PRINTF("\n"); 2062ece92f85SJason Jin TRACE_AND_STEP(); 2063ece92f85SJason Jin *destreg = *srcreg; 2064ece92f85SJason Jin } 2065ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2066ece92f85SJason Jin END_OF_INSTR(); 2067ece92f85SJason Jin } 2068ece92f85SJason Jin 2069ece92f85SJason Jin /**************************************************************************** 2070ece92f85SJason Jin REMARKS: 2071ece92f85SJason Jin Handles opcode 0x8d 2072ece92f85SJason Jin ****************************************************************************/ 2073ece92f85SJason Jin void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1)) 2074ece92f85SJason Jin { 2075ece92f85SJason Jin int mod, rl, rh; 2076ece92f85SJason Jin u16 *srcreg; 2077ece92f85SJason Jin uint destoffset; 2078ece92f85SJason Jin 2079ece92f85SJason Jin /* 2080ece92f85SJason Jin * TODO: Need to handle address size prefix! 2081ece92f85SJason Jin * 2082ece92f85SJason Jin * lea eax,[eax+ebx*2] ?? 2083ece92f85SJason Jin */ 2084ece92f85SJason Jin 2085ece92f85SJason Jin START_OF_INSTR(); 2086ece92f85SJason Jin DECODE_PRINTF("LEA\t"); 2087ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 2088ece92f85SJason Jin if (mod < 3) { 2089ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rh); 2090ece92f85SJason Jin DECODE_PRINTF(","); 2091ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 2092ece92f85SJason Jin DECODE_PRINTF("\n"); 2093ece92f85SJason Jin TRACE_AND_STEP(); 2094ece92f85SJason Jin *srcreg = (u16)destoffset; 2095ece92f85SJason Jin } 2096ece92f85SJason Jin /* } else { undefined. Do nothing. } */ 2097ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2098ece92f85SJason Jin END_OF_INSTR(); 2099ece92f85SJason Jin } 2100ece92f85SJason Jin 2101ece92f85SJason Jin /**************************************************************************** 2102ece92f85SJason Jin REMARKS: 2103ece92f85SJason Jin Handles opcode 0x8e 2104ece92f85SJason Jin ****************************************************************************/ 2105ece92f85SJason Jin void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1)) 2106ece92f85SJason Jin { 2107ece92f85SJason Jin int mod, rl, rh; 2108ece92f85SJason Jin u16 *destreg, *srcreg; 2109ece92f85SJason Jin uint srcoffset; 2110ece92f85SJason Jin u16 srcval; 2111ece92f85SJason Jin 2112ece92f85SJason Jin START_OF_INSTR(); 2113ece92f85SJason Jin DECODE_PRINTF("MOV\t"); 2114ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 2115ece92f85SJason Jin if (mod < 3) { 2116ece92f85SJason Jin destreg = decode_rm_seg_register(rh); 2117ece92f85SJason Jin DECODE_PRINTF(","); 2118ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 2119ece92f85SJason Jin srcval = fetch_data_word(srcoffset); 2120ece92f85SJason Jin DECODE_PRINTF("\n"); 2121ece92f85SJason Jin TRACE_AND_STEP(); 2122ece92f85SJason Jin *destreg = srcval; 2123ece92f85SJason Jin } else { /* register to register */ 2124ece92f85SJason Jin destreg = decode_rm_seg_register(rh); 2125ece92f85SJason Jin DECODE_PRINTF(","); 2126ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl); 2127ece92f85SJason Jin DECODE_PRINTF("\n"); 2128ece92f85SJason Jin TRACE_AND_STEP(); 2129ece92f85SJason Jin *destreg = *srcreg; 2130ece92f85SJason Jin } 2131ece92f85SJason Jin /* 2132ece92f85SJason Jin * Clean up, and reset all the R_xSP pointers to the correct 2133ece92f85SJason Jin * locations. This is about 3x too much overhead (doing all the 2134ece92f85SJason Jin * segreg ptrs when only one is needed, but this instruction 2135ece92f85SJason Jin * *cannot* be that common, and this isn't too much work anyway. 2136ece92f85SJason Jin */ 2137ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2138ece92f85SJason Jin END_OF_INSTR(); 2139ece92f85SJason Jin } 2140ece92f85SJason Jin 2141ece92f85SJason Jin /**************************************************************************** 2142ece92f85SJason Jin REMARKS: 2143ece92f85SJason Jin Handles opcode 0x8f 2144ece92f85SJason Jin ****************************************************************************/ 2145ece92f85SJason Jin void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1)) 2146ece92f85SJason Jin { 2147ece92f85SJason Jin int mod, rl, rh; 2148ece92f85SJason Jin uint destoffset; 2149ece92f85SJason Jin 2150ece92f85SJason Jin START_OF_INSTR(); 2151ece92f85SJason Jin DECODE_PRINTF("POP\t"); 2152ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 2153ece92f85SJason Jin if (rh != 0) { 2154ece92f85SJason Jin DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); 2155ece92f85SJason Jin HALT_SYS(); 2156ece92f85SJason Jin } 2157ece92f85SJason Jin if (mod < 3) { 2158ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 2159ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2160ece92f85SJason Jin u32 destval; 2161ece92f85SJason Jin 2162ece92f85SJason Jin DECODE_PRINTF("\n"); 2163ece92f85SJason Jin TRACE_AND_STEP(); 2164ece92f85SJason Jin destval = pop_long(); 2165ece92f85SJason Jin store_data_long(destoffset, destval); 2166ece92f85SJason Jin } else { 2167ece92f85SJason Jin u16 destval; 2168ece92f85SJason Jin 2169ece92f85SJason Jin DECODE_PRINTF("\n"); 2170ece92f85SJason Jin TRACE_AND_STEP(); 2171ece92f85SJason Jin destval = pop_word(); 2172ece92f85SJason Jin store_data_word(destoffset, destval); 2173ece92f85SJason Jin } 2174ece92f85SJason Jin } else { /* register to register */ 2175ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2176ece92f85SJason Jin u32 *destreg; 2177ece92f85SJason Jin 2178ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 2179ece92f85SJason Jin DECODE_PRINTF("\n"); 2180ece92f85SJason Jin TRACE_AND_STEP(); 2181ece92f85SJason Jin *destreg = pop_long(); 2182ece92f85SJason Jin } else { 2183ece92f85SJason Jin u16 *destreg; 2184ece92f85SJason Jin 2185ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 2186ece92f85SJason Jin DECODE_PRINTF("\n"); 2187ece92f85SJason Jin TRACE_AND_STEP(); 2188ece92f85SJason Jin *destreg = pop_word(); 2189ece92f85SJason Jin } 2190ece92f85SJason Jin } 2191ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2192ece92f85SJason Jin END_OF_INSTR(); 2193ece92f85SJason Jin } 2194ece92f85SJason Jin 2195ece92f85SJason Jin /**************************************************************************** 2196ece92f85SJason Jin REMARKS: 2197ece92f85SJason Jin Handles opcode 0x90 2198ece92f85SJason Jin ****************************************************************************/ 2199ece92f85SJason Jin void x86emuOp_nop(u8 X86EMU_UNUSED(op1)) 2200ece92f85SJason Jin { 2201ece92f85SJason Jin START_OF_INSTR(); 2202ece92f85SJason Jin DECODE_PRINTF("NOP\n"); 2203ece92f85SJason Jin TRACE_AND_STEP(); 2204ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2205ece92f85SJason Jin END_OF_INSTR(); 2206ece92f85SJason Jin } 2207ece92f85SJason Jin 2208ece92f85SJason Jin /**************************************************************************** 2209ece92f85SJason Jin REMARKS: 2210ece92f85SJason Jin Handles opcode 0x91-0x97 2211ece92f85SJason Jin ****************************************************************************/ 2212ece92f85SJason Jin void x86emuOp_xchg_word_AX_register(u8 X86EMU_UNUSED(op1)) 2213ece92f85SJason Jin { 2214ece92f85SJason Jin u32 tmp; 2215ece92f85SJason Jin 2216ece92f85SJason Jin op1 &= 0x7; 2217ece92f85SJason Jin 2218ece92f85SJason Jin START_OF_INSTR(); 2219ece92f85SJason Jin 2220ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2221ece92f85SJason Jin u32 *reg32; 2222ece92f85SJason Jin DECODE_PRINTF("XCHG\tEAX,"); 2223ece92f85SJason Jin reg32 = DECODE_RM_LONG_REGISTER(op1); 2224ece92f85SJason Jin DECODE_PRINTF("\n"); 2225ece92f85SJason Jin TRACE_AND_STEP(); 2226ece92f85SJason Jin tmp = M.x86.R_EAX; 2227ece92f85SJason Jin M.x86.R_EAX = *reg32; 2228ece92f85SJason Jin *reg32 = tmp; 2229ece92f85SJason Jin } else { 2230ece92f85SJason Jin u16 *reg16; 2231ece92f85SJason Jin DECODE_PRINTF("XCHG\tAX,"); 2232ece92f85SJason Jin reg16 = DECODE_RM_WORD_REGISTER(op1); 2233ece92f85SJason Jin DECODE_PRINTF("\n"); 2234ece92f85SJason Jin TRACE_AND_STEP(); 2235ece92f85SJason Jin tmp = M.x86.R_AX; 2236ece92f85SJason Jin M.x86.R_EAX = *reg16; 2237ece92f85SJason Jin *reg16 = (u16)tmp; 2238ece92f85SJason Jin } 2239ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2240ece92f85SJason Jin END_OF_INSTR(); 2241ece92f85SJason Jin } 2242ece92f85SJason Jin 2243ece92f85SJason Jin /**************************************************************************** 2244ece92f85SJason Jin REMARKS: 2245ece92f85SJason Jin Handles opcode 0x98 2246ece92f85SJason Jin ****************************************************************************/ 2247ece92f85SJason Jin void x86emuOp_cbw(u8 X86EMU_UNUSED(op1)) 2248ece92f85SJason Jin { 2249ece92f85SJason Jin START_OF_INSTR(); 2250ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2251ece92f85SJason Jin DECODE_PRINTF("CWDE\n"); 2252ece92f85SJason Jin } else { 2253ece92f85SJason Jin DECODE_PRINTF("CBW\n"); 2254ece92f85SJason Jin } 2255ece92f85SJason Jin TRACE_AND_STEP(); 2256ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2257ece92f85SJason Jin if (M.x86.R_AX & 0x8000) { 2258ece92f85SJason Jin M.x86.R_EAX |= 0xffff0000; 2259ece92f85SJason Jin } else { 2260ece92f85SJason Jin M.x86.R_EAX &= 0x0000ffff; 2261ece92f85SJason Jin } 2262ece92f85SJason Jin } else { 2263ece92f85SJason Jin if (M.x86.R_AL & 0x80) { 2264ece92f85SJason Jin M.x86.R_AH = 0xff; 2265ece92f85SJason Jin } else { 2266ece92f85SJason Jin M.x86.R_AH = 0x0; 2267ece92f85SJason Jin } 2268ece92f85SJason Jin } 2269ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2270ece92f85SJason Jin END_OF_INSTR(); 2271ece92f85SJason Jin } 2272ece92f85SJason Jin 2273ece92f85SJason Jin /**************************************************************************** 2274ece92f85SJason Jin REMARKS: 2275ece92f85SJason Jin Handles opcode 0x99 2276ece92f85SJason Jin ****************************************************************************/ 2277ece92f85SJason Jin void x86emuOp_cwd(u8 X86EMU_UNUSED(op1)) 2278ece92f85SJason Jin { 2279ece92f85SJason Jin START_OF_INSTR(); 2280ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2281ece92f85SJason Jin DECODE_PRINTF("CDQ\n"); 2282ece92f85SJason Jin } else { 2283ece92f85SJason Jin DECODE_PRINTF("CWD\n"); 2284ece92f85SJason Jin } 2285ece92f85SJason Jin DECODE_PRINTF("CWD\n"); 2286ece92f85SJason Jin TRACE_AND_STEP(); 2287ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2288ece92f85SJason Jin if (M.x86.R_EAX & 0x80000000) { 2289ece92f85SJason Jin M.x86.R_EDX = 0xffffffff; 2290ece92f85SJason Jin } else { 2291ece92f85SJason Jin M.x86.R_EDX = 0x0; 2292ece92f85SJason Jin } 2293ece92f85SJason Jin } else { 2294ece92f85SJason Jin if (M.x86.R_AX & 0x8000) { 2295ece92f85SJason Jin M.x86.R_DX = 0xffff; 2296ece92f85SJason Jin } else { 2297ece92f85SJason Jin M.x86.R_DX = 0x0; 2298ece92f85SJason Jin } 2299ece92f85SJason Jin } 2300ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2301ece92f85SJason Jin END_OF_INSTR(); 2302ece92f85SJason Jin } 2303ece92f85SJason Jin 2304ece92f85SJason Jin /**************************************************************************** 2305ece92f85SJason Jin REMARKS: 2306ece92f85SJason Jin Handles opcode 0x9a 2307ece92f85SJason Jin ****************************************************************************/ 2308ece92f85SJason Jin void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1)) 2309ece92f85SJason Jin { 2310ece92f85SJason Jin u16 farseg, faroff; 2311ece92f85SJason Jin 2312ece92f85SJason Jin START_OF_INSTR(); 2313ece92f85SJason Jin DECODE_PRINTF("CALL\t"); 2314ece92f85SJason Jin faroff = fetch_word_imm(); 2315ece92f85SJason Jin farseg = fetch_word_imm(); 2316ece92f85SJason Jin DECODE_PRINTF2("%04x:", farseg); 2317ece92f85SJason Jin DECODE_PRINTF2("%04x\n", faroff); 2318ece92f85SJason Jin CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR "); 2319ece92f85SJason Jin 2320ece92f85SJason Jin /* XXX 2321ece92f85SJason Jin * 2322ece92f85SJason Jin * Hooked interrupt vectors calling into our "BIOS" will cause 2323ece92f85SJason Jin * problems unless all intersegment stuff is checked for BIOS 2324ece92f85SJason Jin * access. Check needed here. For moment, let it alone. 2325ece92f85SJason Jin */ 2326ece92f85SJason Jin TRACE_AND_STEP(); 2327ece92f85SJason Jin push_word(M.x86.R_CS); 2328ece92f85SJason Jin M.x86.R_CS = farseg; 2329ece92f85SJason Jin push_word(M.x86.R_IP); 2330ece92f85SJason Jin M.x86.R_IP = faroff; 2331ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2332ece92f85SJason Jin END_OF_INSTR(); 2333ece92f85SJason Jin } 2334ece92f85SJason Jin 2335ece92f85SJason Jin /**************************************************************************** 2336ece92f85SJason Jin REMARKS: 2337ece92f85SJason Jin Handles opcode 0x9b 2338ece92f85SJason Jin ****************************************************************************/ 2339ece92f85SJason Jin void x86emuOp_wait(u8 X86EMU_UNUSED(op1)) 2340ece92f85SJason Jin { 2341ece92f85SJason Jin START_OF_INSTR(); 2342ece92f85SJason Jin DECODE_PRINTF("WAIT"); 2343ece92f85SJason Jin TRACE_AND_STEP(); 2344ece92f85SJason Jin /* NADA. */ 2345ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2346ece92f85SJason Jin END_OF_INSTR(); 2347ece92f85SJason Jin } 2348ece92f85SJason Jin 2349ece92f85SJason Jin /**************************************************************************** 2350ece92f85SJason Jin REMARKS: 2351ece92f85SJason Jin Handles opcode 0x9c 2352ece92f85SJason Jin ****************************************************************************/ 2353ece92f85SJason Jin void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1)) 2354ece92f85SJason Jin { 2355ece92f85SJason Jin u32 flags; 2356ece92f85SJason Jin 2357ece92f85SJason Jin START_OF_INSTR(); 2358ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2359ece92f85SJason Jin DECODE_PRINTF("PUSHFD\n"); 2360ece92f85SJason Jin } else { 2361ece92f85SJason Jin DECODE_PRINTF("PUSHF\n"); 2362ece92f85SJason Jin } 2363ece92f85SJason Jin TRACE_AND_STEP(); 2364ece92f85SJason Jin 2365ece92f85SJason Jin /* clear out *all* bits not representing flags, and turn on real bits */ 2366ece92f85SJason Jin flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON; 2367ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2368ece92f85SJason Jin push_long(flags); 2369ece92f85SJason Jin } else { 2370ece92f85SJason Jin push_word((u16)flags); 2371ece92f85SJason Jin } 2372ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2373ece92f85SJason Jin END_OF_INSTR(); 2374ece92f85SJason Jin } 2375ece92f85SJason Jin 2376ece92f85SJason Jin /**************************************************************************** 2377ece92f85SJason Jin REMARKS: 2378ece92f85SJason Jin Handles opcode 0x9d 2379ece92f85SJason Jin ****************************************************************************/ 2380ece92f85SJason Jin void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1)) 2381ece92f85SJason Jin { 2382ece92f85SJason Jin START_OF_INSTR(); 2383ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2384ece92f85SJason Jin DECODE_PRINTF("POPFD\n"); 2385ece92f85SJason Jin } else { 2386ece92f85SJason Jin DECODE_PRINTF("POPF\n"); 2387ece92f85SJason Jin } 2388ece92f85SJason Jin TRACE_AND_STEP(); 2389ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2390ece92f85SJason Jin M.x86.R_EFLG = pop_long(); 2391ece92f85SJason Jin } else { 2392ece92f85SJason Jin M.x86.R_FLG = pop_word(); 2393ece92f85SJason Jin } 2394ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2395ece92f85SJason Jin END_OF_INSTR(); 2396ece92f85SJason Jin } 2397ece92f85SJason Jin 2398ece92f85SJason Jin /**************************************************************************** 2399ece92f85SJason Jin REMARKS: 2400ece92f85SJason Jin Handles opcode 0x9e 2401ece92f85SJason Jin ****************************************************************************/ 2402ece92f85SJason Jin void x86emuOp_sahf(u8 X86EMU_UNUSED(op1)) 2403ece92f85SJason Jin { 2404ece92f85SJason Jin START_OF_INSTR(); 2405ece92f85SJason Jin DECODE_PRINTF("SAHF\n"); 2406ece92f85SJason Jin TRACE_AND_STEP(); 2407ece92f85SJason Jin /* clear the lower bits of the flag register */ 2408ece92f85SJason Jin M.x86.R_FLG &= 0xffffff00; 2409ece92f85SJason Jin /* or in the AH register into the flags register */ 2410ece92f85SJason Jin M.x86.R_FLG |= M.x86.R_AH; 2411ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2412ece92f85SJason Jin END_OF_INSTR(); 2413ece92f85SJason Jin } 2414ece92f85SJason Jin 2415ece92f85SJason Jin /**************************************************************************** 2416ece92f85SJason Jin REMARKS: 2417ece92f85SJason Jin Handles opcode 0x9f 2418ece92f85SJason Jin ****************************************************************************/ 2419ece92f85SJason Jin void x86emuOp_lahf(u8 X86EMU_UNUSED(op1)) 2420ece92f85SJason Jin { 2421ece92f85SJason Jin START_OF_INSTR(); 2422ece92f85SJason Jin DECODE_PRINTF("LAHF\n"); 2423ece92f85SJason Jin TRACE_AND_STEP(); 2424ece92f85SJason Jin M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff); 2425ece92f85SJason Jin /*undocumented TC++ behavior??? Nope. It's documented, but 2426ece92f85SJason Jin you have too look real hard to notice it. */ 2427ece92f85SJason Jin M.x86.R_AH |= 0x2; 2428ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2429ece92f85SJason Jin END_OF_INSTR(); 2430ece92f85SJason Jin } 2431ece92f85SJason Jin 2432ece92f85SJason Jin /**************************************************************************** 2433ece92f85SJason Jin REMARKS: 2434ece92f85SJason Jin Handles opcode 0xa0 2435ece92f85SJason Jin ****************************************************************************/ 2436ece92f85SJason Jin void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1)) 2437ece92f85SJason Jin { 2438ece92f85SJason Jin u16 offset; 2439ece92f85SJason Jin 2440ece92f85SJason Jin START_OF_INSTR(); 2441ece92f85SJason Jin DECODE_PRINTF("MOV\tAL,"); 2442ece92f85SJason Jin offset = fetch_word_imm(); 2443ece92f85SJason Jin DECODE_PRINTF2("[%04x]\n", offset); 2444ece92f85SJason Jin TRACE_AND_STEP(); 2445ece92f85SJason Jin M.x86.R_AL = fetch_data_byte(offset); 2446ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2447ece92f85SJason Jin END_OF_INSTR(); 2448ece92f85SJason Jin } 2449ece92f85SJason Jin 2450ece92f85SJason Jin /**************************************************************************** 2451ece92f85SJason Jin REMARKS: 2452ece92f85SJason Jin Handles opcode 0xa1 2453ece92f85SJason Jin ****************************************************************************/ 2454ece92f85SJason Jin void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1)) 2455ece92f85SJason Jin { 2456ece92f85SJason Jin u16 offset; 2457ece92f85SJason Jin 2458ece92f85SJason Jin START_OF_INSTR(); 2459ece92f85SJason Jin offset = fetch_word_imm(); 2460ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2461ece92f85SJason Jin DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset); 2462ece92f85SJason Jin } else { 2463ece92f85SJason Jin DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset); 2464ece92f85SJason Jin } 2465ece92f85SJason Jin TRACE_AND_STEP(); 2466ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2467ece92f85SJason Jin M.x86.R_EAX = fetch_data_long(offset); 2468ece92f85SJason Jin } else { 2469ece92f85SJason Jin M.x86.R_AX = fetch_data_word(offset); 2470ece92f85SJason Jin } 2471ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2472ece92f85SJason Jin END_OF_INSTR(); 2473ece92f85SJason Jin } 2474ece92f85SJason Jin 2475ece92f85SJason Jin /**************************************************************************** 2476ece92f85SJason Jin REMARKS: 2477ece92f85SJason Jin Handles opcode 0xa2 2478ece92f85SJason Jin ****************************************************************************/ 2479ece92f85SJason Jin void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1)) 2480ece92f85SJason Jin { 2481ece92f85SJason Jin u16 offset; 2482ece92f85SJason Jin 2483ece92f85SJason Jin START_OF_INSTR(); 2484ece92f85SJason Jin DECODE_PRINTF("MOV\t"); 2485ece92f85SJason Jin offset = fetch_word_imm(); 2486ece92f85SJason Jin DECODE_PRINTF2("[%04x],AL\n", offset); 2487ece92f85SJason Jin TRACE_AND_STEP(); 2488ece92f85SJason Jin store_data_byte(offset, M.x86.R_AL); 2489ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2490ece92f85SJason Jin END_OF_INSTR(); 2491ece92f85SJason Jin } 2492ece92f85SJason Jin 2493ece92f85SJason Jin /**************************************************************************** 2494ece92f85SJason Jin REMARKS: 2495ece92f85SJason Jin Handles opcode 0xa3 2496ece92f85SJason Jin ****************************************************************************/ 2497ece92f85SJason Jin void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1)) 2498ece92f85SJason Jin { 2499ece92f85SJason Jin u16 offset; 2500ece92f85SJason Jin 2501ece92f85SJason Jin START_OF_INSTR(); 2502ece92f85SJason Jin offset = fetch_word_imm(); 2503ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2504ece92f85SJason Jin DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset); 2505ece92f85SJason Jin } else { 2506ece92f85SJason Jin DECODE_PRINTF2("MOV\t[%04x],AX\n", offset); 2507ece92f85SJason Jin } 2508ece92f85SJason Jin TRACE_AND_STEP(); 2509ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2510ece92f85SJason Jin store_data_long(offset, M.x86.R_EAX); 2511ece92f85SJason Jin } else { 2512ece92f85SJason Jin store_data_word(offset, M.x86.R_AX); 2513ece92f85SJason Jin } 2514ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2515ece92f85SJason Jin END_OF_INSTR(); 2516ece92f85SJason Jin } 2517ece92f85SJason Jin 2518ece92f85SJason Jin /**************************************************************************** 2519ece92f85SJason Jin REMARKS: 2520ece92f85SJason Jin Handles opcode 0xa4 2521ece92f85SJason Jin ****************************************************************************/ 2522ece92f85SJason Jin void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1)) 2523ece92f85SJason Jin { 2524ece92f85SJason Jin u8 val; 2525ece92f85SJason Jin u32 count; 2526ece92f85SJason Jin int inc; 2527ece92f85SJason Jin 2528ece92f85SJason Jin START_OF_INSTR(); 2529ece92f85SJason Jin DECODE_PRINTF("MOVS\tBYTE\n"); 2530ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */ 2531ece92f85SJason Jin inc = -1; 2532ece92f85SJason Jin else 2533ece92f85SJason Jin inc = 1; 2534ece92f85SJason Jin TRACE_AND_STEP(); 2535ece92f85SJason Jin count = 1; 2536ece92f85SJason Jin if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 2537ece92f85SJason Jin /* dont care whether REPE or REPNE */ 2538ece92f85SJason Jin /* move them until CX is ZERO. */ 2539ece92f85SJason Jin count = M.x86.R_CX; 2540ece92f85SJason Jin M.x86.R_CX = 0; 2541ece92f85SJason Jin M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 2542ece92f85SJason Jin } 2543ece92f85SJason Jin while (count--) { 2544ece92f85SJason Jin val = fetch_data_byte(M.x86.R_SI); 2545ece92f85SJason Jin store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val); 2546ece92f85SJason Jin M.x86.R_SI += inc; 2547ece92f85SJason Jin M.x86.R_DI += inc; 2548ece92f85SJason Jin } 2549ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2550ece92f85SJason Jin END_OF_INSTR(); 2551ece92f85SJason Jin } 2552ece92f85SJason Jin 2553ece92f85SJason Jin /**************************************************************************** 2554ece92f85SJason Jin REMARKS: 2555ece92f85SJason Jin Handles opcode 0xa5 2556ece92f85SJason Jin ****************************************************************************/ 2557ece92f85SJason Jin void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1)) 2558ece92f85SJason Jin { 2559ece92f85SJason Jin u32 val; 2560ece92f85SJason Jin int inc; 2561ece92f85SJason Jin u32 count; 2562ece92f85SJason Jin 2563ece92f85SJason Jin START_OF_INSTR(); 2564ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2565ece92f85SJason Jin DECODE_PRINTF("MOVS\tDWORD\n"); 2566ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */ 2567ece92f85SJason Jin inc = -4; 2568ece92f85SJason Jin else 2569ece92f85SJason Jin inc = 4; 2570ece92f85SJason Jin } else { 2571ece92f85SJason Jin DECODE_PRINTF("MOVS\tWORD\n"); 2572ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */ 2573ece92f85SJason Jin inc = -2; 2574ece92f85SJason Jin else 2575ece92f85SJason Jin inc = 2; 2576ece92f85SJason Jin } 2577ece92f85SJason Jin TRACE_AND_STEP(); 2578ece92f85SJason Jin count = 1; 2579ece92f85SJason Jin if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 2580ece92f85SJason Jin /* dont care whether REPE or REPNE */ 2581ece92f85SJason Jin /* move them until CX is ZERO. */ 2582ece92f85SJason Jin count = M.x86.R_CX; 2583ece92f85SJason Jin M.x86.R_CX = 0; 2584ece92f85SJason Jin M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 2585ece92f85SJason Jin } 2586ece92f85SJason Jin while (count--) { 2587ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2588ece92f85SJason Jin val = fetch_data_long(M.x86.R_SI); 2589ece92f85SJason Jin store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val); 2590ece92f85SJason Jin } else { 2591ece92f85SJason Jin val = fetch_data_word(M.x86.R_SI); 2592ece92f85SJason Jin store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val); 2593ece92f85SJason Jin } 2594ece92f85SJason Jin M.x86.R_SI += inc; 2595ece92f85SJason Jin M.x86.R_DI += inc; 2596ece92f85SJason Jin } 2597ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2598ece92f85SJason Jin END_OF_INSTR(); 2599ece92f85SJason Jin } 2600ece92f85SJason Jin 2601ece92f85SJason Jin /**************************************************************************** 2602ece92f85SJason Jin REMARKS: 2603ece92f85SJason Jin Handles opcode 0xa6 2604ece92f85SJason Jin ****************************************************************************/ 2605ece92f85SJason Jin void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1)) 2606ece92f85SJason Jin { 2607ece92f85SJason Jin s8 val1, val2; 2608ece92f85SJason Jin int inc; 2609ece92f85SJason Jin 2610ece92f85SJason Jin START_OF_INSTR(); 2611ece92f85SJason Jin DECODE_PRINTF("CMPS\tBYTE\n"); 2612ece92f85SJason Jin TRACE_AND_STEP(); 2613ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */ 2614ece92f85SJason Jin inc = -1; 2615ece92f85SJason Jin else 2616ece92f85SJason Jin inc = 1; 2617ece92f85SJason Jin 2618ece92f85SJason Jin if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 2619ece92f85SJason Jin /* REPE */ 2620ece92f85SJason Jin /* move them until CX is ZERO. */ 2621ece92f85SJason Jin while (M.x86.R_CX != 0) { 2622ece92f85SJason Jin val1 = fetch_data_byte(M.x86.R_SI); 2623ece92f85SJason Jin val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 2624ece92f85SJason Jin cmp_byte(val1, val2); 2625ece92f85SJason Jin M.x86.R_CX -= 1; 2626ece92f85SJason Jin M.x86.R_SI += inc; 2627ece92f85SJason Jin M.x86.R_DI += inc; 2628ece92f85SJason Jin if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && (ACCESS_FLAG(F_ZF) == 0) ) break; 2629ece92f85SJason Jin if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break; 2630ece92f85SJason Jin } 2631ece92f85SJason Jin M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 2632ece92f85SJason Jin } else { 2633ece92f85SJason Jin val1 = fetch_data_byte(M.x86.R_SI); 2634ece92f85SJason Jin val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 2635ece92f85SJason Jin cmp_byte(val1, val2); 2636ece92f85SJason Jin M.x86.R_SI += inc; 2637ece92f85SJason Jin M.x86.R_DI += inc; 2638ece92f85SJason Jin } 2639ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2640ece92f85SJason Jin END_OF_INSTR(); 2641ece92f85SJason Jin } 2642ece92f85SJason Jin 2643ece92f85SJason Jin /**************************************************************************** 2644ece92f85SJason Jin REMARKS: 2645ece92f85SJason Jin Handles opcode 0xa7 2646ece92f85SJason Jin ****************************************************************************/ 2647ece92f85SJason Jin void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1)) 2648ece92f85SJason Jin { 2649ece92f85SJason Jin u32 val1,val2; 2650ece92f85SJason Jin int inc; 2651ece92f85SJason Jin 2652ece92f85SJason Jin START_OF_INSTR(); 2653ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2654ece92f85SJason Jin DECODE_PRINTF("CMPS\tDWORD\n"); 2655ece92f85SJason Jin inc = 4; 2656ece92f85SJason Jin } else { 2657ece92f85SJason Jin DECODE_PRINTF("CMPS\tWORD\n"); 2658ece92f85SJason Jin inc = 2; 2659ece92f85SJason Jin } 2660ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */ 2661ece92f85SJason Jin inc = -inc; 2662ece92f85SJason Jin 2663ece92f85SJason Jin TRACE_AND_STEP(); 2664ece92f85SJason Jin if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 2665ece92f85SJason Jin /* REPE */ 2666ece92f85SJason Jin /* move them until CX is ZERO. */ 2667ece92f85SJason Jin while (M.x86.R_CX != 0) { 2668ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2669ece92f85SJason Jin val1 = fetch_data_long(M.x86.R_SI); 2670ece92f85SJason Jin val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 2671ece92f85SJason Jin cmp_long(val1, val2); 2672ece92f85SJason Jin } else { 2673ece92f85SJason Jin val1 = fetch_data_word(M.x86.R_SI); 2674ece92f85SJason Jin val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 2675ece92f85SJason Jin cmp_word((u16)val1, (u16)val2); 2676ece92f85SJason Jin } 2677ece92f85SJason Jin M.x86.R_CX -= 1; 2678ece92f85SJason Jin M.x86.R_SI += inc; 2679ece92f85SJason Jin M.x86.R_DI += inc; 2680ece92f85SJason Jin if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && ACCESS_FLAG(F_ZF) == 0 ) break; 2681ece92f85SJason Jin if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break; 2682ece92f85SJason Jin } 2683ece92f85SJason Jin M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 2684ece92f85SJason Jin } else { 2685ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2686ece92f85SJason Jin val1 = fetch_data_long(M.x86.R_SI); 2687ece92f85SJason Jin val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 2688ece92f85SJason Jin cmp_long(val1, val2); 2689ece92f85SJason Jin } else { 2690ece92f85SJason Jin val1 = fetch_data_word(M.x86.R_SI); 2691ece92f85SJason Jin val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 2692ece92f85SJason Jin cmp_word((u16)val1, (u16)val2); 2693ece92f85SJason Jin } 2694ece92f85SJason Jin M.x86.R_SI += inc; 2695ece92f85SJason Jin M.x86.R_DI += inc; 2696ece92f85SJason Jin } 2697ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2698ece92f85SJason Jin END_OF_INSTR(); 2699ece92f85SJason Jin } 2700ece92f85SJason Jin 2701ece92f85SJason Jin /**************************************************************************** 2702ece92f85SJason Jin REMARKS: 2703ece92f85SJason Jin Handles opcode 0xa8 2704ece92f85SJason Jin ****************************************************************************/ 2705ece92f85SJason Jin void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1)) 2706ece92f85SJason Jin { 2707ece92f85SJason Jin int imm; 2708ece92f85SJason Jin 2709ece92f85SJason Jin START_OF_INSTR(); 2710ece92f85SJason Jin DECODE_PRINTF("TEST\tAL,"); 2711ece92f85SJason Jin imm = fetch_byte_imm(); 2712ece92f85SJason Jin DECODE_PRINTF2("%04x\n", imm); 2713ece92f85SJason Jin TRACE_AND_STEP(); 2714ece92f85SJason Jin test_byte(M.x86.R_AL, (u8)imm); 2715ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2716ece92f85SJason Jin END_OF_INSTR(); 2717ece92f85SJason Jin } 2718ece92f85SJason Jin 2719ece92f85SJason Jin /**************************************************************************** 2720ece92f85SJason Jin REMARKS: 2721ece92f85SJason Jin Handles opcode 0xa9 2722ece92f85SJason Jin ****************************************************************************/ 2723ece92f85SJason Jin void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1)) 2724ece92f85SJason Jin { 2725ece92f85SJason Jin u32 srcval; 2726ece92f85SJason Jin 2727ece92f85SJason Jin START_OF_INSTR(); 2728ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2729ece92f85SJason Jin DECODE_PRINTF("TEST\tEAX,"); 2730ece92f85SJason Jin srcval = fetch_long_imm(); 2731ece92f85SJason Jin } else { 2732ece92f85SJason Jin DECODE_PRINTF("TEST\tAX,"); 2733ece92f85SJason Jin srcval = fetch_word_imm(); 2734ece92f85SJason Jin } 2735ece92f85SJason Jin DECODE_PRINTF2("%x\n", srcval); 2736ece92f85SJason Jin TRACE_AND_STEP(); 2737ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2738ece92f85SJason Jin test_long(M.x86.R_EAX, srcval); 2739ece92f85SJason Jin } else { 2740ece92f85SJason Jin test_word(M.x86.R_AX, (u16)srcval); 2741ece92f85SJason Jin } 2742ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2743ece92f85SJason Jin END_OF_INSTR(); 2744ece92f85SJason Jin } 2745ece92f85SJason Jin 2746ece92f85SJason Jin /**************************************************************************** 2747ece92f85SJason Jin REMARKS: 2748ece92f85SJason Jin Handles opcode 0xaa 2749ece92f85SJason Jin ****************************************************************************/ 2750ece92f85SJason Jin void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1)) 2751ece92f85SJason Jin { 2752ece92f85SJason Jin int inc; 2753ece92f85SJason Jin 2754ece92f85SJason Jin START_OF_INSTR(); 2755ece92f85SJason Jin DECODE_PRINTF("STOS\tBYTE\n"); 2756ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */ 2757ece92f85SJason Jin inc = -1; 2758ece92f85SJason Jin else 2759ece92f85SJason Jin inc = 1; 2760ece92f85SJason Jin TRACE_AND_STEP(); 2761ece92f85SJason Jin if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 2762ece92f85SJason Jin /* dont care whether REPE or REPNE */ 2763ece92f85SJason Jin /* move them until CX is ZERO. */ 2764ece92f85SJason Jin while (M.x86.R_CX != 0) { 2765ece92f85SJason Jin store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); 2766ece92f85SJason Jin M.x86.R_CX -= 1; 2767ece92f85SJason Jin M.x86.R_DI += inc; 2768ece92f85SJason Jin } 2769ece92f85SJason Jin M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 2770ece92f85SJason Jin } else { 2771ece92f85SJason Jin store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL); 2772ece92f85SJason Jin M.x86.R_DI += inc; 2773ece92f85SJason Jin } 2774ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2775ece92f85SJason Jin END_OF_INSTR(); 2776ece92f85SJason Jin } 2777ece92f85SJason Jin 2778ece92f85SJason Jin /**************************************************************************** 2779ece92f85SJason Jin REMARKS: 2780ece92f85SJason Jin Handles opcode 0xab 2781ece92f85SJason Jin ****************************************************************************/ 2782ece92f85SJason Jin void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1)) 2783ece92f85SJason Jin { 2784ece92f85SJason Jin int inc; 2785ece92f85SJason Jin u32 count; 2786ece92f85SJason Jin 2787ece92f85SJason Jin START_OF_INSTR(); 2788ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2789ece92f85SJason Jin DECODE_PRINTF("STOS\tDWORD\n"); 2790ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */ 2791ece92f85SJason Jin inc = -4; 2792ece92f85SJason Jin else 2793ece92f85SJason Jin inc = 4; 2794ece92f85SJason Jin } else { 2795ece92f85SJason Jin DECODE_PRINTF("STOS\tWORD\n"); 2796ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */ 2797ece92f85SJason Jin inc = -2; 2798ece92f85SJason Jin else 2799ece92f85SJason Jin inc = 2; 2800ece92f85SJason Jin } 2801ece92f85SJason Jin TRACE_AND_STEP(); 2802ece92f85SJason Jin count = 1; 2803ece92f85SJason Jin if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 2804ece92f85SJason Jin /* dont care whether REPE or REPNE */ 2805ece92f85SJason Jin /* move them until CX is ZERO. */ 2806ece92f85SJason Jin count = M.x86.R_CX; 2807ece92f85SJason Jin M.x86.R_CX = 0; 2808ece92f85SJason Jin M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 2809ece92f85SJason Jin } 2810ece92f85SJason Jin while (count--) { 2811ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2812ece92f85SJason Jin store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX); 2813ece92f85SJason Jin } else { 2814ece92f85SJason Jin store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX); 2815ece92f85SJason Jin } 2816ece92f85SJason Jin M.x86.R_DI += inc; 2817ece92f85SJason Jin } 2818ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2819ece92f85SJason Jin END_OF_INSTR(); 2820ece92f85SJason Jin } 2821ece92f85SJason Jin 2822ece92f85SJason Jin /**************************************************************************** 2823ece92f85SJason Jin REMARKS: 2824ece92f85SJason Jin Handles opcode 0xac 2825ece92f85SJason Jin ****************************************************************************/ 2826ece92f85SJason Jin void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1)) 2827ece92f85SJason Jin { 2828ece92f85SJason Jin int inc; 2829ece92f85SJason Jin 2830ece92f85SJason Jin START_OF_INSTR(); 2831ece92f85SJason Jin DECODE_PRINTF("LODS\tBYTE\n"); 2832ece92f85SJason Jin TRACE_AND_STEP(); 2833ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */ 2834ece92f85SJason Jin inc = -1; 2835ece92f85SJason Jin else 2836ece92f85SJason Jin inc = 1; 2837ece92f85SJason Jin if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 2838ece92f85SJason Jin /* dont care whether REPE or REPNE */ 2839ece92f85SJason Jin /* move them until CX is ZERO. */ 2840ece92f85SJason Jin while (M.x86.R_CX != 0) { 2841ece92f85SJason Jin M.x86.R_AL = fetch_data_byte(M.x86.R_SI); 2842ece92f85SJason Jin M.x86.R_CX -= 1; 2843ece92f85SJason Jin M.x86.R_SI += inc; 2844ece92f85SJason Jin } 2845ece92f85SJason Jin M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 2846ece92f85SJason Jin } else { 2847ece92f85SJason Jin M.x86.R_AL = fetch_data_byte(M.x86.R_SI); 2848ece92f85SJason Jin M.x86.R_SI += inc; 2849ece92f85SJason Jin } 2850ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2851ece92f85SJason Jin END_OF_INSTR(); 2852ece92f85SJason Jin } 2853ece92f85SJason Jin 2854ece92f85SJason Jin /**************************************************************************** 2855ece92f85SJason Jin REMARKS: 2856ece92f85SJason Jin Handles opcode 0xad 2857ece92f85SJason Jin ****************************************************************************/ 2858ece92f85SJason Jin void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1)) 2859ece92f85SJason Jin { 2860ece92f85SJason Jin int inc; 2861ece92f85SJason Jin u32 count; 2862ece92f85SJason Jin 2863ece92f85SJason Jin START_OF_INSTR(); 2864ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2865ece92f85SJason Jin DECODE_PRINTF("LODS\tDWORD\n"); 2866ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */ 2867ece92f85SJason Jin inc = -4; 2868ece92f85SJason Jin else 2869ece92f85SJason Jin inc = 4; 2870ece92f85SJason Jin } else { 2871ece92f85SJason Jin DECODE_PRINTF("LODS\tWORD\n"); 2872ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */ 2873ece92f85SJason Jin inc = -2; 2874ece92f85SJason Jin else 2875ece92f85SJason Jin inc = 2; 2876ece92f85SJason Jin } 2877ece92f85SJason Jin TRACE_AND_STEP(); 2878ece92f85SJason Jin count = 1; 2879ece92f85SJason Jin if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) { 2880ece92f85SJason Jin /* dont care whether REPE or REPNE */ 2881ece92f85SJason Jin /* move them until CX is ZERO. */ 2882ece92f85SJason Jin count = M.x86.R_CX; 2883ece92f85SJason Jin M.x86.R_CX = 0; 2884ece92f85SJason Jin M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE); 2885ece92f85SJason Jin } 2886ece92f85SJason Jin while (count--) { 2887ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2888ece92f85SJason Jin M.x86.R_EAX = fetch_data_long(M.x86.R_SI); 2889ece92f85SJason Jin } else { 2890ece92f85SJason Jin M.x86.R_AX = fetch_data_word(M.x86.R_SI); 2891ece92f85SJason Jin } 2892ece92f85SJason Jin M.x86.R_SI += inc; 2893ece92f85SJason Jin } 2894ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2895ece92f85SJason Jin END_OF_INSTR(); 2896ece92f85SJason Jin } 2897ece92f85SJason Jin 2898ece92f85SJason Jin /**************************************************************************** 2899ece92f85SJason Jin REMARKS: 2900ece92f85SJason Jin Handles opcode 0xae 2901ece92f85SJason Jin ****************************************************************************/ 2902ece92f85SJason Jin void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1)) 2903ece92f85SJason Jin { 2904ece92f85SJason Jin s8 val2; 2905ece92f85SJason Jin int inc; 2906ece92f85SJason Jin 2907ece92f85SJason Jin START_OF_INSTR(); 2908ece92f85SJason Jin DECODE_PRINTF("SCAS\tBYTE\n"); 2909ece92f85SJason Jin TRACE_AND_STEP(); 2910ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */ 2911ece92f85SJason Jin inc = -1; 2912ece92f85SJason Jin else 2913ece92f85SJason Jin inc = 1; 2914ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_REPE) { 2915ece92f85SJason Jin /* REPE */ 2916ece92f85SJason Jin /* move them until CX is ZERO. */ 2917ece92f85SJason Jin while (M.x86.R_CX != 0) { 2918ece92f85SJason Jin val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 2919ece92f85SJason Jin cmp_byte(M.x86.R_AL, val2); 2920ece92f85SJason Jin M.x86.R_CX -= 1; 2921ece92f85SJason Jin M.x86.R_DI += inc; 2922ece92f85SJason Jin if (ACCESS_FLAG(F_ZF) == 0) 2923ece92f85SJason Jin break; 2924ece92f85SJason Jin } 2925ece92f85SJason Jin M.x86.mode &= ~SYSMODE_PREFIX_REPE; 2926ece92f85SJason Jin } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 2927ece92f85SJason Jin /* REPNE */ 2928ece92f85SJason Jin /* move them until CX is ZERO. */ 2929ece92f85SJason Jin while (M.x86.R_CX != 0) { 2930ece92f85SJason Jin val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 2931ece92f85SJason Jin cmp_byte(M.x86.R_AL, val2); 2932ece92f85SJason Jin M.x86.R_CX -= 1; 2933ece92f85SJason Jin M.x86.R_DI += inc; 2934ece92f85SJason Jin if (ACCESS_FLAG(F_ZF)) 2935ece92f85SJason Jin break; /* zero flag set means equal */ 2936ece92f85SJason Jin } 2937ece92f85SJason Jin M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 2938ece92f85SJason Jin } else { 2939ece92f85SJason Jin val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI); 2940ece92f85SJason Jin cmp_byte(M.x86.R_AL, val2); 2941ece92f85SJason Jin M.x86.R_DI += inc; 2942ece92f85SJason Jin } 2943ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 2944ece92f85SJason Jin END_OF_INSTR(); 2945ece92f85SJason Jin } 2946ece92f85SJason Jin 2947ece92f85SJason Jin /**************************************************************************** 2948ece92f85SJason Jin REMARKS: 2949ece92f85SJason Jin Handles opcode 0xaf 2950ece92f85SJason Jin ****************************************************************************/ 2951ece92f85SJason Jin void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1)) 2952ece92f85SJason Jin { 2953ece92f85SJason Jin int inc; 2954ece92f85SJason Jin u32 val; 2955ece92f85SJason Jin 2956ece92f85SJason Jin START_OF_INSTR(); 2957ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2958ece92f85SJason Jin DECODE_PRINTF("SCAS\tDWORD\n"); 2959ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */ 2960ece92f85SJason Jin inc = -4; 2961ece92f85SJason Jin else 2962ece92f85SJason Jin inc = 4; 2963ece92f85SJason Jin } else { 2964ece92f85SJason Jin DECODE_PRINTF("SCAS\tWORD\n"); 2965ece92f85SJason Jin if (ACCESS_FLAG(F_DF)) /* down */ 2966ece92f85SJason Jin inc = -2; 2967ece92f85SJason Jin else 2968ece92f85SJason Jin inc = 2; 2969ece92f85SJason Jin } 2970ece92f85SJason Jin TRACE_AND_STEP(); 2971ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_REPE) { 2972ece92f85SJason Jin /* REPE */ 2973ece92f85SJason Jin /* move them until CX is ZERO. */ 2974ece92f85SJason Jin while (M.x86.R_CX != 0) { 2975ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2976ece92f85SJason Jin val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 2977ece92f85SJason Jin cmp_long(M.x86.R_EAX, val); 2978ece92f85SJason Jin } else { 2979ece92f85SJason Jin val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 2980ece92f85SJason Jin cmp_word(M.x86.R_AX, (u16)val); 2981ece92f85SJason Jin } 2982ece92f85SJason Jin M.x86.R_CX -= 1; 2983ece92f85SJason Jin M.x86.R_DI += inc; 2984ece92f85SJason Jin if (ACCESS_FLAG(F_ZF) == 0) 2985ece92f85SJason Jin break; 2986ece92f85SJason Jin } 2987ece92f85SJason Jin M.x86.mode &= ~SYSMODE_PREFIX_REPE; 2988ece92f85SJason Jin } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) { 2989ece92f85SJason Jin /* REPNE */ 2990ece92f85SJason Jin /* move them until CX is ZERO. */ 2991ece92f85SJason Jin while (M.x86.R_CX != 0) { 2992ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 2993ece92f85SJason Jin val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 2994ece92f85SJason Jin cmp_long(M.x86.R_EAX, val); 2995ece92f85SJason Jin } else { 2996ece92f85SJason Jin val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 2997ece92f85SJason Jin cmp_word(M.x86.R_AX, (u16)val); 2998ece92f85SJason Jin } 2999ece92f85SJason Jin M.x86.R_CX -= 1; 3000ece92f85SJason Jin M.x86.R_DI += inc; 3001ece92f85SJason Jin if (ACCESS_FLAG(F_ZF)) 3002ece92f85SJason Jin break; /* zero flag set means equal */ 3003ece92f85SJason Jin } 3004ece92f85SJason Jin M.x86.mode &= ~SYSMODE_PREFIX_REPNE; 3005ece92f85SJason Jin } else { 3006ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3007ece92f85SJason Jin val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI); 3008ece92f85SJason Jin cmp_long(M.x86.R_EAX, val); 3009ece92f85SJason Jin } else { 3010ece92f85SJason Jin val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI); 3011ece92f85SJason Jin cmp_word(M.x86.R_AX, (u16)val); 3012ece92f85SJason Jin } 3013ece92f85SJason Jin M.x86.R_DI += inc; 3014ece92f85SJason Jin } 3015ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3016ece92f85SJason Jin END_OF_INSTR(); 3017ece92f85SJason Jin } 3018ece92f85SJason Jin 3019ece92f85SJason Jin /**************************************************************************** 3020ece92f85SJason Jin REMARKS: 3021ece92f85SJason Jin Handles opcode 0xb0 - 0xb7 3022ece92f85SJason Jin ****************************************************************************/ 3023ece92f85SJason Jin void x86emuOp_mov_byte_register_IMM(u8 op1) 3024ece92f85SJason Jin { 3025ece92f85SJason Jin u8 imm, *ptr; 3026ece92f85SJason Jin 3027ece92f85SJason Jin START_OF_INSTR(); 3028ece92f85SJason Jin DECODE_PRINTF("MOV\t"); 3029ece92f85SJason Jin ptr = DECODE_RM_BYTE_REGISTER(op1 & 0x7); 3030ece92f85SJason Jin DECODE_PRINTF(","); 3031ece92f85SJason Jin imm = fetch_byte_imm(); 3032ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm); 3033ece92f85SJason Jin TRACE_AND_STEP(); 3034ece92f85SJason Jin *ptr = imm; 3035ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3036ece92f85SJason Jin END_OF_INSTR(); 3037ece92f85SJason Jin } 3038ece92f85SJason Jin 3039ece92f85SJason Jin /**************************************************************************** 3040ece92f85SJason Jin REMARKS: 3041ece92f85SJason Jin Handles opcode 0xb8 - 0xbf 3042ece92f85SJason Jin ****************************************************************************/ 3043ece92f85SJason Jin void x86emuOp_mov_word_register_IMM(u8 X86EMU_UNUSED(op1)) 3044ece92f85SJason Jin { 3045ece92f85SJason Jin u32 srcval; 3046ece92f85SJason Jin 3047ece92f85SJason Jin op1 &= 0x7; 3048ece92f85SJason Jin 3049ece92f85SJason Jin START_OF_INSTR(); 3050ece92f85SJason Jin DECODE_PRINTF("MOV\t"); 3051ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3052ece92f85SJason Jin u32 *reg32; 3053ece92f85SJason Jin reg32 = DECODE_RM_LONG_REGISTER(op1); 3054ece92f85SJason Jin srcval = fetch_long_imm(); 3055ece92f85SJason Jin DECODE_PRINTF2(",%x\n", srcval); 3056ece92f85SJason Jin TRACE_AND_STEP(); 3057ece92f85SJason Jin *reg32 = srcval; 3058ece92f85SJason Jin } else { 3059ece92f85SJason Jin u16 *reg16; 3060ece92f85SJason Jin reg16 = DECODE_RM_WORD_REGISTER(op1); 3061ece92f85SJason Jin srcval = fetch_word_imm(); 3062ece92f85SJason Jin DECODE_PRINTF2(",%x\n", srcval); 3063ece92f85SJason Jin TRACE_AND_STEP(); 3064ece92f85SJason Jin *reg16 = (u16)srcval; 3065ece92f85SJason Jin } 3066ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3067ece92f85SJason Jin END_OF_INSTR(); 3068ece92f85SJason Jin } 3069ece92f85SJason Jin 3070ece92f85SJason Jin /**************************************************************************** 3071ece92f85SJason Jin REMARKS: 3072ece92f85SJason Jin Handles opcode 0xc0 3073ece92f85SJason Jin ****************************************************************************/ 3074ece92f85SJason Jin void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1)) 3075ece92f85SJason Jin { 3076ece92f85SJason Jin int mod, rl, rh; 3077ece92f85SJason Jin u8 *destreg; 3078ece92f85SJason Jin uint destoffset; 3079ece92f85SJason Jin u8 destval; 3080ece92f85SJason Jin u8 amt; 3081ece92f85SJason Jin 3082ece92f85SJason Jin /* 3083ece92f85SJason Jin * Yet another weirdo special case instruction format. Part of 3084ece92f85SJason Jin * the opcode held below in "RH". Doubly nested case would 3085ece92f85SJason Jin * result, except that the decoded instruction 3086ece92f85SJason Jin */ 3087ece92f85SJason Jin START_OF_INSTR(); 3088ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 3089ece92f85SJason Jin #ifdef DEBUG 3090ece92f85SJason Jin if (DEBUG_DECODE()) { 3091ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more 3092ece92f85SJason Jin general, so that it is important to leave the strings 3093ece92f85SJason Jin in the same format, even though the result is that the 3094ece92f85SJason Jin above test is done twice. */ 3095ece92f85SJason Jin 3096ece92f85SJason Jin switch (rh) { 3097ece92f85SJason Jin case 0: 3098ece92f85SJason Jin DECODE_PRINTF("ROL\t"); 3099ece92f85SJason Jin break; 3100ece92f85SJason Jin case 1: 3101ece92f85SJason Jin DECODE_PRINTF("ROR\t"); 3102ece92f85SJason Jin break; 3103ece92f85SJason Jin case 2: 3104ece92f85SJason Jin DECODE_PRINTF("RCL\t"); 3105ece92f85SJason Jin break; 3106ece92f85SJason Jin case 3: 3107ece92f85SJason Jin DECODE_PRINTF("RCR\t"); 3108ece92f85SJason Jin break; 3109ece92f85SJason Jin case 4: 3110ece92f85SJason Jin DECODE_PRINTF("SHL\t"); 3111ece92f85SJason Jin break; 3112ece92f85SJason Jin case 5: 3113ece92f85SJason Jin DECODE_PRINTF("SHR\t"); 3114ece92f85SJason Jin break; 3115ece92f85SJason Jin case 6: 3116ece92f85SJason Jin DECODE_PRINTF("SAL\t"); 3117ece92f85SJason Jin break; 3118ece92f85SJason Jin case 7: 3119ece92f85SJason Jin DECODE_PRINTF("SAR\t"); 3120ece92f85SJason Jin break; 3121ece92f85SJason Jin } 3122ece92f85SJason Jin } 3123ece92f85SJason Jin #endif 3124ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing 3125ece92f85SJason Jin mode. */ 3126ece92f85SJason Jin if (mod < 3) { 3127ece92f85SJason Jin DECODE_PRINTF("BYTE PTR "); 3128ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 3129ece92f85SJason Jin amt = fetch_byte_imm(); 3130ece92f85SJason Jin DECODE_PRINTF2(",%x\n", amt); 3131ece92f85SJason Jin destval = fetch_data_byte(destoffset); 3132ece92f85SJason Jin TRACE_AND_STEP(); 3133ece92f85SJason Jin destval = (*opcD0_byte_operation[rh]) (destval, amt); 3134ece92f85SJason Jin store_data_byte(destoffset, destval); 3135ece92f85SJason Jin } else { /* register to register */ 3136ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl); 3137ece92f85SJason Jin amt = fetch_byte_imm(); 3138ece92f85SJason Jin DECODE_PRINTF2(",%x\n", amt); 3139ece92f85SJason Jin TRACE_AND_STEP(); 3140ece92f85SJason Jin destval = (*opcD0_byte_operation[rh]) (*destreg, amt); 3141ece92f85SJason Jin *destreg = destval; 3142ece92f85SJason Jin } 3143ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3144ece92f85SJason Jin END_OF_INSTR(); 3145ece92f85SJason Jin } 3146ece92f85SJason Jin 3147ece92f85SJason Jin /**************************************************************************** 3148ece92f85SJason Jin REMARKS: 3149ece92f85SJason Jin Handles opcode 0xc1 3150ece92f85SJason Jin ****************************************************************************/ 3151ece92f85SJason Jin void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1)) 3152ece92f85SJason Jin { 3153ece92f85SJason Jin int mod, rl, rh; 3154ece92f85SJason Jin uint destoffset; 3155ece92f85SJason Jin u8 amt; 3156ece92f85SJason Jin 3157ece92f85SJason Jin /* 3158ece92f85SJason Jin * Yet another weirdo special case instruction format. Part of 3159ece92f85SJason Jin * the opcode held below in "RH". Doubly nested case would 3160ece92f85SJason Jin * result, except that the decoded instruction 3161ece92f85SJason Jin */ 3162ece92f85SJason Jin START_OF_INSTR(); 3163ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 3164ece92f85SJason Jin #ifdef DEBUG 3165ece92f85SJason Jin if (DEBUG_DECODE()) { 3166ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more 3167ece92f85SJason Jin general, so that it is important to leave the strings 3168ece92f85SJason Jin in the same format, even though the result is that the 3169ece92f85SJason Jin above test is done twice. */ 3170ece92f85SJason Jin 3171ece92f85SJason Jin switch (rh) { 3172ece92f85SJason Jin case 0: 3173ece92f85SJason Jin DECODE_PRINTF("ROL\t"); 3174ece92f85SJason Jin break; 3175ece92f85SJason Jin case 1: 3176ece92f85SJason Jin DECODE_PRINTF("ROR\t"); 3177ece92f85SJason Jin break; 3178ece92f85SJason Jin case 2: 3179ece92f85SJason Jin DECODE_PRINTF("RCL\t"); 3180ece92f85SJason Jin break; 3181ece92f85SJason Jin case 3: 3182ece92f85SJason Jin DECODE_PRINTF("RCR\t"); 3183ece92f85SJason Jin break; 3184ece92f85SJason Jin case 4: 3185ece92f85SJason Jin DECODE_PRINTF("SHL\t"); 3186ece92f85SJason Jin break; 3187ece92f85SJason Jin case 5: 3188ece92f85SJason Jin DECODE_PRINTF("SHR\t"); 3189ece92f85SJason Jin break; 3190ece92f85SJason Jin case 6: 3191ece92f85SJason Jin DECODE_PRINTF("SAL\t"); 3192ece92f85SJason Jin break; 3193ece92f85SJason Jin case 7: 3194ece92f85SJason Jin DECODE_PRINTF("SAR\t"); 3195ece92f85SJason Jin break; 3196ece92f85SJason Jin } 3197ece92f85SJason Jin } 3198ece92f85SJason Jin #endif 3199ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing 3200ece92f85SJason Jin mode. */ 3201ece92f85SJason Jin if (mod < 3) { 3202ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3203ece92f85SJason Jin u32 destval; 3204ece92f85SJason Jin 3205ece92f85SJason Jin DECODE_PRINTF("DWORD PTR "); 3206ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 3207ece92f85SJason Jin amt = fetch_byte_imm(); 3208ece92f85SJason Jin DECODE_PRINTF2(",%x\n", amt); 3209ece92f85SJason Jin destval = fetch_data_long(destoffset); 3210ece92f85SJason Jin TRACE_AND_STEP(); 3211ece92f85SJason Jin destval = (*opcD1_long_operation[rh]) (destval, amt); 3212ece92f85SJason Jin store_data_long(destoffset, destval); 3213ece92f85SJason Jin } else { 3214ece92f85SJason Jin u16 destval; 3215ece92f85SJason Jin 3216ece92f85SJason Jin DECODE_PRINTF("WORD PTR "); 3217ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 3218ece92f85SJason Jin amt = fetch_byte_imm(); 3219ece92f85SJason Jin DECODE_PRINTF2(",%x\n", amt); 3220ece92f85SJason Jin destval = fetch_data_word(destoffset); 3221ece92f85SJason Jin TRACE_AND_STEP(); 3222ece92f85SJason Jin destval = (*opcD1_word_operation[rh]) (destval, amt); 3223ece92f85SJason Jin store_data_word(destoffset, destval); 3224ece92f85SJason Jin } 3225ece92f85SJason Jin } else { /* register to register */ 3226ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3227ece92f85SJason Jin u32 *destreg; 3228ece92f85SJason Jin 3229ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 3230ece92f85SJason Jin amt = fetch_byte_imm(); 3231ece92f85SJason Jin DECODE_PRINTF2(",%x\n", amt); 3232ece92f85SJason Jin TRACE_AND_STEP(); 3233ece92f85SJason Jin *destreg = (*opcD1_long_operation[rh]) (*destreg, amt); 3234ece92f85SJason Jin } else { 3235ece92f85SJason Jin u16 *destreg; 3236ece92f85SJason Jin 3237ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 3238ece92f85SJason Jin amt = fetch_byte_imm(); 3239ece92f85SJason Jin DECODE_PRINTF2(",%x\n", amt); 3240ece92f85SJason Jin TRACE_AND_STEP(); 3241ece92f85SJason Jin *destreg = (*opcD1_word_operation[rh]) (*destreg, amt); 3242ece92f85SJason Jin } 3243ece92f85SJason Jin } 3244ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3245ece92f85SJason Jin END_OF_INSTR(); 3246ece92f85SJason Jin } 3247ece92f85SJason Jin 3248ece92f85SJason Jin /**************************************************************************** 3249ece92f85SJason Jin REMARKS: 3250ece92f85SJason Jin Handles opcode 0xc2 3251ece92f85SJason Jin ****************************************************************************/ 3252ece92f85SJason Jin void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1)) 3253ece92f85SJason Jin { 3254ece92f85SJason Jin u16 imm; 3255ece92f85SJason Jin 3256ece92f85SJason Jin START_OF_INSTR(); 3257ece92f85SJason Jin DECODE_PRINTF("RET\t"); 3258ece92f85SJason Jin imm = fetch_word_imm(); 3259ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm); 3260ece92f85SJason Jin RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip); 3261ece92f85SJason Jin TRACE_AND_STEP(); 3262ece92f85SJason Jin M.x86.R_IP = pop_word(); 3263ece92f85SJason Jin M.x86.R_SP += imm; 3264ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3265ece92f85SJason Jin END_OF_INSTR(); 3266ece92f85SJason Jin } 3267ece92f85SJason Jin 3268ece92f85SJason Jin /**************************************************************************** 3269ece92f85SJason Jin REMARKS: 3270ece92f85SJason Jin Handles opcode 0xc3 3271ece92f85SJason Jin ****************************************************************************/ 3272ece92f85SJason Jin void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1)) 3273ece92f85SJason Jin { 3274ece92f85SJason Jin START_OF_INSTR(); 3275ece92f85SJason Jin DECODE_PRINTF("RET\n"); 3276ece92f85SJason Jin RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip); 3277ece92f85SJason Jin TRACE_AND_STEP(); 3278ece92f85SJason Jin M.x86.R_IP = pop_word(); 3279ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3280ece92f85SJason Jin END_OF_INSTR(); 3281ece92f85SJason Jin } 3282ece92f85SJason Jin 3283ece92f85SJason Jin /**************************************************************************** 3284ece92f85SJason Jin REMARKS: 3285ece92f85SJason Jin Handles opcode 0xc4 3286ece92f85SJason Jin ****************************************************************************/ 3287ece92f85SJason Jin void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1)) 3288ece92f85SJason Jin { 3289ece92f85SJason Jin int mod, rh, rl; 3290ece92f85SJason Jin u16 *dstreg; 3291ece92f85SJason Jin uint srcoffset; 3292ece92f85SJason Jin 3293ece92f85SJason Jin START_OF_INSTR(); 3294ece92f85SJason Jin DECODE_PRINTF("LES\t"); 3295ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 3296ece92f85SJason Jin if (mod < 3) { 3297ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh); 3298ece92f85SJason Jin DECODE_PRINTF(","); 3299ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 3300ece92f85SJason Jin DECODE_PRINTF("\n"); 3301ece92f85SJason Jin TRACE_AND_STEP(); 3302ece92f85SJason Jin *dstreg = fetch_data_word(srcoffset); 3303ece92f85SJason Jin M.x86.R_ES = fetch_data_word(srcoffset + 2); 3304ece92f85SJason Jin } 3305ece92f85SJason Jin /* else UNDEFINED! register to register */ 3306ece92f85SJason Jin 3307ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3308ece92f85SJason Jin END_OF_INSTR(); 3309ece92f85SJason Jin } 3310ece92f85SJason Jin 3311ece92f85SJason Jin /**************************************************************************** 3312ece92f85SJason Jin REMARKS: 3313ece92f85SJason Jin Handles opcode 0xc5 3314ece92f85SJason Jin ****************************************************************************/ 3315ece92f85SJason Jin void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1)) 3316ece92f85SJason Jin { 3317ece92f85SJason Jin int mod, rh, rl; 3318ece92f85SJason Jin u16 *dstreg; 3319ece92f85SJason Jin uint srcoffset; 3320ece92f85SJason Jin 3321ece92f85SJason Jin START_OF_INSTR(); 3322ece92f85SJason Jin DECODE_PRINTF("LDS\t"); 3323ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 3324ece92f85SJason Jin if (mod < 3) { 3325ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh); 3326ece92f85SJason Jin DECODE_PRINTF(","); 3327ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 3328ece92f85SJason Jin DECODE_PRINTF("\n"); 3329ece92f85SJason Jin TRACE_AND_STEP(); 3330ece92f85SJason Jin *dstreg = fetch_data_word(srcoffset); 3331ece92f85SJason Jin M.x86.R_DS = fetch_data_word(srcoffset + 2); 3332ece92f85SJason Jin } 3333ece92f85SJason Jin /* else UNDEFINED! */ 3334ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3335ece92f85SJason Jin END_OF_INSTR(); 3336ece92f85SJason Jin } 3337ece92f85SJason Jin 3338ece92f85SJason Jin /**************************************************************************** 3339ece92f85SJason Jin REMARKS: 3340ece92f85SJason Jin Handles opcode 0xc6 3341ece92f85SJason Jin ****************************************************************************/ 3342ece92f85SJason Jin void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1)) 3343ece92f85SJason Jin { 3344ece92f85SJason Jin int mod, rl, rh; 3345ece92f85SJason Jin u8 *destreg; 3346ece92f85SJason Jin uint destoffset; 3347ece92f85SJason Jin u8 imm; 3348ece92f85SJason Jin 3349ece92f85SJason Jin START_OF_INSTR(); 3350ece92f85SJason Jin DECODE_PRINTF("MOV\t"); 3351ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 3352ece92f85SJason Jin if (rh != 0) { 3353ece92f85SJason Jin DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n"); 3354ece92f85SJason Jin HALT_SYS(); 3355ece92f85SJason Jin } 3356ece92f85SJason Jin if (mod < 3) { 3357ece92f85SJason Jin DECODE_PRINTF("BYTE PTR "); 3358ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 3359ece92f85SJason Jin imm = fetch_byte_imm(); 3360ece92f85SJason Jin DECODE_PRINTF2(",%2x\n", imm); 3361ece92f85SJason Jin TRACE_AND_STEP(); 3362ece92f85SJason Jin store_data_byte(destoffset, imm); 3363ece92f85SJason Jin } else { /* register to register */ 3364ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl); 3365ece92f85SJason Jin imm = fetch_byte_imm(); 3366ece92f85SJason Jin DECODE_PRINTF2(",%2x\n", imm); 3367ece92f85SJason Jin TRACE_AND_STEP(); 3368ece92f85SJason Jin *destreg = imm; 3369ece92f85SJason Jin } 3370ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3371ece92f85SJason Jin END_OF_INSTR(); 3372ece92f85SJason Jin } 3373ece92f85SJason Jin 3374ece92f85SJason Jin /**************************************************************************** 3375ece92f85SJason Jin REMARKS: 3376ece92f85SJason Jin Handles opcode 0xc7 3377ece92f85SJason Jin ****************************************************************************/ 3378ece92f85SJason Jin void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1)) 3379ece92f85SJason Jin { 3380ece92f85SJason Jin int mod, rl, rh; 3381ece92f85SJason Jin uint destoffset; 3382ece92f85SJason Jin 3383ece92f85SJason Jin START_OF_INSTR(); 3384ece92f85SJason Jin DECODE_PRINTF("MOV\t"); 3385ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 3386ece92f85SJason Jin if (rh != 0) { 3387ece92f85SJason Jin DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n"); 3388ece92f85SJason Jin HALT_SYS(); 3389ece92f85SJason Jin } 3390ece92f85SJason Jin if (mod < 3) { 3391ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3392ece92f85SJason Jin u32 imm; 3393ece92f85SJason Jin 3394ece92f85SJason Jin DECODE_PRINTF("DWORD PTR "); 3395ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 3396ece92f85SJason Jin imm = fetch_long_imm(); 3397ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm); 3398ece92f85SJason Jin TRACE_AND_STEP(); 3399ece92f85SJason Jin store_data_long(destoffset, imm); 3400ece92f85SJason Jin } else { 3401ece92f85SJason Jin u16 imm; 3402ece92f85SJason Jin 3403ece92f85SJason Jin DECODE_PRINTF("WORD PTR "); 3404ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 3405ece92f85SJason Jin imm = fetch_word_imm(); 3406ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm); 3407ece92f85SJason Jin TRACE_AND_STEP(); 3408ece92f85SJason Jin store_data_word(destoffset, imm); 3409ece92f85SJason Jin } 3410ece92f85SJason Jin } else { /* register to register */ 3411ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3412ece92f85SJason Jin u32 *destreg; 3413ece92f85SJason Jin u32 imm; 3414ece92f85SJason Jin 3415ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 3416ece92f85SJason Jin imm = fetch_long_imm(); 3417ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm); 3418ece92f85SJason Jin TRACE_AND_STEP(); 3419ece92f85SJason Jin *destreg = imm; 3420ece92f85SJason Jin } else { 3421ece92f85SJason Jin u16 *destreg; 3422ece92f85SJason Jin u16 imm; 3423ece92f85SJason Jin 3424ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 3425ece92f85SJason Jin imm = fetch_word_imm(); 3426ece92f85SJason Jin DECODE_PRINTF2(",%x\n", imm); 3427ece92f85SJason Jin TRACE_AND_STEP(); 3428ece92f85SJason Jin *destreg = imm; 3429ece92f85SJason Jin } 3430ece92f85SJason Jin } 3431ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3432ece92f85SJason Jin END_OF_INSTR(); 3433ece92f85SJason Jin } 3434ece92f85SJason Jin 3435ece92f85SJason Jin /**************************************************************************** 3436ece92f85SJason Jin REMARKS: 3437ece92f85SJason Jin Handles opcode 0xc8 3438ece92f85SJason Jin ****************************************************************************/ 3439ece92f85SJason Jin void x86emuOp_enter(u8 X86EMU_UNUSED(op1)) 3440ece92f85SJason Jin { 3441ece92f85SJason Jin u16 local,frame_pointer; 3442ece92f85SJason Jin u8 nesting; 3443ece92f85SJason Jin int i; 3444ece92f85SJason Jin 3445ece92f85SJason Jin START_OF_INSTR(); 3446ece92f85SJason Jin local = fetch_word_imm(); 3447ece92f85SJason Jin nesting = fetch_byte_imm(); 3448ece92f85SJason Jin DECODE_PRINTF2("ENTER %x\n", local); 3449ece92f85SJason Jin DECODE_PRINTF2(",%x\n", nesting); 3450ece92f85SJason Jin TRACE_AND_STEP(); 3451ece92f85SJason Jin push_word(M.x86.R_BP); 3452ece92f85SJason Jin frame_pointer = M.x86.R_SP; 3453ece92f85SJason Jin if (nesting > 0) { 3454ece92f85SJason Jin for (i = 1; i < nesting; i++) { 3455ece92f85SJason Jin M.x86.R_BP -= 2; 3456ece92f85SJason Jin push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP)); 3457ece92f85SJason Jin } 3458ece92f85SJason Jin push_word(frame_pointer); 3459ece92f85SJason Jin } 3460ece92f85SJason Jin M.x86.R_BP = frame_pointer; 3461ece92f85SJason Jin M.x86.R_SP = (u16)(M.x86.R_SP - local); 3462ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3463ece92f85SJason Jin END_OF_INSTR(); 3464ece92f85SJason Jin } 3465ece92f85SJason Jin 3466ece92f85SJason Jin /**************************************************************************** 3467ece92f85SJason Jin REMARKS: 3468ece92f85SJason Jin Handles opcode 0xc9 3469ece92f85SJason Jin ****************************************************************************/ 3470ece92f85SJason Jin void x86emuOp_leave(u8 X86EMU_UNUSED(op1)) 3471ece92f85SJason Jin { 3472ece92f85SJason Jin START_OF_INSTR(); 3473ece92f85SJason Jin DECODE_PRINTF("LEAVE\n"); 3474ece92f85SJason Jin TRACE_AND_STEP(); 3475ece92f85SJason Jin M.x86.R_SP = M.x86.R_BP; 3476ece92f85SJason Jin M.x86.R_BP = pop_word(); 3477ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3478ece92f85SJason Jin END_OF_INSTR(); 3479ece92f85SJason Jin } 3480ece92f85SJason Jin 3481ece92f85SJason Jin /**************************************************************************** 3482ece92f85SJason Jin REMARKS: 3483ece92f85SJason Jin Handles opcode 0xca 3484ece92f85SJason Jin ****************************************************************************/ 3485ece92f85SJason Jin void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1)) 3486ece92f85SJason Jin { 3487ece92f85SJason Jin u16 imm; 3488ece92f85SJason Jin 3489ece92f85SJason Jin START_OF_INSTR(); 3490ece92f85SJason Jin DECODE_PRINTF("RETF\t"); 3491ece92f85SJason Jin imm = fetch_word_imm(); 3492ece92f85SJason Jin DECODE_PRINTF2("%x\n", imm); 3493ece92f85SJason Jin RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip); 3494ece92f85SJason Jin TRACE_AND_STEP(); 3495ece92f85SJason Jin M.x86.R_IP = pop_word(); 3496ece92f85SJason Jin M.x86.R_CS = pop_word(); 3497ece92f85SJason Jin M.x86.R_SP += imm; 3498ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3499ece92f85SJason Jin END_OF_INSTR(); 3500ece92f85SJason Jin } 3501ece92f85SJason Jin 3502ece92f85SJason Jin /**************************************************************************** 3503ece92f85SJason Jin REMARKS: 3504ece92f85SJason Jin Handles opcode 0xcb 3505ece92f85SJason Jin ****************************************************************************/ 3506ece92f85SJason Jin void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1)) 3507ece92f85SJason Jin { 3508ece92f85SJason Jin START_OF_INSTR(); 3509ece92f85SJason Jin DECODE_PRINTF("RETF\n"); 3510ece92f85SJason Jin RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip); 3511ece92f85SJason Jin TRACE_AND_STEP(); 3512ece92f85SJason Jin M.x86.R_IP = pop_word(); 3513ece92f85SJason Jin M.x86.R_CS = pop_word(); 3514ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3515ece92f85SJason Jin END_OF_INSTR(); 3516ece92f85SJason Jin } 3517ece92f85SJason Jin 3518ece92f85SJason Jin /**************************************************************************** 3519ece92f85SJason Jin REMARKS: 3520ece92f85SJason Jin Handles opcode 0xcc 3521ece92f85SJason Jin ****************************************************************************/ 3522ece92f85SJason Jin void x86emuOp_int3(u8 X86EMU_UNUSED(op1)) 3523ece92f85SJason Jin { 3524ece92f85SJason Jin u16 tmp; 3525ece92f85SJason Jin 3526ece92f85SJason Jin START_OF_INSTR(); 3527ece92f85SJason Jin DECODE_PRINTF("INT 3\n"); 3528ece92f85SJason Jin tmp = (u16) mem_access_word(3 * 4 + 2); 3529ece92f85SJason Jin /* access the segment register */ 3530ece92f85SJason Jin TRACE_AND_STEP(); 3531ece92f85SJason Jin if (_X86EMU_intrTab[3]) { 3532ece92f85SJason Jin (*_X86EMU_intrTab[3])(3); 3533ece92f85SJason Jin } else { 3534ece92f85SJason Jin push_word((u16)M.x86.R_FLG); 3535ece92f85SJason Jin CLEAR_FLAG(F_IF); 3536ece92f85SJason Jin CLEAR_FLAG(F_TF); 3537ece92f85SJason Jin push_word(M.x86.R_CS); 3538ece92f85SJason Jin M.x86.R_CS = mem_access_word(3 * 4 + 2); 3539ece92f85SJason Jin push_word(M.x86.R_IP); 3540ece92f85SJason Jin M.x86.R_IP = mem_access_word(3 * 4); 3541ece92f85SJason Jin } 3542ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3543ece92f85SJason Jin END_OF_INSTR(); 3544ece92f85SJason Jin } 3545ece92f85SJason Jin 3546ece92f85SJason Jin /**************************************************************************** 3547ece92f85SJason Jin REMARKS: 3548ece92f85SJason Jin Handles opcode 0xcd 3549ece92f85SJason Jin ****************************************************************************/ 3550ece92f85SJason Jin void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1)) 3551ece92f85SJason Jin { 3552ece92f85SJason Jin u16 tmp; 3553ece92f85SJason Jin u8 intnum; 3554ece92f85SJason Jin 3555ece92f85SJason Jin START_OF_INSTR(); 3556ece92f85SJason Jin DECODE_PRINTF("INT\t"); 3557ece92f85SJason Jin intnum = fetch_byte_imm(); 3558ece92f85SJason Jin DECODE_PRINTF2("%x\n", intnum); 3559ece92f85SJason Jin tmp = mem_access_word(intnum * 4 + 2); 3560ece92f85SJason Jin TRACE_AND_STEP(); 3561ece92f85SJason Jin if (_X86EMU_intrTab[intnum]) { 3562ece92f85SJason Jin (*_X86EMU_intrTab[intnum])(intnum); 3563ece92f85SJason Jin } else { 3564ece92f85SJason Jin push_word((u16)M.x86.R_FLG); 3565ece92f85SJason Jin CLEAR_FLAG(F_IF); 3566ece92f85SJason Jin CLEAR_FLAG(F_TF); 3567ece92f85SJason Jin push_word(M.x86.R_CS); 3568ece92f85SJason Jin M.x86.R_CS = mem_access_word(intnum * 4 + 2); 3569ece92f85SJason Jin push_word(M.x86.R_IP); 3570ece92f85SJason Jin M.x86.R_IP = mem_access_word(intnum * 4); 3571ece92f85SJason Jin } 3572ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3573ece92f85SJason Jin END_OF_INSTR(); 3574ece92f85SJason Jin } 3575ece92f85SJason Jin 3576ece92f85SJason Jin /**************************************************************************** 3577ece92f85SJason Jin REMARKS: 3578ece92f85SJason Jin Handles opcode 0xce 3579ece92f85SJason Jin ****************************************************************************/ 3580ece92f85SJason Jin void x86emuOp_into(u8 X86EMU_UNUSED(op1)) 3581ece92f85SJason Jin { 3582ece92f85SJason Jin u16 tmp; 3583ece92f85SJason Jin 3584ece92f85SJason Jin START_OF_INSTR(); 3585ece92f85SJason Jin DECODE_PRINTF("INTO\n"); 3586ece92f85SJason Jin TRACE_AND_STEP(); 3587ece92f85SJason Jin if (ACCESS_FLAG(F_OF)) { 3588ece92f85SJason Jin tmp = mem_access_word(4 * 4 + 2); 3589ece92f85SJason Jin if (_X86EMU_intrTab[4]) { 3590ece92f85SJason Jin (*_X86EMU_intrTab[4])(4); 3591ece92f85SJason Jin } else { 3592ece92f85SJason Jin push_word((u16)M.x86.R_FLG); 3593ece92f85SJason Jin CLEAR_FLAG(F_IF); 3594ece92f85SJason Jin CLEAR_FLAG(F_TF); 3595ece92f85SJason Jin push_word(M.x86.R_CS); 3596ece92f85SJason Jin M.x86.R_CS = mem_access_word(4 * 4 + 2); 3597ece92f85SJason Jin push_word(M.x86.R_IP); 3598ece92f85SJason Jin M.x86.R_IP = mem_access_word(4 * 4); 3599ece92f85SJason Jin } 3600ece92f85SJason Jin } 3601ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3602ece92f85SJason Jin END_OF_INSTR(); 3603ece92f85SJason Jin } 3604ece92f85SJason Jin 3605ece92f85SJason Jin /**************************************************************************** 3606ece92f85SJason Jin REMARKS: 3607ece92f85SJason Jin Handles opcode 0xcf 3608ece92f85SJason Jin ****************************************************************************/ 3609ece92f85SJason Jin void x86emuOp_iret(u8 X86EMU_UNUSED(op1)) 3610ece92f85SJason Jin { 3611ece92f85SJason Jin START_OF_INSTR(); 3612ece92f85SJason Jin DECODE_PRINTF("IRET\n"); 3613ece92f85SJason Jin 3614ece92f85SJason Jin TRACE_AND_STEP(); 3615ece92f85SJason Jin 3616ece92f85SJason Jin M.x86.R_IP = pop_word(); 3617ece92f85SJason Jin M.x86.R_CS = pop_word(); 3618ece92f85SJason Jin M.x86.R_FLG = pop_word(); 3619ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3620ece92f85SJason Jin END_OF_INSTR(); 3621ece92f85SJason Jin } 3622ece92f85SJason Jin 3623ece92f85SJason Jin /**************************************************************************** 3624ece92f85SJason Jin REMARKS: 3625ece92f85SJason Jin Handles opcode 0xd0 3626ece92f85SJason Jin ****************************************************************************/ 3627ece92f85SJason Jin void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1)) 3628ece92f85SJason Jin { 3629ece92f85SJason Jin int mod, rl, rh; 3630ece92f85SJason Jin u8 *destreg; 3631ece92f85SJason Jin uint destoffset; 3632ece92f85SJason Jin u8 destval; 3633ece92f85SJason Jin 3634ece92f85SJason Jin /* 3635ece92f85SJason Jin * Yet another weirdo special case instruction format. Part of 3636ece92f85SJason Jin * the opcode held below in "RH". Doubly nested case would 3637ece92f85SJason Jin * result, except that the decoded instruction 3638ece92f85SJason Jin */ 3639ece92f85SJason Jin START_OF_INSTR(); 3640ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 3641ece92f85SJason Jin #ifdef DEBUG 3642ece92f85SJason Jin if (DEBUG_DECODE()) { 3643ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more 3644ece92f85SJason Jin general, so that it is important to leave the strings 3645ece92f85SJason Jin in the same format, even though the result is that the 3646ece92f85SJason Jin above test is done twice. */ 3647ece92f85SJason Jin switch (rh) { 3648ece92f85SJason Jin case 0: 3649ece92f85SJason Jin DECODE_PRINTF("ROL\t"); 3650ece92f85SJason Jin break; 3651ece92f85SJason Jin case 1: 3652ece92f85SJason Jin DECODE_PRINTF("ROR\t"); 3653ece92f85SJason Jin break; 3654ece92f85SJason Jin case 2: 3655ece92f85SJason Jin DECODE_PRINTF("RCL\t"); 3656ece92f85SJason Jin break; 3657ece92f85SJason Jin case 3: 3658ece92f85SJason Jin DECODE_PRINTF("RCR\t"); 3659ece92f85SJason Jin break; 3660ece92f85SJason Jin case 4: 3661ece92f85SJason Jin DECODE_PRINTF("SHL\t"); 3662ece92f85SJason Jin break; 3663ece92f85SJason Jin case 5: 3664ece92f85SJason Jin DECODE_PRINTF("SHR\t"); 3665ece92f85SJason Jin break; 3666ece92f85SJason Jin case 6: 3667ece92f85SJason Jin DECODE_PRINTF("SAL\t"); 3668ece92f85SJason Jin break; 3669ece92f85SJason Jin case 7: 3670ece92f85SJason Jin DECODE_PRINTF("SAR\t"); 3671ece92f85SJason Jin break; 3672ece92f85SJason Jin } 3673ece92f85SJason Jin } 3674ece92f85SJason Jin #endif 3675ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing 3676ece92f85SJason Jin mode. */ 3677ece92f85SJason Jin if (mod < 3) { 3678ece92f85SJason Jin DECODE_PRINTF("BYTE PTR "); 3679ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 3680ece92f85SJason Jin DECODE_PRINTF(",1\n"); 3681ece92f85SJason Jin destval = fetch_data_byte(destoffset); 3682ece92f85SJason Jin TRACE_AND_STEP(); 3683ece92f85SJason Jin destval = (*opcD0_byte_operation[rh]) (destval, 1); 3684ece92f85SJason Jin store_data_byte(destoffset, destval); 3685ece92f85SJason Jin } else { /* register to register */ 3686ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl); 3687ece92f85SJason Jin DECODE_PRINTF(",1\n"); 3688ece92f85SJason Jin TRACE_AND_STEP(); 3689ece92f85SJason Jin destval = (*opcD0_byte_operation[rh]) (*destreg, 1); 3690ece92f85SJason Jin *destreg = destval; 3691ece92f85SJason Jin } 3692ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3693ece92f85SJason Jin END_OF_INSTR(); 3694ece92f85SJason Jin } 3695ece92f85SJason Jin 3696ece92f85SJason Jin /**************************************************************************** 3697ece92f85SJason Jin REMARKS: 3698ece92f85SJason Jin Handles opcode 0xd1 3699ece92f85SJason Jin ****************************************************************************/ 3700ece92f85SJason Jin void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1)) 3701ece92f85SJason Jin { 3702ece92f85SJason Jin int mod, rl, rh; 3703ece92f85SJason Jin uint destoffset; 3704ece92f85SJason Jin 3705ece92f85SJason Jin /* 3706ece92f85SJason Jin * Yet another weirdo special case instruction format. Part of 3707ece92f85SJason Jin * the opcode held below in "RH". Doubly nested case would 3708ece92f85SJason Jin * result, except that the decoded instruction 3709ece92f85SJason Jin */ 3710ece92f85SJason Jin START_OF_INSTR(); 3711ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 3712ece92f85SJason Jin #ifdef DEBUG 3713ece92f85SJason Jin if (DEBUG_DECODE()) { 3714ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more 3715ece92f85SJason Jin general, so that it is important to leave the strings 3716ece92f85SJason Jin in the same format, even though the result is that the 3717ece92f85SJason Jin above test is done twice. */ 3718ece92f85SJason Jin switch (rh) { 3719ece92f85SJason Jin case 0: 3720ece92f85SJason Jin DECODE_PRINTF("ROL\t"); 3721ece92f85SJason Jin break; 3722ece92f85SJason Jin case 1: 3723ece92f85SJason Jin DECODE_PRINTF("ROR\t"); 3724ece92f85SJason Jin break; 3725ece92f85SJason Jin case 2: 3726ece92f85SJason Jin DECODE_PRINTF("RCL\t"); 3727ece92f85SJason Jin break; 3728ece92f85SJason Jin case 3: 3729ece92f85SJason Jin DECODE_PRINTF("RCR\t"); 3730ece92f85SJason Jin break; 3731ece92f85SJason Jin case 4: 3732ece92f85SJason Jin DECODE_PRINTF("SHL\t"); 3733ece92f85SJason Jin break; 3734ece92f85SJason Jin case 5: 3735ece92f85SJason Jin DECODE_PRINTF("SHR\t"); 3736ece92f85SJason Jin break; 3737ece92f85SJason Jin case 6: 3738ece92f85SJason Jin DECODE_PRINTF("SAL\t"); 3739ece92f85SJason Jin break; 3740ece92f85SJason Jin case 7: 3741ece92f85SJason Jin DECODE_PRINTF("SAR\t"); 3742ece92f85SJason Jin break; 3743ece92f85SJason Jin } 3744ece92f85SJason Jin } 3745ece92f85SJason Jin #endif 3746ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing 3747ece92f85SJason Jin mode. */ 3748ece92f85SJason Jin if (mod < 3) { 3749ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3750ece92f85SJason Jin u32 destval; 3751ece92f85SJason Jin 3752ece92f85SJason Jin DECODE_PRINTF("DWORD PTR "); 3753ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 3754ece92f85SJason Jin DECODE_PRINTF(",1\n"); 3755ece92f85SJason Jin destval = fetch_data_long(destoffset); 3756ece92f85SJason Jin TRACE_AND_STEP(); 3757ece92f85SJason Jin destval = (*opcD1_long_operation[rh]) (destval, 1); 3758ece92f85SJason Jin store_data_long(destoffset, destval); 3759ece92f85SJason Jin } else { 3760ece92f85SJason Jin u16 destval; 3761ece92f85SJason Jin 3762ece92f85SJason Jin DECODE_PRINTF("WORD PTR "); 3763ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 3764ece92f85SJason Jin DECODE_PRINTF(",1\n"); 3765ece92f85SJason Jin destval = fetch_data_word(destoffset); 3766ece92f85SJason Jin TRACE_AND_STEP(); 3767ece92f85SJason Jin destval = (*opcD1_word_operation[rh]) (destval, 1); 3768ece92f85SJason Jin store_data_word(destoffset, destval); 3769ece92f85SJason Jin } 3770ece92f85SJason Jin } else { /* register to register */ 3771ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3772ece92f85SJason Jin u32 destval; 3773ece92f85SJason Jin u32 *destreg; 3774ece92f85SJason Jin 3775ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 3776ece92f85SJason Jin DECODE_PRINTF(",1\n"); 3777ece92f85SJason Jin TRACE_AND_STEP(); 3778ece92f85SJason Jin destval = (*opcD1_long_operation[rh]) (*destreg, 1); 3779ece92f85SJason Jin *destreg = destval; 3780ece92f85SJason Jin } else { 3781ece92f85SJason Jin u16 destval; 3782ece92f85SJason Jin u16 *destreg; 3783ece92f85SJason Jin 3784ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 3785ece92f85SJason Jin DECODE_PRINTF(",1\n"); 3786ece92f85SJason Jin TRACE_AND_STEP(); 3787ece92f85SJason Jin destval = (*opcD1_word_operation[rh]) (*destreg, 1); 3788ece92f85SJason Jin *destreg = destval; 3789ece92f85SJason Jin } 3790ece92f85SJason Jin } 3791ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3792ece92f85SJason Jin END_OF_INSTR(); 3793ece92f85SJason Jin } 3794ece92f85SJason Jin 3795ece92f85SJason Jin /**************************************************************************** 3796ece92f85SJason Jin REMARKS: 3797ece92f85SJason Jin Handles opcode 0xd2 3798ece92f85SJason Jin ****************************************************************************/ 3799ece92f85SJason Jin void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1)) 3800ece92f85SJason Jin { 3801ece92f85SJason Jin int mod, rl, rh; 3802ece92f85SJason Jin u8 *destreg; 3803ece92f85SJason Jin uint destoffset; 3804ece92f85SJason Jin u8 destval; 3805ece92f85SJason Jin u8 amt; 3806ece92f85SJason Jin 3807ece92f85SJason Jin /* 3808ece92f85SJason Jin * Yet another weirdo special case instruction format. Part of 3809ece92f85SJason Jin * the opcode held below in "RH". Doubly nested case would 3810ece92f85SJason Jin * result, except that the decoded instruction 3811ece92f85SJason Jin */ 3812ece92f85SJason Jin START_OF_INSTR(); 3813ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 3814ece92f85SJason Jin #ifdef DEBUG 3815ece92f85SJason Jin if (DEBUG_DECODE()) { 3816ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more 3817ece92f85SJason Jin general, so that it is important to leave the strings 3818ece92f85SJason Jin in the same format, even though the result is that the 3819ece92f85SJason Jin above test is done twice. */ 3820ece92f85SJason Jin switch (rh) { 3821ece92f85SJason Jin case 0: 3822ece92f85SJason Jin DECODE_PRINTF("ROL\t"); 3823ece92f85SJason Jin break; 3824ece92f85SJason Jin case 1: 3825ece92f85SJason Jin DECODE_PRINTF("ROR\t"); 3826ece92f85SJason Jin break; 3827ece92f85SJason Jin case 2: 3828ece92f85SJason Jin DECODE_PRINTF("RCL\t"); 3829ece92f85SJason Jin break; 3830ece92f85SJason Jin case 3: 3831ece92f85SJason Jin DECODE_PRINTF("RCR\t"); 3832ece92f85SJason Jin break; 3833ece92f85SJason Jin case 4: 3834ece92f85SJason Jin DECODE_PRINTF("SHL\t"); 3835ece92f85SJason Jin break; 3836ece92f85SJason Jin case 5: 3837ece92f85SJason Jin DECODE_PRINTF("SHR\t"); 3838ece92f85SJason Jin break; 3839ece92f85SJason Jin case 6: 3840ece92f85SJason Jin DECODE_PRINTF("SAL\t"); 3841ece92f85SJason Jin break; 3842ece92f85SJason Jin case 7: 3843ece92f85SJason Jin DECODE_PRINTF("SAR\t"); 3844ece92f85SJason Jin break; 3845ece92f85SJason Jin } 3846ece92f85SJason Jin } 3847ece92f85SJason Jin #endif 3848ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing 3849ece92f85SJason Jin mode. */ 3850ece92f85SJason Jin amt = M.x86.R_CL; 3851ece92f85SJason Jin if (mod < 3) { 3852ece92f85SJason Jin DECODE_PRINTF("BYTE PTR "); 3853ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 3854ece92f85SJason Jin DECODE_PRINTF(",CL\n"); 3855ece92f85SJason Jin destval = fetch_data_byte(destoffset); 3856ece92f85SJason Jin TRACE_AND_STEP(); 3857ece92f85SJason Jin destval = (*opcD0_byte_operation[rh]) (destval, amt); 3858ece92f85SJason Jin store_data_byte(destoffset, destval); 3859ece92f85SJason Jin } else { /* register to register */ 3860ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl); 3861ece92f85SJason Jin DECODE_PRINTF(",CL\n"); 3862ece92f85SJason Jin TRACE_AND_STEP(); 3863ece92f85SJason Jin destval = (*opcD0_byte_operation[rh]) (*destreg, amt); 3864ece92f85SJason Jin *destreg = destval; 3865ece92f85SJason Jin } 3866ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3867ece92f85SJason Jin END_OF_INSTR(); 3868ece92f85SJason Jin } 3869ece92f85SJason Jin 3870ece92f85SJason Jin /**************************************************************************** 3871ece92f85SJason Jin REMARKS: 3872ece92f85SJason Jin Handles opcode 0xd3 3873ece92f85SJason Jin ****************************************************************************/ 3874ece92f85SJason Jin void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1)) 3875ece92f85SJason Jin { 3876ece92f85SJason Jin int mod, rl, rh; 3877ece92f85SJason Jin uint destoffset; 3878ece92f85SJason Jin u8 amt; 3879ece92f85SJason Jin 3880ece92f85SJason Jin /* 3881ece92f85SJason Jin * Yet another weirdo special case instruction format. Part of 3882ece92f85SJason Jin * the opcode held below in "RH". Doubly nested case would 3883ece92f85SJason Jin * result, except that the decoded instruction 3884ece92f85SJason Jin */ 3885ece92f85SJason Jin START_OF_INSTR(); 3886ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 3887ece92f85SJason Jin #ifdef DEBUG 3888ece92f85SJason Jin if (DEBUG_DECODE()) { 3889ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more 3890ece92f85SJason Jin general, so that it is important to leave the strings 3891ece92f85SJason Jin in the same format, even though the result is that the 3892ece92f85SJason Jin above test is done twice. */ 3893ece92f85SJason Jin switch (rh) { 3894ece92f85SJason Jin case 0: 3895ece92f85SJason Jin DECODE_PRINTF("ROL\t"); 3896ece92f85SJason Jin break; 3897ece92f85SJason Jin case 1: 3898ece92f85SJason Jin DECODE_PRINTF("ROR\t"); 3899ece92f85SJason Jin break; 3900ece92f85SJason Jin case 2: 3901ece92f85SJason Jin DECODE_PRINTF("RCL\t"); 3902ece92f85SJason Jin break; 3903ece92f85SJason Jin case 3: 3904ece92f85SJason Jin DECODE_PRINTF("RCR\t"); 3905ece92f85SJason Jin break; 3906ece92f85SJason Jin case 4: 3907ece92f85SJason Jin DECODE_PRINTF("SHL\t"); 3908ece92f85SJason Jin break; 3909ece92f85SJason Jin case 5: 3910ece92f85SJason Jin DECODE_PRINTF("SHR\t"); 3911ece92f85SJason Jin break; 3912ece92f85SJason Jin case 6: 3913ece92f85SJason Jin DECODE_PRINTF("SAL\t"); 3914ece92f85SJason Jin break; 3915ece92f85SJason Jin case 7: 3916ece92f85SJason Jin DECODE_PRINTF("SAR\t"); 3917ece92f85SJason Jin break; 3918ece92f85SJason Jin } 3919ece92f85SJason Jin } 3920ece92f85SJason Jin #endif 3921ece92f85SJason Jin /* know operation, decode the mod byte to find the addressing 3922ece92f85SJason Jin mode. */ 3923ece92f85SJason Jin amt = M.x86.R_CL; 3924ece92f85SJason Jin if (mod < 3) { 3925ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3926ece92f85SJason Jin u32 destval; 3927ece92f85SJason Jin 3928ece92f85SJason Jin DECODE_PRINTF("DWORD PTR "); 3929ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 3930ece92f85SJason Jin DECODE_PRINTF(",CL\n"); 3931ece92f85SJason Jin destval = fetch_data_long(destoffset); 3932ece92f85SJason Jin TRACE_AND_STEP(); 3933ece92f85SJason Jin destval = (*opcD1_long_operation[rh]) (destval, amt); 3934ece92f85SJason Jin store_data_long(destoffset, destval); 3935ece92f85SJason Jin } else { 3936ece92f85SJason Jin u16 destval; 3937ece92f85SJason Jin 3938ece92f85SJason Jin DECODE_PRINTF("WORD PTR "); 3939ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 3940ece92f85SJason Jin DECODE_PRINTF(",CL\n"); 3941ece92f85SJason Jin destval = fetch_data_word(destoffset); 3942ece92f85SJason Jin TRACE_AND_STEP(); 3943ece92f85SJason Jin destval = (*opcD1_word_operation[rh]) (destval, amt); 3944ece92f85SJason Jin store_data_word(destoffset, destval); 3945ece92f85SJason Jin } 3946ece92f85SJason Jin } else { /* register to register */ 3947ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 3948ece92f85SJason Jin u32 *destreg; 3949ece92f85SJason Jin 3950ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 3951ece92f85SJason Jin DECODE_PRINTF(",CL\n"); 3952ece92f85SJason Jin TRACE_AND_STEP(); 3953ece92f85SJason Jin *destreg = (*opcD1_long_operation[rh]) (*destreg, amt); 3954ece92f85SJason Jin } else { 3955ece92f85SJason Jin u16 *destreg; 3956ece92f85SJason Jin 3957ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 3958ece92f85SJason Jin DECODE_PRINTF(",CL\n"); 3959ece92f85SJason Jin TRACE_AND_STEP(); 3960ece92f85SJason Jin *destreg = (*opcD1_word_operation[rh]) (*destreg, amt); 3961ece92f85SJason Jin } 3962ece92f85SJason Jin } 3963ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3964ece92f85SJason Jin END_OF_INSTR(); 3965ece92f85SJason Jin } 3966ece92f85SJason Jin 3967ece92f85SJason Jin /**************************************************************************** 3968ece92f85SJason Jin REMARKS: 3969ece92f85SJason Jin Handles opcode 0xd4 3970ece92f85SJason Jin ****************************************************************************/ 3971ece92f85SJason Jin void x86emuOp_aam(u8 X86EMU_UNUSED(op1)) 3972ece92f85SJason Jin { 3973ece92f85SJason Jin u8 a; 3974ece92f85SJason Jin 3975ece92f85SJason Jin START_OF_INSTR(); 3976ece92f85SJason Jin DECODE_PRINTF("AAM\n"); 3977ece92f85SJason Jin a = fetch_byte_imm(); /* this is a stupid encoding. */ 3978ece92f85SJason Jin if (a != 10) { 3979ece92f85SJason Jin DECODE_PRINTF("ERROR DECODING AAM\n"); 3980ece92f85SJason Jin TRACE_REGS(); 3981ece92f85SJason Jin HALT_SYS(); 3982ece92f85SJason Jin } 3983ece92f85SJason Jin TRACE_AND_STEP(); 3984ece92f85SJason Jin /* note the type change here --- returning AL and AH in AX. */ 3985ece92f85SJason Jin M.x86.R_AX = aam_word(M.x86.R_AL); 3986ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 3987ece92f85SJason Jin END_OF_INSTR(); 3988ece92f85SJason Jin } 3989ece92f85SJason Jin 3990ece92f85SJason Jin /**************************************************************************** 3991ece92f85SJason Jin REMARKS: 3992ece92f85SJason Jin Handles opcode 0xd5 3993ece92f85SJason Jin ****************************************************************************/ 3994ece92f85SJason Jin void x86emuOp_aad(u8 X86EMU_UNUSED(op1)) 3995ece92f85SJason Jin { 3996ece92f85SJason Jin u8 a; 3997ece92f85SJason Jin 3998ece92f85SJason Jin START_OF_INSTR(); 3999ece92f85SJason Jin DECODE_PRINTF("AAD\n"); 4000ece92f85SJason Jin a = fetch_byte_imm(); 4001ece92f85SJason Jin TRACE_AND_STEP(); 4002ece92f85SJason Jin M.x86.R_AX = aad_word(M.x86.R_AX); 4003ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4004ece92f85SJason Jin END_OF_INSTR(); 4005ece92f85SJason Jin } 4006ece92f85SJason Jin 4007ece92f85SJason Jin /* opcode 0xd6 ILLEGAL OPCODE */ 4008ece92f85SJason Jin 4009ece92f85SJason Jin /**************************************************************************** 4010ece92f85SJason Jin REMARKS: 4011ece92f85SJason Jin Handles opcode 0xd7 4012ece92f85SJason Jin ****************************************************************************/ 4013ece92f85SJason Jin void x86emuOp_xlat(u8 X86EMU_UNUSED(op1)) 4014ece92f85SJason Jin { 4015ece92f85SJason Jin u16 addr; 4016ece92f85SJason Jin 4017ece92f85SJason Jin START_OF_INSTR(); 4018ece92f85SJason Jin DECODE_PRINTF("XLAT\n"); 4019ece92f85SJason Jin TRACE_AND_STEP(); 4020ece92f85SJason Jin addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL); 4021ece92f85SJason Jin M.x86.R_AL = fetch_data_byte(addr); 4022ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4023ece92f85SJason Jin END_OF_INSTR(); 4024ece92f85SJason Jin } 4025ece92f85SJason Jin 4026ece92f85SJason Jin /* instuctions D8 .. DF are in i87_ops.c */ 4027ece92f85SJason Jin 4028ece92f85SJason Jin /**************************************************************************** 4029ece92f85SJason Jin REMARKS: 4030ece92f85SJason Jin Handles opcode 0xe0 4031ece92f85SJason Jin ****************************************************************************/ 4032ece92f85SJason Jin void x86emuOp_loopne(u8 X86EMU_UNUSED(op1)) 4033ece92f85SJason Jin { 4034ece92f85SJason Jin s16 ip; 4035ece92f85SJason Jin 4036ece92f85SJason Jin START_OF_INSTR(); 4037ece92f85SJason Jin DECODE_PRINTF("LOOPNE\t"); 4038ece92f85SJason Jin ip = (s8) fetch_byte_imm(); 4039ece92f85SJason Jin ip += (s16) M.x86.R_IP; 4040ece92f85SJason Jin DECODE_PRINTF2("%04x\n", ip); 4041ece92f85SJason Jin TRACE_AND_STEP(); 4042ece92f85SJason Jin M.x86.R_CX -= 1; 4043ece92f85SJason Jin if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */ 4044ece92f85SJason Jin M.x86.R_IP = ip; 4045ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4046ece92f85SJason Jin END_OF_INSTR(); 4047ece92f85SJason Jin } 4048ece92f85SJason Jin 4049ece92f85SJason Jin /**************************************************************************** 4050ece92f85SJason Jin REMARKS: 4051ece92f85SJason Jin Handles opcode 0xe1 4052ece92f85SJason Jin ****************************************************************************/ 4053ece92f85SJason Jin void x86emuOp_loope(u8 X86EMU_UNUSED(op1)) 4054ece92f85SJason Jin { 4055ece92f85SJason Jin s16 ip; 4056ece92f85SJason Jin 4057ece92f85SJason Jin START_OF_INSTR(); 4058ece92f85SJason Jin DECODE_PRINTF("LOOPE\t"); 4059ece92f85SJason Jin ip = (s8) fetch_byte_imm(); 4060ece92f85SJason Jin ip += (s16) M.x86.R_IP; 4061ece92f85SJason Jin DECODE_PRINTF2("%04x\n", ip); 4062ece92f85SJason Jin TRACE_AND_STEP(); 4063ece92f85SJason Jin M.x86.R_CX -= 1; 4064ece92f85SJason Jin if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */ 4065ece92f85SJason Jin M.x86.R_IP = ip; 4066ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4067ece92f85SJason Jin END_OF_INSTR(); 4068ece92f85SJason Jin } 4069ece92f85SJason Jin 4070ece92f85SJason Jin /**************************************************************************** 4071ece92f85SJason Jin REMARKS: 4072ece92f85SJason Jin Handles opcode 0xe2 4073ece92f85SJason Jin ****************************************************************************/ 4074ece92f85SJason Jin void x86emuOp_loop(u8 X86EMU_UNUSED(op1)) 4075ece92f85SJason Jin { 4076ece92f85SJason Jin s16 ip; 4077ece92f85SJason Jin 4078ece92f85SJason Jin START_OF_INSTR(); 4079ece92f85SJason Jin DECODE_PRINTF("LOOP\t"); 4080ece92f85SJason Jin ip = (s8) fetch_byte_imm(); 4081ece92f85SJason Jin ip += (s16) M.x86.R_IP; 4082ece92f85SJason Jin DECODE_PRINTF2("%04x\n", ip); 4083ece92f85SJason Jin TRACE_AND_STEP(); 4084ece92f85SJason Jin M.x86.R_CX -= 1; 4085ece92f85SJason Jin if (M.x86.R_CX != 0) 4086ece92f85SJason Jin M.x86.R_IP = ip; 4087ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4088ece92f85SJason Jin END_OF_INSTR(); 4089ece92f85SJason Jin } 4090ece92f85SJason Jin 4091ece92f85SJason Jin /**************************************************************************** 4092ece92f85SJason Jin REMARKS: 4093ece92f85SJason Jin Handles opcode 0xe3 4094ece92f85SJason Jin ****************************************************************************/ 4095ece92f85SJason Jin void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1)) 4096ece92f85SJason Jin { 4097ece92f85SJason Jin u16 target; 4098ece92f85SJason Jin s8 offset; 4099ece92f85SJason Jin 4100ece92f85SJason Jin /* jump to byte offset if overflow flag is set */ 4101ece92f85SJason Jin START_OF_INSTR(); 4102ece92f85SJason Jin DECODE_PRINTF("JCXZ\t"); 4103ece92f85SJason Jin offset = (s8)fetch_byte_imm(); 4104ece92f85SJason Jin target = (u16)(M.x86.R_IP + offset); 4105ece92f85SJason Jin DECODE_PRINTF2("%x\n", target); 4106ece92f85SJason Jin TRACE_AND_STEP(); 4107ece92f85SJason Jin if (M.x86.R_CX == 0) 4108ece92f85SJason Jin M.x86.R_IP = target; 4109ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4110ece92f85SJason Jin END_OF_INSTR(); 4111ece92f85SJason Jin } 4112ece92f85SJason Jin 4113ece92f85SJason Jin /**************************************************************************** 4114ece92f85SJason Jin REMARKS: 4115ece92f85SJason Jin Handles opcode 0xe4 4116ece92f85SJason Jin ****************************************************************************/ 4117ece92f85SJason Jin void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1)) 4118ece92f85SJason Jin { 4119ece92f85SJason Jin u8 port; 4120ece92f85SJason Jin 4121ece92f85SJason Jin START_OF_INSTR(); 4122ece92f85SJason Jin DECODE_PRINTF("IN\t"); 4123ece92f85SJason Jin port = (u8) fetch_byte_imm(); 4124ece92f85SJason Jin DECODE_PRINTF2("%x,AL\n", port); 4125ece92f85SJason Jin TRACE_AND_STEP(); 4126ece92f85SJason Jin M.x86.R_AL = (*sys_inb)(port); 4127ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4128ece92f85SJason Jin END_OF_INSTR(); 4129ece92f85SJason Jin } 4130ece92f85SJason Jin 4131ece92f85SJason Jin /**************************************************************************** 4132ece92f85SJason Jin REMARKS: 4133ece92f85SJason Jin Handles opcode 0xe5 4134ece92f85SJason Jin ****************************************************************************/ 4135ece92f85SJason Jin void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1)) 4136ece92f85SJason Jin { 4137ece92f85SJason Jin u8 port; 4138ece92f85SJason Jin 4139ece92f85SJason Jin START_OF_INSTR(); 4140ece92f85SJason Jin DECODE_PRINTF("IN\t"); 4141ece92f85SJason Jin port = (u8) fetch_byte_imm(); 4142ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4143ece92f85SJason Jin DECODE_PRINTF2("EAX,%x\n", port); 4144ece92f85SJason Jin } else { 4145ece92f85SJason Jin DECODE_PRINTF2("AX,%x\n", port); 4146ece92f85SJason Jin } 4147ece92f85SJason Jin TRACE_AND_STEP(); 4148ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4149ece92f85SJason Jin M.x86.R_EAX = (*sys_inl)(port); 4150ece92f85SJason Jin } else { 4151ece92f85SJason Jin M.x86.R_AX = (*sys_inw)(port); 4152ece92f85SJason Jin } 4153ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4154ece92f85SJason Jin END_OF_INSTR(); 4155ece92f85SJason Jin } 4156ece92f85SJason Jin 4157ece92f85SJason Jin /**************************************************************************** 4158ece92f85SJason Jin REMARKS: 4159ece92f85SJason Jin Handles opcode 0xe6 4160ece92f85SJason Jin ****************************************************************************/ 4161ece92f85SJason Jin void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1)) 4162ece92f85SJason Jin { 4163ece92f85SJason Jin u8 port; 4164ece92f85SJason Jin 4165ece92f85SJason Jin START_OF_INSTR(); 4166ece92f85SJason Jin DECODE_PRINTF("OUT\t"); 4167ece92f85SJason Jin port = (u8) fetch_byte_imm(); 4168ece92f85SJason Jin DECODE_PRINTF2("%x,AL\n", port); 4169ece92f85SJason Jin TRACE_AND_STEP(); 4170ece92f85SJason Jin (*sys_outb)(port, M.x86.R_AL); 4171ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4172ece92f85SJason Jin END_OF_INSTR(); 4173ece92f85SJason Jin } 4174ece92f85SJason Jin 4175ece92f85SJason Jin /**************************************************************************** 4176ece92f85SJason Jin REMARKS: 4177ece92f85SJason Jin Handles opcode 0xe7 4178ece92f85SJason Jin ****************************************************************************/ 4179ece92f85SJason Jin void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1)) 4180ece92f85SJason Jin { 4181ece92f85SJason Jin u8 port; 4182ece92f85SJason Jin 4183ece92f85SJason Jin START_OF_INSTR(); 4184ece92f85SJason Jin DECODE_PRINTF("OUT\t"); 4185ece92f85SJason Jin port = (u8) fetch_byte_imm(); 4186ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4187ece92f85SJason Jin DECODE_PRINTF2("%x,EAX\n", port); 4188ece92f85SJason Jin } else { 4189ece92f85SJason Jin DECODE_PRINTF2("%x,AX\n", port); 4190ece92f85SJason Jin } 4191ece92f85SJason Jin TRACE_AND_STEP(); 4192ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4193ece92f85SJason Jin (*sys_outl)(port, M.x86.R_EAX); 4194ece92f85SJason Jin } else { 4195ece92f85SJason Jin (*sys_outw)(port, M.x86.R_AX); 4196ece92f85SJason Jin } 4197ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4198ece92f85SJason Jin END_OF_INSTR(); 4199ece92f85SJason Jin } 4200ece92f85SJason Jin 4201ece92f85SJason Jin /**************************************************************************** 4202ece92f85SJason Jin REMARKS: 4203ece92f85SJason Jin Handles opcode 0xe8 4204ece92f85SJason Jin ****************************************************************************/ 4205ece92f85SJason Jin void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1)) 4206ece92f85SJason Jin { 4207ece92f85SJason Jin s16 ip; 4208ece92f85SJason Jin 4209ece92f85SJason Jin START_OF_INSTR(); 4210ece92f85SJason Jin DECODE_PRINTF("CALL\t"); 4211ece92f85SJason Jin ip = (s16) fetch_word_imm(); 4212ece92f85SJason Jin ip += (s16) M.x86.R_IP; /* CHECK SIGN */ 4213ece92f85SJason Jin DECODE_PRINTF2("%04x\n", ip); 4214ece92f85SJason Jin CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, ""); 4215ece92f85SJason Jin TRACE_AND_STEP(); 4216ece92f85SJason Jin push_word(M.x86.R_IP); 4217ece92f85SJason Jin M.x86.R_IP = ip; 4218ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4219ece92f85SJason Jin END_OF_INSTR(); 4220ece92f85SJason Jin } 4221ece92f85SJason Jin 4222ece92f85SJason Jin /**************************************************************************** 4223ece92f85SJason Jin REMARKS: 4224ece92f85SJason Jin Handles opcode 0xe9 4225ece92f85SJason Jin ****************************************************************************/ 4226ece92f85SJason Jin void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1)) 4227ece92f85SJason Jin { 4228ece92f85SJason Jin int ip; 4229ece92f85SJason Jin 4230ece92f85SJason Jin START_OF_INSTR(); 4231ece92f85SJason Jin DECODE_PRINTF("JMP\t"); 4232ece92f85SJason Jin ip = (s16)fetch_word_imm(); 4233ece92f85SJason Jin ip += (s16)M.x86.R_IP; 4234ece92f85SJason Jin DECODE_PRINTF2("%04x\n", ip); 4235ece92f85SJason Jin TRACE_AND_STEP(); 4236ece92f85SJason Jin M.x86.R_IP = (u16)ip; 4237ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4238ece92f85SJason Jin END_OF_INSTR(); 4239ece92f85SJason Jin } 4240ece92f85SJason Jin 4241ece92f85SJason Jin /**************************************************************************** 4242ece92f85SJason Jin REMARKS: 4243ece92f85SJason Jin Handles opcode 0xea 4244ece92f85SJason Jin ****************************************************************************/ 4245ece92f85SJason Jin void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1)) 4246ece92f85SJason Jin { 4247ece92f85SJason Jin u16 cs, ip; 4248ece92f85SJason Jin 4249ece92f85SJason Jin START_OF_INSTR(); 4250ece92f85SJason Jin DECODE_PRINTF("JMP\tFAR "); 4251ece92f85SJason Jin ip = fetch_word_imm(); 4252ece92f85SJason Jin cs = fetch_word_imm(); 4253ece92f85SJason Jin DECODE_PRINTF2("%04x:", cs); 4254ece92f85SJason Jin DECODE_PRINTF2("%04x\n", ip); 4255ece92f85SJason Jin TRACE_AND_STEP(); 4256ece92f85SJason Jin M.x86.R_IP = ip; 4257ece92f85SJason Jin M.x86.R_CS = cs; 4258ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4259ece92f85SJason Jin END_OF_INSTR(); 4260ece92f85SJason Jin } 4261ece92f85SJason Jin 4262ece92f85SJason Jin /**************************************************************************** 4263ece92f85SJason Jin REMARKS: 4264ece92f85SJason Jin Handles opcode 0xeb 4265ece92f85SJason Jin ****************************************************************************/ 4266ece92f85SJason Jin void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1)) 4267ece92f85SJason Jin { 4268ece92f85SJason Jin u16 target; 4269ece92f85SJason Jin s8 offset; 4270ece92f85SJason Jin 4271ece92f85SJason Jin START_OF_INSTR(); 4272ece92f85SJason Jin DECODE_PRINTF("JMP\t"); 4273ece92f85SJason Jin offset = (s8)fetch_byte_imm(); 4274ece92f85SJason Jin target = (u16)(M.x86.R_IP + offset); 4275ece92f85SJason Jin DECODE_PRINTF2("%x\n", target); 4276ece92f85SJason Jin TRACE_AND_STEP(); 4277ece92f85SJason Jin M.x86.R_IP = target; 4278ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4279ece92f85SJason Jin END_OF_INSTR(); 4280ece92f85SJason Jin } 4281ece92f85SJason Jin 4282ece92f85SJason Jin /**************************************************************************** 4283ece92f85SJason Jin REMARKS: 4284ece92f85SJason Jin Handles opcode 0xec 4285ece92f85SJason Jin ****************************************************************************/ 4286ece92f85SJason Jin void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1)) 4287ece92f85SJason Jin { 4288ece92f85SJason Jin START_OF_INSTR(); 4289ece92f85SJason Jin DECODE_PRINTF("IN\tAL,DX\n"); 4290ece92f85SJason Jin TRACE_AND_STEP(); 4291ece92f85SJason Jin M.x86.R_AL = (*sys_inb)(M.x86.R_DX); 4292ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4293ece92f85SJason Jin END_OF_INSTR(); 4294ece92f85SJason Jin } 4295ece92f85SJason Jin 4296ece92f85SJason Jin /**************************************************************************** 4297ece92f85SJason Jin REMARKS: 4298ece92f85SJason Jin Handles opcode 0xed 4299ece92f85SJason Jin ****************************************************************************/ 4300ece92f85SJason Jin void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1)) 4301ece92f85SJason Jin { 4302ece92f85SJason Jin START_OF_INSTR(); 4303ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4304ece92f85SJason Jin DECODE_PRINTF("IN\tEAX,DX\n"); 4305ece92f85SJason Jin } else { 4306ece92f85SJason Jin DECODE_PRINTF("IN\tAX,DX\n"); 4307ece92f85SJason Jin } 4308ece92f85SJason Jin TRACE_AND_STEP(); 4309ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4310ece92f85SJason Jin M.x86.R_EAX = (*sys_inl)(M.x86.R_DX); 4311ece92f85SJason Jin } else { 4312ece92f85SJason Jin M.x86.R_AX = (*sys_inw)(M.x86.R_DX); 4313ece92f85SJason Jin } 4314ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4315ece92f85SJason Jin END_OF_INSTR(); 4316ece92f85SJason Jin } 4317ece92f85SJason Jin 4318ece92f85SJason Jin /**************************************************************************** 4319ece92f85SJason Jin REMARKS: 4320ece92f85SJason Jin Handles opcode 0xee 4321ece92f85SJason Jin ****************************************************************************/ 4322ece92f85SJason Jin void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1)) 4323ece92f85SJason Jin { 4324ece92f85SJason Jin START_OF_INSTR(); 4325ece92f85SJason Jin DECODE_PRINTF("OUT\tDX,AL\n"); 4326ece92f85SJason Jin TRACE_AND_STEP(); 4327ece92f85SJason Jin (*sys_outb)(M.x86.R_DX, M.x86.R_AL); 4328ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4329ece92f85SJason Jin END_OF_INSTR(); 4330ece92f85SJason Jin } 4331ece92f85SJason Jin 4332ece92f85SJason Jin /**************************************************************************** 4333ece92f85SJason Jin REMARKS: 4334ece92f85SJason Jin Handles opcode 0xef 4335ece92f85SJason Jin ****************************************************************************/ 4336ece92f85SJason Jin void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1)) 4337ece92f85SJason Jin { 4338ece92f85SJason Jin START_OF_INSTR(); 4339ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4340ece92f85SJason Jin DECODE_PRINTF("OUT\tDX,EAX\n"); 4341ece92f85SJason Jin } else { 4342ece92f85SJason Jin DECODE_PRINTF("OUT\tDX,AX\n"); 4343ece92f85SJason Jin } 4344ece92f85SJason Jin TRACE_AND_STEP(); 4345ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4346ece92f85SJason Jin (*sys_outl)(M.x86.R_DX, M.x86.R_EAX); 4347ece92f85SJason Jin } else { 4348ece92f85SJason Jin (*sys_outw)(M.x86.R_DX, M.x86.R_AX); 4349ece92f85SJason Jin } 4350ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4351ece92f85SJason Jin END_OF_INSTR(); 4352ece92f85SJason Jin } 4353ece92f85SJason Jin 4354ece92f85SJason Jin /**************************************************************************** 4355ece92f85SJason Jin REMARKS: 4356ece92f85SJason Jin Handles opcode 0xf0 4357ece92f85SJason Jin ****************************************************************************/ 4358ece92f85SJason Jin void x86emuOp_lock(u8 X86EMU_UNUSED(op1)) 4359ece92f85SJason Jin { 4360ece92f85SJason Jin START_OF_INSTR(); 4361ece92f85SJason Jin DECODE_PRINTF("LOCK:\n"); 4362ece92f85SJason Jin TRACE_AND_STEP(); 4363ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4364ece92f85SJason Jin END_OF_INSTR(); 4365ece92f85SJason Jin } 4366ece92f85SJason Jin 4367ece92f85SJason Jin /*opcode 0xf1 ILLEGAL OPERATION */ 4368ece92f85SJason Jin 4369ece92f85SJason Jin /**************************************************************************** 4370ece92f85SJason Jin REMARKS: 4371ece92f85SJason Jin Handles opcode 0xf2 4372ece92f85SJason Jin ****************************************************************************/ 4373ece92f85SJason Jin void x86emuOp_repne(u8 X86EMU_UNUSED(op1)) 4374ece92f85SJason Jin { 4375ece92f85SJason Jin START_OF_INSTR(); 4376ece92f85SJason Jin DECODE_PRINTF("REPNE\n"); 4377ece92f85SJason Jin TRACE_AND_STEP(); 4378ece92f85SJason Jin M.x86.mode |= SYSMODE_PREFIX_REPNE; 4379ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4380ece92f85SJason Jin END_OF_INSTR(); 4381ece92f85SJason Jin } 4382ece92f85SJason Jin 4383ece92f85SJason Jin /**************************************************************************** 4384ece92f85SJason Jin REMARKS: 4385ece92f85SJason Jin Handles opcode 0xf3 4386ece92f85SJason Jin ****************************************************************************/ 4387ece92f85SJason Jin void x86emuOp_repe(u8 X86EMU_UNUSED(op1)) 4388ece92f85SJason Jin { 4389ece92f85SJason Jin START_OF_INSTR(); 4390ece92f85SJason Jin DECODE_PRINTF("REPE\n"); 4391ece92f85SJason Jin TRACE_AND_STEP(); 4392ece92f85SJason Jin M.x86.mode |= SYSMODE_PREFIX_REPE; 4393ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4394ece92f85SJason Jin END_OF_INSTR(); 4395ece92f85SJason Jin } 4396ece92f85SJason Jin 4397ece92f85SJason Jin /**************************************************************************** 4398ece92f85SJason Jin REMARKS: 4399ece92f85SJason Jin Handles opcode 0xf4 4400ece92f85SJason Jin ****************************************************************************/ 4401ece92f85SJason Jin void x86emuOp_halt(u8 X86EMU_UNUSED(op1)) 4402ece92f85SJason Jin { 4403ece92f85SJason Jin START_OF_INSTR(); 4404ece92f85SJason Jin DECODE_PRINTF("HALT\n"); 4405ece92f85SJason Jin TRACE_AND_STEP(); 4406ece92f85SJason Jin HALT_SYS(); 4407ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4408ece92f85SJason Jin END_OF_INSTR(); 4409ece92f85SJason Jin } 4410ece92f85SJason Jin 4411ece92f85SJason Jin /**************************************************************************** 4412ece92f85SJason Jin REMARKS: 4413ece92f85SJason Jin Handles opcode 0xf5 4414ece92f85SJason Jin ****************************************************************************/ 4415ece92f85SJason Jin void x86emuOp_cmc(u8 X86EMU_UNUSED(op1)) 4416ece92f85SJason Jin { 4417ece92f85SJason Jin /* complement the carry flag. */ 4418ece92f85SJason Jin START_OF_INSTR(); 4419ece92f85SJason Jin DECODE_PRINTF("CMC\n"); 4420ece92f85SJason Jin TRACE_AND_STEP(); 4421ece92f85SJason Jin TOGGLE_FLAG(F_CF); 4422ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4423ece92f85SJason Jin END_OF_INSTR(); 4424ece92f85SJason Jin } 4425ece92f85SJason Jin 4426ece92f85SJason Jin /**************************************************************************** 4427ece92f85SJason Jin REMARKS: 4428ece92f85SJason Jin Handles opcode 0xf6 4429ece92f85SJason Jin ****************************************************************************/ 4430ece92f85SJason Jin void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1)) 4431ece92f85SJason Jin { 4432ece92f85SJason Jin int mod, rl, rh; 4433ece92f85SJason Jin u8 *destreg; 4434ece92f85SJason Jin uint destoffset; 4435ece92f85SJason Jin u8 destval, srcval; 4436ece92f85SJason Jin 4437ece92f85SJason Jin /* long, drawn out code follows. Double switch for a total 4438ece92f85SJason Jin of 32 cases. */ 4439ece92f85SJason Jin START_OF_INSTR(); 4440ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 4441ece92f85SJason Jin DECODE_PRINTF(opF6_names[rh]); 4442ece92f85SJason Jin if (mod < 3) { 4443ece92f85SJason Jin DECODE_PRINTF("BYTE PTR "); 4444ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 4445ece92f85SJason Jin destval = fetch_data_byte(destoffset); 4446ece92f85SJason Jin 4447ece92f85SJason Jin switch (rh) { 4448ece92f85SJason Jin case 0: /* test byte imm */ 4449ece92f85SJason Jin DECODE_PRINTF(","); 4450ece92f85SJason Jin srcval = fetch_byte_imm(); 4451ece92f85SJason Jin DECODE_PRINTF2("%02x\n", srcval); 4452ece92f85SJason Jin TRACE_AND_STEP(); 4453ece92f85SJason Jin test_byte(destval, srcval); 4454ece92f85SJason Jin break; 4455ece92f85SJason Jin case 1: 4456ece92f85SJason Jin DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 4457ece92f85SJason Jin HALT_SYS(); 4458ece92f85SJason Jin break; 4459ece92f85SJason Jin case 2: 4460ece92f85SJason Jin DECODE_PRINTF("\n"); 4461ece92f85SJason Jin TRACE_AND_STEP(); 4462ece92f85SJason Jin destval = not_byte(destval); 4463ece92f85SJason Jin store_data_byte(destoffset, destval); 4464ece92f85SJason Jin break; 4465ece92f85SJason Jin case 3: 4466ece92f85SJason Jin DECODE_PRINTF("\n"); 4467ece92f85SJason Jin TRACE_AND_STEP(); 4468ece92f85SJason Jin destval = neg_byte(destval); 4469ece92f85SJason Jin store_data_byte(destoffset, destval); 4470ece92f85SJason Jin break; 4471ece92f85SJason Jin case 4: 4472ece92f85SJason Jin DECODE_PRINTF("\n"); 4473ece92f85SJason Jin TRACE_AND_STEP(); 4474ece92f85SJason Jin mul_byte(destval); 4475ece92f85SJason Jin break; 4476ece92f85SJason Jin case 5: 4477ece92f85SJason Jin DECODE_PRINTF("\n"); 4478ece92f85SJason Jin TRACE_AND_STEP(); 4479ece92f85SJason Jin imul_byte(destval); 4480ece92f85SJason Jin break; 4481ece92f85SJason Jin case 6: 4482ece92f85SJason Jin DECODE_PRINTF("\n"); 4483ece92f85SJason Jin TRACE_AND_STEP(); 4484ece92f85SJason Jin div_byte(destval); 4485ece92f85SJason Jin break; 4486ece92f85SJason Jin default: 4487ece92f85SJason Jin DECODE_PRINTF("\n"); 4488ece92f85SJason Jin TRACE_AND_STEP(); 4489ece92f85SJason Jin idiv_byte(destval); 4490ece92f85SJason Jin break; 4491ece92f85SJason Jin } 4492ece92f85SJason Jin } else { /* mod=11 */ 4493ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl); 4494ece92f85SJason Jin switch (rh) { 4495ece92f85SJason Jin case 0: /* test byte imm */ 4496ece92f85SJason Jin DECODE_PRINTF(","); 4497ece92f85SJason Jin srcval = fetch_byte_imm(); 4498ece92f85SJason Jin DECODE_PRINTF2("%02x\n", srcval); 4499ece92f85SJason Jin TRACE_AND_STEP(); 4500ece92f85SJason Jin test_byte(*destreg, srcval); 4501ece92f85SJason Jin break; 4502ece92f85SJason Jin case 1: 4503ece92f85SJason Jin DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 4504ece92f85SJason Jin HALT_SYS(); 4505ece92f85SJason Jin break; 4506ece92f85SJason Jin case 2: 4507ece92f85SJason Jin DECODE_PRINTF("\n"); 4508ece92f85SJason Jin TRACE_AND_STEP(); 4509ece92f85SJason Jin *destreg = not_byte(*destreg); 4510ece92f85SJason Jin break; 4511ece92f85SJason Jin case 3: 4512ece92f85SJason Jin DECODE_PRINTF("\n"); 4513ece92f85SJason Jin TRACE_AND_STEP(); 4514ece92f85SJason Jin *destreg = neg_byte(*destreg); 4515ece92f85SJason Jin break; 4516ece92f85SJason Jin case 4: 4517ece92f85SJason Jin DECODE_PRINTF("\n"); 4518ece92f85SJason Jin TRACE_AND_STEP(); 4519ece92f85SJason Jin mul_byte(*destreg); /*!!! */ 4520ece92f85SJason Jin break; 4521ece92f85SJason Jin case 5: 4522ece92f85SJason Jin DECODE_PRINTF("\n"); 4523ece92f85SJason Jin TRACE_AND_STEP(); 4524ece92f85SJason Jin imul_byte(*destreg); 4525ece92f85SJason Jin break; 4526ece92f85SJason Jin case 6: 4527ece92f85SJason Jin DECODE_PRINTF("\n"); 4528ece92f85SJason Jin TRACE_AND_STEP(); 4529ece92f85SJason Jin div_byte(*destreg); 4530ece92f85SJason Jin break; 4531ece92f85SJason Jin default: 4532ece92f85SJason Jin DECODE_PRINTF("\n"); 4533ece92f85SJason Jin TRACE_AND_STEP(); 4534ece92f85SJason Jin idiv_byte(*destreg); 4535ece92f85SJason Jin break; 4536ece92f85SJason Jin } 4537ece92f85SJason Jin } 4538ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4539ece92f85SJason Jin END_OF_INSTR(); 4540ece92f85SJason Jin } 4541ece92f85SJason Jin 4542ece92f85SJason Jin /**************************************************************************** 4543ece92f85SJason Jin REMARKS: 4544ece92f85SJason Jin Handles opcode 0xf7 4545ece92f85SJason Jin ****************************************************************************/ 4546ece92f85SJason Jin void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1)) 4547ece92f85SJason Jin { 4548ece92f85SJason Jin int mod, rl, rh; 4549ece92f85SJason Jin uint destoffset; 4550ece92f85SJason Jin 4551ece92f85SJason Jin START_OF_INSTR(); 4552ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 4553ece92f85SJason Jin DECODE_PRINTF(opF6_names[rh]); 4554ece92f85SJason Jin if (mod < 3) { 4555ece92f85SJason Jin 4556ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4557ece92f85SJason Jin u32 destval, srcval; 4558ece92f85SJason Jin 4559ece92f85SJason Jin DECODE_PRINTF("DWORD PTR "); 4560ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 4561ece92f85SJason Jin destval = fetch_data_long(destoffset); 4562ece92f85SJason Jin 4563ece92f85SJason Jin switch (rh) { 4564ece92f85SJason Jin case 0: 4565ece92f85SJason Jin DECODE_PRINTF(","); 4566ece92f85SJason Jin srcval = fetch_long_imm(); 4567ece92f85SJason Jin DECODE_PRINTF2("%x\n", srcval); 4568ece92f85SJason Jin TRACE_AND_STEP(); 4569ece92f85SJason Jin test_long(destval, srcval); 4570ece92f85SJason Jin break; 4571ece92f85SJason Jin case 1: 4572ece92f85SJason Jin DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n"); 4573ece92f85SJason Jin HALT_SYS(); 4574ece92f85SJason Jin break; 4575ece92f85SJason Jin case 2: 4576ece92f85SJason Jin DECODE_PRINTF("\n"); 4577ece92f85SJason Jin TRACE_AND_STEP(); 4578ece92f85SJason Jin destval = not_long(destval); 4579ece92f85SJason Jin store_data_long(destoffset, destval); 4580ece92f85SJason Jin break; 4581ece92f85SJason Jin case 3: 4582ece92f85SJason Jin DECODE_PRINTF("\n"); 4583ece92f85SJason Jin TRACE_AND_STEP(); 4584ece92f85SJason Jin destval = neg_long(destval); 4585ece92f85SJason Jin store_data_long(destoffset, destval); 4586ece92f85SJason Jin break; 4587ece92f85SJason Jin case 4: 4588ece92f85SJason Jin DECODE_PRINTF("\n"); 4589ece92f85SJason Jin TRACE_AND_STEP(); 4590ece92f85SJason Jin mul_long(destval); 4591ece92f85SJason Jin break; 4592ece92f85SJason Jin case 5: 4593ece92f85SJason Jin DECODE_PRINTF("\n"); 4594ece92f85SJason Jin TRACE_AND_STEP(); 4595ece92f85SJason Jin imul_long(destval); 4596ece92f85SJason Jin break; 4597ece92f85SJason Jin case 6: 4598ece92f85SJason Jin DECODE_PRINTF("\n"); 4599ece92f85SJason Jin TRACE_AND_STEP(); 4600ece92f85SJason Jin div_long(destval); 4601ece92f85SJason Jin break; 4602ece92f85SJason Jin case 7: 4603ece92f85SJason Jin DECODE_PRINTF("\n"); 4604ece92f85SJason Jin TRACE_AND_STEP(); 4605ece92f85SJason Jin idiv_long(destval); 4606ece92f85SJason Jin break; 4607ece92f85SJason Jin } 4608ece92f85SJason Jin } else { 4609ece92f85SJason Jin u16 destval, srcval; 4610ece92f85SJason Jin 4611ece92f85SJason Jin DECODE_PRINTF("WORD PTR "); 4612ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 4613ece92f85SJason Jin destval = fetch_data_word(destoffset); 4614ece92f85SJason Jin 4615ece92f85SJason Jin switch (rh) { 4616ece92f85SJason Jin case 0: /* test word imm */ 4617ece92f85SJason Jin DECODE_PRINTF(","); 4618ece92f85SJason Jin srcval = fetch_word_imm(); 4619ece92f85SJason Jin DECODE_PRINTF2("%x\n", srcval); 4620ece92f85SJason Jin TRACE_AND_STEP(); 4621ece92f85SJason Jin test_word(destval, srcval); 4622ece92f85SJason Jin break; 4623ece92f85SJason Jin case 1: 4624ece92f85SJason Jin DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n"); 4625ece92f85SJason Jin HALT_SYS(); 4626ece92f85SJason Jin break; 4627ece92f85SJason Jin case 2: 4628ece92f85SJason Jin DECODE_PRINTF("\n"); 4629ece92f85SJason Jin TRACE_AND_STEP(); 4630ece92f85SJason Jin destval = not_word(destval); 4631ece92f85SJason Jin store_data_word(destoffset, destval); 4632ece92f85SJason Jin break; 4633ece92f85SJason Jin case 3: 4634ece92f85SJason Jin DECODE_PRINTF("\n"); 4635ece92f85SJason Jin TRACE_AND_STEP(); 4636ece92f85SJason Jin destval = neg_word(destval); 4637ece92f85SJason Jin store_data_word(destoffset, destval); 4638ece92f85SJason Jin break; 4639ece92f85SJason Jin case 4: 4640ece92f85SJason Jin DECODE_PRINTF("\n"); 4641ece92f85SJason Jin TRACE_AND_STEP(); 4642ece92f85SJason Jin mul_word(destval); 4643ece92f85SJason Jin break; 4644ece92f85SJason Jin case 5: 4645ece92f85SJason Jin DECODE_PRINTF("\n"); 4646ece92f85SJason Jin TRACE_AND_STEP(); 4647ece92f85SJason Jin imul_word(destval); 4648ece92f85SJason Jin break; 4649ece92f85SJason Jin case 6: 4650ece92f85SJason Jin DECODE_PRINTF("\n"); 4651ece92f85SJason Jin TRACE_AND_STEP(); 4652ece92f85SJason Jin div_word(destval); 4653ece92f85SJason Jin break; 4654ece92f85SJason Jin case 7: 4655ece92f85SJason Jin DECODE_PRINTF("\n"); 4656ece92f85SJason Jin TRACE_AND_STEP(); 4657ece92f85SJason Jin idiv_word(destval); 4658ece92f85SJason Jin break; 4659ece92f85SJason Jin } 4660ece92f85SJason Jin } 4661ece92f85SJason Jin 4662ece92f85SJason Jin } else { /* mod=11 */ 4663ece92f85SJason Jin 4664ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4665ece92f85SJason Jin u32 *destreg; 4666ece92f85SJason Jin u32 srcval; 4667ece92f85SJason Jin 4668ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 4669ece92f85SJason Jin 4670ece92f85SJason Jin switch (rh) { 4671ece92f85SJason Jin case 0: /* test word imm */ 4672ece92f85SJason Jin DECODE_PRINTF(","); 4673ece92f85SJason Jin srcval = fetch_long_imm(); 4674ece92f85SJason Jin DECODE_PRINTF2("%x\n", srcval); 4675ece92f85SJason Jin TRACE_AND_STEP(); 4676ece92f85SJason Jin test_long(*destreg, srcval); 4677ece92f85SJason Jin break; 4678ece92f85SJason Jin case 1: 4679ece92f85SJason Jin DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 4680ece92f85SJason Jin HALT_SYS(); 4681ece92f85SJason Jin break; 4682ece92f85SJason Jin case 2: 4683ece92f85SJason Jin DECODE_PRINTF("\n"); 4684ece92f85SJason Jin TRACE_AND_STEP(); 4685ece92f85SJason Jin *destreg = not_long(*destreg); 4686ece92f85SJason Jin break; 4687ece92f85SJason Jin case 3: 4688ece92f85SJason Jin DECODE_PRINTF("\n"); 4689ece92f85SJason Jin TRACE_AND_STEP(); 4690ece92f85SJason Jin *destreg = neg_long(*destreg); 4691ece92f85SJason Jin break; 4692ece92f85SJason Jin case 4: 4693ece92f85SJason Jin DECODE_PRINTF("\n"); 4694ece92f85SJason Jin TRACE_AND_STEP(); 4695ece92f85SJason Jin mul_long(*destreg); /*!!! */ 4696ece92f85SJason Jin break; 4697ece92f85SJason Jin case 5: 4698ece92f85SJason Jin DECODE_PRINTF("\n"); 4699ece92f85SJason Jin TRACE_AND_STEP(); 4700ece92f85SJason Jin imul_long(*destreg); 4701ece92f85SJason Jin break; 4702ece92f85SJason Jin case 6: 4703ece92f85SJason Jin DECODE_PRINTF("\n"); 4704ece92f85SJason Jin TRACE_AND_STEP(); 4705ece92f85SJason Jin div_long(*destreg); 4706ece92f85SJason Jin break; 4707ece92f85SJason Jin case 7: 4708ece92f85SJason Jin DECODE_PRINTF("\n"); 4709ece92f85SJason Jin TRACE_AND_STEP(); 4710ece92f85SJason Jin idiv_long(*destreg); 4711ece92f85SJason Jin break; 4712ece92f85SJason Jin } 4713ece92f85SJason Jin } else { 4714ece92f85SJason Jin u16 *destreg; 4715ece92f85SJason Jin u16 srcval; 4716ece92f85SJason Jin 4717ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 4718ece92f85SJason Jin 4719ece92f85SJason Jin switch (rh) { 4720ece92f85SJason Jin case 0: /* test word imm */ 4721ece92f85SJason Jin DECODE_PRINTF(","); 4722ece92f85SJason Jin srcval = fetch_word_imm(); 4723ece92f85SJason Jin DECODE_PRINTF2("%x\n", srcval); 4724ece92f85SJason Jin TRACE_AND_STEP(); 4725ece92f85SJason Jin test_word(*destreg, srcval); 4726ece92f85SJason Jin break; 4727ece92f85SJason Jin case 1: 4728ece92f85SJason Jin DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n"); 4729ece92f85SJason Jin HALT_SYS(); 4730ece92f85SJason Jin break; 4731ece92f85SJason Jin case 2: 4732ece92f85SJason Jin DECODE_PRINTF("\n"); 4733ece92f85SJason Jin TRACE_AND_STEP(); 4734ece92f85SJason Jin *destreg = not_word(*destreg); 4735ece92f85SJason Jin break; 4736ece92f85SJason Jin case 3: 4737ece92f85SJason Jin DECODE_PRINTF("\n"); 4738ece92f85SJason Jin TRACE_AND_STEP(); 4739ece92f85SJason Jin *destreg = neg_word(*destreg); 4740ece92f85SJason Jin break; 4741ece92f85SJason Jin case 4: 4742ece92f85SJason Jin DECODE_PRINTF("\n"); 4743ece92f85SJason Jin TRACE_AND_STEP(); 4744ece92f85SJason Jin mul_word(*destreg); /*!!! */ 4745ece92f85SJason Jin break; 4746ece92f85SJason Jin case 5: 4747ece92f85SJason Jin DECODE_PRINTF("\n"); 4748ece92f85SJason Jin TRACE_AND_STEP(); 4749ece92f85SJason Jin imul_word(*destreg); 4750ece92f85SJason Jin break; 4751ece92f85SJason Jin case 6: 4752ece92f85SJason Jin DECODE_PRINTF("\n"); 4753ece92f85SJason Jin TRACE_AND_STEP(); 4754ece92f85SJason Jin div_word(*destreg); 4755ece92f85SJason Jin break; 4756ece92f85SJason Jin case 7: 4757ece92f85SJason Jin DECODE_PRINTF("\n"); 4758ece92f85SJason Jin TRACE_AND_STEP(); 4759ece92f85SJason Jin idiv_word(*destreg); 4760ece92f85SJason Jin break; 4761ece92f85SJason Jin } 4762ece92f85SJason Jin } 4763ece92f85SJason Jin } 4764ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4765ece92f85SJason Jin END_OF_INSTR(); 4766ece92f85SJason Jin } 4767ece92f85SJason Jin 4768ece92f85SJason Jin /**************************************************************************** 4769ece92f85SJason Jin REMARKS: 4770ece92f85SJason Jin Handles opcode 0xf8 4771ece92f85SJason Jin ****************************************************************************/ 4772ece92f85SJason Jin void x86emuOp_clc(u8 X86EMU_UNUSED(op1)) 4773ece92f85SJason Jin { 4774ece92f85SJason Jin /* clear the carry flag. */ 4775ece92f85SJason Jin START_OF_INSTR(); 4776ece92f85SJason Jin DECODE_PRINTF("CLC\n"); 4777ece92f85SJason Jin TRACE_AND_STEP(); 4778ece92f85SJason Jin CLEAR_FLAG(F_CF); 4779ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4780ece92f85SJason Jin END_OF_INSTR(); 4781ece92f85SJason Jin } 4782ece92f85SJason Jin 4783ece92f85SJason Jin /**************************************************************************** 4784ece92f85SJason Jin REMARKS: 4785ece92f85SJason Jin Handles opcode 0xf9 4786ece92f85SJason Jin ****************************************************************************/ 4787ece92f85SJason Jin void x86emuOp_stc(u8 X86EMU_UNUSED(op1)) 4788ece92f85SJason Jin { 4789ece92f85SJason Jin /* set the carry flag. */ 4790ece92f85SJason Jin START_OF_INSTR(); 4791ece92f85SJason Jin DECODE_PRINTF("STC\n"); 4792ece92f85SJason Jin TRACE_AND_STEP(); 4793ece92f85SJason Jin SET_FLAG(F_CF); 4794ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4795ece92f85SJason Jin END_OF_INSTR(); 4796ece92f85SJason Jin } 4797ece92f85SJason Jin 4798ece92f85SJason Jin /**************************************************************************** 4799ece92f85SJason Jin REMARKS: 4800ece92f85SJason Jin Handles opcode 0xfa 4801ece92f85SJason Jin ****************************************************************************/ 4802ece92f85SJason Jin void x86emuOp_cli(u8 X86EMU_UNUSED(op1)) 4803ece92f85SJason Jin { 4804ece92f85SJason Jin /* clear interrupts. */ 4805ece92f85SJason Jin START_OF_INSTR(); 4806ece92f85SJason Jin DECODE_PRINTF("CLI\n"); 4807ece92f85SJason Jin TRACE_AND_STEP(); 4808ece92f85SJason Jin CLEAR_FLAG(F_IF); 4809ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4810ece92f85SJason Jin END_OF_INSTR(); 4811ece92f85SJason Jin } 4812ece92f85SJason Jin 4813ece92f85SJason Jin /**************************************************************************** 4814ece92f85SJason Jin REMARKS: 4815ece92f85SJason Jin Handles opcode 0xfb 4816ece92f85SJason Jin ****************************************************************************/ 4817ece92f85SJason Jin void x86emuOp_sti(u8 X86EMU_UNUSED(op1)) 4818ece92f85SJason Jin { 4819ece92f85SJason Jin /* enable interrupts. */ 4820ece92f85SJason Jin START_OF_INSTR(); 4821ece92f85SJason Jin DECODE_PRINTF("STI\n"); 4822ece92f85SJason Jin TRACE_AND_STEP(); 4823ece92f85SJason Jin SET_FLAG(F_IF); 4824ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4825ece92f85SJason Jin END_OF_INSTR(); 4826ece92f85SJason Jin } 4827ece92f85SJason Jin 4828ece92f85SJason Jin /**************************************************************************** 4829ece92f85SJason Jin REMARKS: 4830ece92f85SJason Jin Handles opcode 0xfc 4831ece92f85SJason Jin ****************************************************************************/ 4832ece92f85SJason Jin void x86emuOp_cld(u8 X86EMU_UNUSED(op1)) 4833ece92f85SJason Jin { 4834ece92f85SJason Jin /* clear interrupts. */ 4835ece92f85SJason Jin START_OF_INSTR(); 4836ece92f85SJason Jin DECODE_PRINTF("CLD\n"); 4837ece92f85SJason Jin TRACE_AND_STEP(); 4838ece92f85SJason Jin CLEAR_FLAG(F_DF); 4839ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4840ece92f85SJason Jin END_OF_INSTR(); 4841ece92f85SJason Jin } 4842ece92f85SJason Jin 4843ece92f85SJason Jin /**************************************************************************** 4844ece92f85SJason Jin REMARKS: 4845ece92f85SJason Jin Handles opcode 0xfd 4846ece92f85SJason Jin ****************************************************************************/ 4847ece92f85SJason Jin void x86emuOp_std(u8 X86EMU_UNUSED(op1)) 4848ece92f85SJason Jin { 4849ece92f85SJason Jin /* clear interrupts. */ 4850ece92f85SJason Jin START_OF_INSTR(); 4851ece92f85SJason Jin DECODE_PRINTF("STD\n"); 4852ece92f85SJason Jin TRACE_AND_STEP(); 4853ece92f85SJason Jin SET_FLAG(F_DF); 4854ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4855ece92f85SJason Jin END_OF_INSTR(); 4856ece92f85SJason Jin } 4857ece92f85SJason Jin 4858ece92f85SJason Jin /**************************************************************************** 4859ece92f85SJason Jin REMARKS: 4860ece92f85SJason Jin Handles opcode 0xfe 4861ece92f85SJason Jin ****************************************************************************/ 4862ece92f85SJason Jin void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1)) 4863ece92f85SJason Jin { 4864ece92f85SJason Jin int mod, rh, rl; 4865ece92f85SJason Jin u8 destval; 4866ece92f85SJason Jin uint destoffset; 4867ece92f85SJason Jin u8 *destreg; 4868ece92f85SJason Jin 4869ece92f85SJason Jin /* Yet another special case instruction. */ 4870ece92f85SJason Jin START_OF_INSTR(); 4871ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 4872ece92f85SJason Jin #ifdef DEBUG 4873ece92f85SJason Jin if (DEBUG_DECODE()) { 4874ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more 4875ece92f85SJason Jin general, so that it is important to leave the strings 4876ece92f85SJason Jin in the same format, even though the result is that the 4877ece92f85SJason Jin above test is done twice. */ 4878ece92f85SJason Jin 4879ece92f85SJason Jin switch (rh) { 4880ece92f85SJason Jin case 0: 4881ece92f85SJason Jin DECODE_PRINTF("INC\t"); 4882ece92f85SJason Jin break; 4883ece92f85SJason Jin case 1: 4884ece92f85SJason Jin DECODE_PRINTF("DEC\t"); 4885ece92f85SJason Jin break; 4886ece92f85SJason Jin case 2: 4887ece92f85SJason Jin case 3: 4888ece92f85SJason Jin case 4: 4889ece92f85SJason Jin case 5: 4890ece92f85SJason Jin case 6: 4891ece92f85SJason Jin case 7: 4892ece92f85SJason Jin DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod); 4893ece92f85SJason Jin HALT_SYS(); 4894ece92f85SJason Jin break; 4895ece92f85SJason Jin } 4896ece92f85SJason Jin } 4897ece92f85SJason Jin #endif 4898ece92f85SJason Jin if (mod < 3) { 4899ece92f85SJason Jin DECODE_PRINTF("BYTE PTR "); 4900ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 4901ece92f85SJason Jin DECODE_PRINTF("\n"); 4902ece92f85SJason Jin destval = fetch_data_byte(destoffset); 4903ece92f85SJason Jin TRACE_AND_STEP(); 4904ece92f85SJason Jin if (rh == 0) 4905ece92f85SJason Jin destval = inc_byte(destval); 4906ece92f85SJason Jin else 4907ece92f85SJason Jin destval = dec_byte(destval); 4908ece92f85SJason Jin store_data_byte(destoffset, destval); 4909ece92f85SJason Jin } else { 4910ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl); 4911ece92f85SJason Jin DECODE_PRINTF("\n"); 4912ece92f85SJason Jin TRACE_AND_STEP(); 4913ece92f85SJason Jin if (rh == 0) 4914ece92f85SJason Jin *destreg = inc_byte(*destreg); 4915ece92f85SJason Jin else 4916ece92f85SJason Jin *destreg = dec_byte(*destreg); 4917ece92f85SJason Jin } 4918ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 4919ece92f85SJason Jin END_OF_INSTR(); 4920ece92f85SJason Jin } 4921ece92f85SJason Jin 4922ece92f85SJason Jin /**************************************************************************** 4923ece92f85SJason Jin REMARKS: 4924ece92f85SJason Jin Handles opcode 0xff 4925ece92f85SJason Jin ****************************************************************************/ 4926ece92f85SJason Jin void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1)) 4927ece92f85SJason Jin { 4928ece92f85SJason Jin int mod, rh, rl; 4929ece92f85SJason Jin uint destoffset = 0; 4930ece92f85SJason Jin u16 *destreg; 4931ece92f85SJason Jin u16 destval,destval2; 4932ece92f85SJason Jin 4933ece92f85SJason Jin /* Yet another special case instruction. */ 4934ece92f85SJason Jin START_OF_INSTR(); 4935ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 4936ece92f85SJason Jin #ifdef DEBUG 4937ece92f85SJason Jin if (DEBUG_DECODE()) { 4938ece92f85SJason Jin /* XXX DECODE_PRINTF may be changed to something more 4939ece92f85SJason Jin general, so that it is important to leave the strings 4940ece92f85SJason Jin in the same format, even though the result is that the 4941ece92f85SJason Jin above test is done twice. */ 4942ece92f85SJason Jin 4943ece92f85SJason Jin switch (rh) { 4944ece92f85SJason Jin case 0: 4945ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4946ece92f85SJason Jin DECODE_PRINTF("INC\tDWORD PTR "); 4947ece92f85SJason Jin } else { 4948ece92f85SJason Jin DECODE_PRINTF("INC\tWORD PTR "); 4949ece92f85SJason Jin } 4950ece92f85SJason Jin break; 4951ece92f85SJason Jin case 1: 4952ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4953ece92f85SJason Jin DECODE_PRINTF("DEC\tDWORD PTR "); 4954ece92f85SJason Jin } else { 4955ece92f85SJason Jin DECODE_PRINTF("DEC\tWORD PTR "); 4956ece92f85SJason Jin } 4957ece92f85SJason Jin break; 4958ece92f85SJason Jin case 2: 4959ece92f85SJason Jin DECODE_PRINTF("CALL\t "); 4960ece92f85SJason Jin break; 4961ece92f85SJason Jin case 3: 4962ece92f85SJason Jin DECODE_PRINTF("CALL\tFAR "); 4963ece92f85SJason Jin break; 4964ece92f85SJason Jin case 4: 4965ece92f85SJason Jin DECODE_PRINTF("JMP\t"); 4966ece92f85SJason Jin break; 4967ece92f85SJason Jin case 5: 4968ece92f85SJason Jin DECODE_PRINTF("JMP\tFAR "); 4969ece92f85SJason Jin break; 4970ece92f85SJason Jin case 6: 4971ece92f85SJason Jin DECODE_PRINTF("PUSH\t"); 4972ece92f85SJason Jin break; 4973ece92f85SJason Jin case 7: 4974ece92f85SJason Jin DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t"); 4975ece92f85SJason Jin HALT_SYS(); 4976ece92f85SJason Jin break; 4977ece92f85SJason Jin } 4978ece92f85SJason Jin } 4979ece92f85SJason Jin #endif 4980ece92f85SJason Jin if (mod < 3) { 4981ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 4982ece92f85SJason Jin DECODE_PRINTF("\n"); 4983ece92f85SJason Jin switch (rh) { 4984ece92f85SJason Jin case 0: /* inc word ptr ... */ 4985ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 4986ece92f85SJason Jin u32 destval; 4987ece92f85SJason Jin 4988ece92f85SJason Jin destval = fetch_data_long(destoffset); 4989ece92f85SJason Jin TRACE_AND_STEP(); 4990ece92f85SJason Jin destval = inc_long(destval); 4991ece92f85SJason Jin store_data_long(destoffset, destval); 4992ece92f85SJason Jin } else { 4993ece92f85SJason Jin u16 destval; 4994ece92f85SJason Jin 4995ece92f85SJason Jin destval = fetch_data_word(destoffset); 4996ece92f85SJason Jin TRACE_AND_STEP(); 4997ece92f85SJason Jin destval = inc_word(destval); 4998ece92f85SJason Jin store_data_word(destoffset, destval); 4999ece92f85SJason Jin } 5000ece92f85SJason Jin break; 5001ece92f85SJason Jin case 1: /* dec word ptr ... */ 5002ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5003ece92f85SJason Jin u32 destval; 5004ece92f85SJason Jin 5005ece92f85SJason Jin destval = fetch_data_long(destoffset); 5006ece92f85SJason Jin TRACE_AND_STEP(); 5007ece92f85SJason Jin destval = dec_long(destval); 5008ece92f85SJason Jin store_data_long(destoffset, destval); 5009ece92f85SJason Jin } else { 5010ece92f85SJason Jin u16 destval; 5011ece92f85SJason Jin 5012ece92f85SJason Jin destval = fetch_data_word(destoffset); 5013ece92f85SJason Jin TRACE_AND_STEP(); 5014ece92f85SJason Jin destval = dec_word(destval); 5015ece92f85SJason Jin store_data_word(destoffset, destval); 5016ece92f85SJason Jin } 5017ece92f85SJason Jin break; 5018ece92f85SJason Jin case 2: /* call word ptr ... */ 5019ece92f85SJason Jin destval = fetch_data_word(destoffset); 5020ece92f85SJason Jin TRACE_AND_STEP(); 5021ece92f85SJason Jin push_word(M.x86.R_IP); 5022ece92f85SJason Jin M.x86.R_IP = destval; 5023ece92f85SJason Jin break; 5024ece92f85SJason Jin case 3: /* call far ptr ... */ 5025ece92f85SJason Jin destval = fetch_data_word(destoffset); 5026ece92f85SJason Jin destval2 = fetch_data_word(destoffset + 2); 5027ece92f85SJason Jin TRACE_AND_STEP(); 5028ece92f85SJason Jin push_word(M.x86.R_CS); 5029ece92f85SJason Jin M.x86.R_CS = destval2; 5030ece92f85SJason Jin push_word(M.x86.R_IP); 5031ece92f85SJason Jin M.x86.R_IP = destval; 5032ece92f85SJason Jin break; 5033ece92f85SJason Jin case 4: /* jmp word ptr ... */ 5034ece92f85SJason Jin destval = fetch_data_word(destoffset); 5035ece92f85SJason Jin TRACE_AND_STEP(); 5036ece92f85SJason Jin M.x86.R_IP = destval; 5037ece92f85SJason Jin break; 5038ece92f85SJason Jin case 5: /* jmp far ptr ... */ 5039ece92f85SJason Jin destval = fetch_data_word(destoffset); 5040ece92f85SJason Jin destval2 = fetch_data_word(destoffset + 2); 5041ece92f85SJason Jin TRACE_AND_STEP(); 5042ece92f85SJason Jin M.x86.R_IP = destval; 5043ece92f85SJason Jin M.x86.R_CS = destval2; 5044ece92f85SJason Jin break; 5045ece92f85SJason Jin case 6: /* push word ptr ... */ 5046ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5047ece92f85SJason Jin u32 destval; 5048ece92f85SJason Jin 5049ece92f85SJason Jin destval = fetch_data_long(destoffset); 5050ece92f85SJason Jin TRACE_AND_STEP(); 5051ece92f85SJason Jin push_long(destval); 5052ece92f85SJason Jin } else { 5053ece92f85SJason Jin u16 destval; 5054ece92f85SJason Jin 5055ece92f85SJason Jin destval = fetch_data_word(destoffset); 5056ece92f85SJason Jin TRACE_AND_STEP(); 5057ece92f85SJason Jin push_word(destval); 5058ece92f85SJason Jin } 5059ece92f85SJason Jin break; 5060ece92f85SJason Jin } 5061ece92f85SJason Jin } else { 5062ece92f85SJason Jin switch (rh) { 5063ece92f85SJason Jin case 0: 5064ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5065ece92f85SJason Jin u32 *destreg; 5066ece92f85SJason Jin 5067ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 5068ece92f85SJason Jin DECODE_PRINTF("\n"); 5069ece92f85SJason Jin TRACE_AND_STEP(); 5070ece92f85SJason Jin *destreg = inc_long(*destreg); 5071ece92f85SJason Jin } else { 5072ece92f85SJason Jin u16 *destreg; 5073ece92f85SJason Jin 5074ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 5075ece92f85SJason Jin DECODE_PRINTF("\n"); 5076ece92f85SJason Jin TRACE_AND_STEP(); 5077ece92f85SJason Jin *destreg = inc_word(*destreg); 5078ece92f85SJason Jin } 5079ece92f85SJason Jin break; 5080ece92f85SJason Jin case 1: 5081ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5082ece92f85SJason Jin u32 *destreg; 5083ece92f85SJason Jin 5084ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 5085ece92f85SJason Jin DECODE_PRINTF("\n"); 5086ece92f85SJason Jin TRACE_AND_STEP(); 5087ece92f85SJason Jin *destreg = dec_long(*destreg); 5088ece92f85SJason Jin } else { 5089ece92f85SJason Jin u16 *destreg; 5090ece92f85SJason Jin 5091ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 5092ece92f85SJason Jin DECODE_PRINTF("\n"); 5093ece92f85SJason Jin TRACE_AND_STEP(); 5094ece92f85SJason Jin *destreg = dec_word(*destreg); 5095ece92f85SJason Jin } 5096ece92f85SJason Jin break; 5097ece92f85SJason Jin case 2: /* call word ptr ... */ 5098ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 5099ece92f85SJason Jin DECODE_PRINTF("\n"); 5100ece92f85SJason Jin TRACE_AND_STEP(); 5101ece92f85SJason Jin push_word(M.x86.R_IP); 5102ece92f85SJason Jin M.x86.R_IP = *destreg; 5103ece92f85SJason Jin break; 5104ece92f85SJason Jin case 3: /* jmp far ptr ... */ 5105ece92f85SJason Jin DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); 5106ece92f85SJason Jin TRACE_AND_STEP(); 5107ece92f85SJason Jin HALT_SYS(); 5108ece92f85SJason Jin break; 5109ece92f85SJason Jin 5110ece92f85SJason Jin case 4: /* jmp ... */ 5111ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 5112ece92f85SJason Jin DECODE_PRINTF("\n"); 5113ece92f85SJason Jin TRACE_AND_STEP(); 5114ece92f85SJason Jin M.x86.R_IP = (u16) (*destreg); 5115ece92f85SJason Jin break; 5116ece92f85SJason Jin case 5: /* jmp far ptr ... */ 5117ece92f85SJason Jin DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n"); 5118ece92f85SJason Jin TRACE_AND_STEP(); 5119ece92f85SJason Jin HALT_SYS(); 5120ece92f85SJason Jin break; 5121ece92f85SJason Jin case 6: 5122ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 5123ece92f85SJason Jin u32 *destreg; 5124ece92f85SJason Jin 5125ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 5126ece92f85SJason Jin DECODE_PRINTF("\n"); 5127ece92f85SJason Jin TRACE_AND_STEP(); 5128ece92f85SJason Jin push_long(*destreg); 5129ece92f85SJason Jin } else { 5130ece92f85SJason Jin u16 *destreg; 5131ece92f85SJason Jin 5132ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 5133ece92f85SJason Jin DECODE_PRINTF("\n"); 5134ece92f85SJason Jin TRACE_AND_STEP(); 5135ece92f85SJason Jin push_word(*destreg); 5136ece92f85SJason Jin } 5137ece92f85SJason Jin break; 5138ece92f85SJason Jin } 5139ece92f85SJason Jin } 5140ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 5141ece92f85SJason Jin END_OF_INSTR(); 5142ece92f85SJason Jin } 5143ece92f85SJason Jin 5144ece92f85SJason Jin /*************************************************************************** 5145ece92f85SJason Jin * Single byte operation code table: 5146ece92f85SJason Jin **************************************************************************/ 514730c6a241SAnatolij Gustschin void (*x86emu_optab[256])(u8) __attribute__ ((section(GOT2_TYPE))) = 5148ece92f85SJason Jin { 5149ece92f85SJason Jin /* 0x00 */ x86emuOp_genop_byte_RM_R, 5150ece92f85SJason Jin /* 0x01 */ x86emuOp_genop_word_RM_R, 5151ece92f85SJason Jin /* 0x02 */ x86emuOp_genop_byte_R_RM, 5152ece92f85SJason Jin /* 0x03 */ x86emuOp_genop_word_R_RM, 5153ece92f85SJason Jin /* 0x04 */ x86emuOp_genop_byte_AL_IMM, 5154ece92f85SJason Jin /* 0x05 */ x86emuOp_genop_word_AX_IMM, 5155ece92f85SJason Jin /* 0x06 */ x86emuOp_push_ES, 5156ece92f85SJason Jin /* 0x07 */ x86emuOp_pop_ES, 5157ece92f85SJason Jin 5158ece92f85SJason Jin /* 0x08 */ x86emuOp_genop_byte_RM_R, 5159ece92f85SJason Jin /* 0x09 */ x86emuOp_genop_word_RM_R, 5160ece92f85SJason Jin /* 0x0a */ x86emuOp_genop_byte_R_RM, 5161ece92f85SJason Jin /* 0x0b */ x86emuOp_genop_word_R_RM, 5162ece92f85SJason Jin /* 0x0c */ x86emuOp_genop_byte_AL_IMM, 5163ece92f85SJason Jin /* 0x0d */ x86emuOp_genop_word_AX_IMM, 5164ece92f85SJason Jin /* 0x0e */ x86emuOp_push_CS, 5165ece92f85SJason Jin /* 0x0f */ x86emuOp_two_byte, 5166ece92f85SJason Jin 5167ece92f85SJason Jin /* 0x10 */ x86emuOp_genop_byte_RM_R, 5168ece92f85SJason Jin /* 0x11 */ x86emuOp_genop_word_RM_R, 5169ece92f85SJason Jin /* 0x12 */ x86emuOp_genop_byte_R_RM, 5170ece92f85SJason Jin /* 0x13 */ x86emuOp_genop_word_R_RM, 5171ece92f85SJason Jin /* 0x14 */ x86emuOp_genop_byte_AL_IMM, 5172ece92f85SJason Jin /* 0x15 */ x86emuOp_genop_word_AX_IMM, 5173ece92f85SJason Jin /* 0x16 */ x86emuOp_push_SS, 5174ece92f85SJason Jin /* 0x17 */ x86emuOp_pop_SS, 5175ece92f85SJason Jin 5176ece92f85SJason Jin /* 0x18 */ x86emuOp_genop_byte_RM_R, 5177ece92f85SJason Jin /* 0x19 */ x86emuOp_genop_word_RM_R, 5178ece92f85SJason Jin /* 0x1a */ x86emuOp_genop_byte_R_RM, 5179ece92f85SJason Jin /* 0x1b */ x86emuOp_genop_word_R_RM, 5180ece92f85SJason Jin /* 0x1c */ x86emuOp_genop_byte_AL_IMM, 5181ece92f85SJason Jin /* 0x1d */ x86emuOp_genop_word_AX_IMM, 5182ece92f85SJason Jin /* 0x1e */ x86emuOp_push_DS, 5183ece92f85SJason Jin /* 0x1f */ x86emuOp_pop_DS, 5184ece92f85SJason Jin 5185ece92f85SJason Jin /* 0x20 */ x86emuOp_genop_byte_RM_R, 5186ece92f85SJason Jin /* 0x21 */ x86emuOp_genop_word_RM_R, 5187ece92f85SJason Jin /* 0x22 */ x86emuOp_genop_byte_R_RM, 5188ece92f85SJason Jin /* 0x23 */ x86emuOp_genop_word_R_RM, 5189ece92f85SJason Jin /* 0x24 */ x86emuOp_genop_byte_AL_IMM, 5190ece92f85SJason Jin /* 0x25 */ x86emuOp_genop_word_AX_IMM, 5191ece92f85SJason Jin /* 0x26 */ x86emuOp_segovr_ES, 5192ece92f85SJason Jin /* 0x27 */ x86emuOp_daa, 5193ece92f85SJason Jin 5194ece92f85SJason Jin /* 0x28 */ x86emuOp_genop_byte_RM_R, 5195ece92f85SJason Jin /* 0x29 */ x86emuOp_genop_word_RM_R, 5196ece92f85SJason Jin /* 0x2a */ x86emuOp_genop_byte_R_RM, 5197ece92f85SJason Jin /* 0x2b */ x86emuOp_genop_word_R_RM, 5198ece92f85SJason Jin /* 0x2c */ x86emuOp_genop_byte_AL_IMM, 5199ece92f85SJason Jin /* 0x2d */ x86emuOp_genop_word_AX_IMM, 5200ece92f85SJason Jin /* 0x2e */ x86emuOp_segovr_CS, 5201ece92f85SJason Jin /* 0x2f */ x86emuOp_das, 5202ece92f85SJason Jin 5203ece92f85SJason Jin /* 0x30 */ x86emuOp_genop_byte_RM_R, 5204ece92f85SJason Jin /* 0x31 */ x86emuOp_genop_word_RM_R, 5205ece92f85SJason Jin /* 0x32 */ x86emuOp_genop_byte_R_RM, 5206ece92f85SJason Jin /* 0x33 */ x86emuOp_genop_word_R_RM, 5207ece92f85SJason Jin /* 0x34 */ x86emuOp_genop_byte_AL_IMM, 5208ece92f85SJason Jin /* 0x35 */ x86emuOp_genop_word_AX_IMM, 5209ece92f85SJason Jin /* 0x36 */ x86emuOp_segovr_SS, 5210ece92f85SJason Jin /* 0x37 */ x86emuOp_aaa, 5211ece92f85SJason Jin 5212ece92f85SJason Jin /* 0x38 */ x86emuOp_genop_byte_RM_R, 5213ece92f85SJason Jin /* 0x39 */ x86emuOp_genop_word_RM_R, 5214ece92f85SJason Jin /* 0x3a */ x86emuOp_genop_byte_R_RM, 5215ece92f85SJason Jin /* 0x3b */ x86emuOp_genop_word_R_RM, 5216ece92f85SJason Jin /* 0x3c */ x86emuOp_genop_byte_AL_IMM, 5217ece92f85SJason Jin /* 0x3d */ x86emuOp_genop_word_AX_IMM, 5218ece92f85SJason Jin /* 0x3e */ x86emuOp_segovr_DS, 5219ece92f85SJason Jin /* 0x3f */ x86emuOp_aas, 5220ece92f85SJason Jin 5221ece92f85SJason Jin /* 0x40 */ x86emuOp_inc_register, 5222ece92f85SJason Jin /* 0x41 */ x86emuOp_inc_register, 5223ece92f85SJason Jin /* 0x42 */ x86emuOp_inc_register, 5224ece92f85SJason Jin /* 0x43 */ x86emuOp_inc_register, 5225ece92f85SJason Jin /* 0x44 */ x86emuOp_inc_register, 5226ece92f85SJason Jin /* 0x45 */ x86emuOp_inc_register, 5227ece92f85SJason Jin /* 0x46 */ x86emuOp_inc_register, 5228ece92f85SJason Jin /* 0x47 */ x86emuOp_inc_register, 5229ece92f85SJason Jin 5230ece92f85SJason Jin /* 0x48 */ x86emuOp_dec_register, 5231ece92f85SJason Jin /* 0x49 */ x86emuOp_dec_register, 5232ece92f85SJason Jin /* 0x4a */ x86emuOp_dec_register, 5233ece92f85SJason Jin /* 0x4b */ x86emuOp_dec_register, 5234ece92f85SJason Jin /* 0x4c */ x86emuOp_dec_register, 5235ece92f85SJason Jin /* 0x4d */ x86emuOp_dec_register, 5236ece92f85SJason Jin /* 0x4e */ x86emuOp_dec_register, 5237ece92f85SJason Jin /* 0x4f */ x86emuOp_dec_register, 5238ece92f85SJason Jin 5239ece92f85SJason Jin /* 0x50 */ x86emuOp_push_register, 5240ece92f85SJason Jin /* 0x51 */ x86emuOp_push_register, 5241ece92f85SJason Jin /* 0x52 */ x86emuOp_push_register, 5242ece92f85SJason Jin /* 0x53 */ x86emuOp_push_register, 5243ece92f85SJason Jin /* 0x54 */ x86emuOp_push_register, 5244ece92f85SJason Jin /* 0x55 */ x86emuOp_push_register, 5245ece92f85SJason Jin /* 0x56 */ x86emuOp_push_register, 5246ece92f85SJason Jin /* 0x57 */ x86emuOp_push_register, 5247ece92f85SJason Jin 5248ece92f85SJason Jin /* 0x58 */ x86emuOp_pop_register, 5249ece92f85SJason Jin /* 0x59 */ x86emuOp_pop_register, 5250ece92f85SJason Jin /* 0x5a */ x86emuOp_pop_register, 5251ece92f85SJason Jin /* 0x5b */ x86emuOp_pop_register, 5252ece92f85SJason Jin /* 0x5c */ x86emuOp_pop_register, 5253ece92f85SJason Jin /* 0x5d */ x86emuOp_pop_register, 5254ece92f85SJason Jin /* 0x5e */ x86emuOp_pop_register, 5255ece92f85SJason Jin /* 0x5f */ x86emuOp_pop_register, 5256ece92f85SJason Jin 5257ece92f85SJason Jin /* 0x60 */ x86emuOp_push_all, 5258ece92f85SJason Jin /* 0x61 */ x86emuOp_pop_all, 5259ece92f85SJason Jin /* 0x62 */ x86emuOp_illegal_op, /* bound */ 5260ece92f85SJason Jin /* 0x63 */ x86emuOp_illegal_op, /* arpl */ 5261ece92f85SJason Jin /* 0x64 */ x86emuOp_segovr_FS, 5262ece92f85SJason Jin /* 0x65 */ x86emuOp_segovr_GS, 5263ece92f85SJason Jin /* 0x66 */ x86emuOp_prefix_data, 5264ece92f85SJason Jin /* 0x67 */ x86emuOp_prefix_addr, 5265ece92f85SJason Jin 5266ece92f85SJason Jin /* 0x68 */ x86emuOp_push_word_IMM, 5267ece92f85SJason Jin /* 0x69 */ x86emuOp_imul_word_IMM, 5268ece92f85SJason Jin /* 0x6a */ x86emuOp_push_byte_IMM, 5269ece92f85SJason Jin /* 0x6b */ x86emuOp_imul_byte_IMM, 5270ece92f85SJason Jin /* 0x6c */ x86emuOp_ins_byte, 5271ece92f85SJason Jin /* 0x6d */ x86emuOp_ins_word, 5272ece92f85SJason Jin /* 0x6e */ x86emuOp_outs_byte, 5273ece92f85SJason Jin /* 0x6f */ x86emuOp_outs_word, 5274ece92f85SJason Jin 5275ece92f85SJason Jin /* 0x70 */ x86emuOp_jump_near_cond, 5276ece92f85SJason Jin /* 0x71 */ x86emuOp_jump_near_cond, 5277ece92f85SJason Jin /* 0x72 */ x86emuOp_jump_near_cond, 5278ece92f85SJason Jin /* 0x73 */ x86emuOp_jump_near_cond, 5279ece92f85SJason Jin /* 0x74 */ x86emuOp_jump_near_cond, 5280ece92f85SJason Jin /* 0x75 */ x86emuOp_jump_near_cond, 5281ece92f85SJason Jin /* 0x76 */ x86emuOp_jump_near_cond, 5282ece92f85SJason Jin /* 0x77 */ x86emuOp_jump_near_cond, 5283ece92f85SJason Jin 5284ece92f85SJason Jin /* 0x78 */ x86emuOp_jump_near_cond, 5285ece92f85SJason Jin /* 0x79 */ x86emuOp_jump_near_cond, 5286ece92f85SJason Jin /* 0x7a */ x86emuOp_jump_near_cond, 5287ece92f85SJason Jin /* 0x7b */ x86emuOp_jump_near_cond, 5288ece92f85SJason Jin /* 0x7c */ x86emuOp_jump_near_cond, 5289ece92f85SJason Jin /* 0x7d */ x86emuOp_jump_near_cond, 5290ece92f85SJason Jin /* 0x7e */ x86emuOp_jump_near_cond, 5291ece92f85SJason Jin /* 0x7f */ x86emuOp_jump_near_cond, 5292ece92f85SJason Jin 5293ece92f85SJason Jin /* 0x80 */ x86emuOp_opc80_byte_RM_IMM, 5294ece92f85SJason Jin /* 0x81 */ x86emuOp_opc81_word_RM_IMM, 5295ece92f85SJason Jin /* 0x82 */ x86emuOp_opc82_byte_RM_IMM, 5296ece92f85SJason Jin /* 0x83 */ x86emuOp_opc83_word_RM_IMM, 5297ece92f85SJason Jin /* 0x84 */ x86emuOp_test_byte_RM_R, 5298ece92f85SJason Jin /* 0x85 */ x86emuOp_test_word_RM_R, 5299ece92f85SJason Jin /* 0x86 */ x86emuOp_xchg_byte_RM_R, 5300ece92f85SJason Jin /* 0x87 */ x86emuOp_xchg_word_RM_R, 5301ece92f85SJason Jin 5302ece92f85SJason Jin /* 0x88 */ x86emuOp_mov_byte_RM_R, 5303ece92f85SJason Jin /* 0x89 */ x86emuOp_mov_word_RM_R, 5304ece92f85SJason Jin /* 0x8a */ x86emuOp_mov_byte_R_RM, 5305ece92f85SJason Jin /* 0x8b */ x86emuOp_mov_word_R_RM, 5306ece92f85SJason Jin /* 0x8c */ x86emuOp_mov_word_RM_SR, 5307ece92f85SJason Jin /* 0x8d */ x86emuOp_lea_word_R_M, 5308ece92f85SJason Jin /* 0x8e */ x86emuOp_mov_word_SR_RM, 5309ece92f85SJason Jin /* 0x8f */ x86emuOp_pop_RM, 5310ece92f85SJason Jin 5311ece92f85SJason Jin /* 0x90 */ x86emuOp_nop, 5312ece92f85SJason Jin /* 0x91 */ x86emuOp_xchg_word_AX_register, 5313ece92f85SJason Jin /* 0x92 */ x86emuOp_xchg_word_AX_register, 5314ece92f85SJason Jin /* 0x93 */ x86emuOp_xchg_word_AX_register, 5315ece92f85SJason Jin /* 0x94 */ x86emuOp_xchg_word_AX_register, 5316ece92f85SJason Jin /* 0x95 */ x86emuOp_xchg_word_AX_register, 5317ece92f85SJason Jin /* 0x96 */ x86emuOp_xchg_word_AX_register, 5318ece92f85SJason Jin /* 0x97 */ x86emuOp_xchg_word_AX_register, 5319ece92f85SJason Jin 5320ece92f85SJason Jin /* 0x98 */ x86emuOp_cbw, 5321ece92f85SJason Jin /* 0x99 */ x86emuOp_cwd, 5322ece92f85SJason Jin /* 0x9a */ x86emuOp_call_far_IMM, 5323ece92f85SJason Jin /* 0x9b */ x86emuOp_wait, 5324ece92f85SJason Jin /* 0x9c */ x86emuOp_pushf_word, 5325ece92f85SJason Jin /* 0x9d */ x86emuOp_popf_word, 5326ece92f85SJason Jin /* 0x9e */ x86emuOp_sahf, 5327ece92f85SJason Jin /* 0x9f */ x86emuOp_lahf, 5328ece92f85SJason Jin 5329ece92f85SJason Jin /* 0xa0 */ x86emuOp_mov_AL_M_IMM, 5330ece92f85SJason Jin /* 0xa1 */ x86emuOp_mov_AX_M_IMM, 5331ece92f85SJason Jin /* 0xa2 */ x86emuOp_mov_M_AL_IMM, 5332ece92f85SJason Jin /* 0xa3 */ x86emuOp_mov_M_AX_IMM, 5333ece92f85SJason Jin /* 0xa4 */ x86emuOp_movs_byte, 5334ece92f85SJason Jin /* 0xa5 */ x86emuOp_movs_word, 5335ece92f85SJason Jin /* 0xa6 */ x86emuOp_cmps_byte, 5336ece92f85SJason Jin /* 0xa7 */ x86emuOp_cmps_word, 5337ece92f85SJason Jin /* 0xa8 */ x86emuOp_test_AL_IMM, 5338ece92f85SJason Jin /* 0xa9 */ x86emuOp_test_AX_IMM, 5339ece92f85SJason Jin /* 0xaa */ x86emuOp_stos_byte, 5340ece92f85SJason Jin /* 0xab */ x86emuOp_stos_word, 5341ece92f85SJason Jin /* 0xac */ x86emuOp_lods_byte, 5342ece92f85SJason Jin /* 0xad */ x86emuOp_lods_word, 5343ece92f85SJason Jin /* 0xac */ x86emuOp_scas_byte, 5344ece92f85SJason Jin /* 0xad */ x86emuOp_scas_word, 5345ece92f85SJason Jin 5346ece92f85SJason Jin /* 0xb0 */ x86emuOp_mov_byte_register_IMM, 5347ece92f85SJason Jin /* 0xb1 */ x86emuOp_mov_byte_register_IMM, 5348ece92f85SJason Jin /* 0xb2 */ x86emuOp_mov_byte_register_IMM, 5349ece92f85SJason Jin /* 0xb3 */ x86emuOp_mov_byte_register_IMM, 5350ece92f85SJason Jin /* 0xb4 */ x86emuOp_mov_byte_register_IMM, 5351ece92f85SJason Jin /* 0xb5 */ x86emuOp_mov_byte_register_IMM, 5352ece92f85SJason Jin /* 0xb6 */ x86emuOp_mov_byte_register_IMM, 5353ece92f85SJason Jin /* 0xb7 */ x86emuOp_mov_byte_register_IMM, 5354ece92f85SJason Jin 5355ece92f85SJason Jin /* 0xb8 */ x86emuOp_mov_word_register_IMM, 5356ece92f85SJason Jin /* 0xb9 */ x86emuOp_mov_word_register_IMM, 5357ece92f85SJason Jin /* 0xba */ x86emuOp_mov_word_register_IMM, 5358ece92f85SJason Jin /* 0xbb */ x86emuOp_mov_word_register_IMM, 5359ece92f85SJason Jin /* 0xbc */ x86emuOp_mov_word_register_IMM, 5360ece92f85SJason Jin /* 0xbd */ x86emuOp_mov_word_register_IMM, 5361ece92f85SJason Jin /* 0xbe */ x86emuOp_mov_word_register_IMM, 5362ece92f85SJason Jin /* 0xbf */ x86emuOp_mov_word_register_IMM, 5363ece92f85SJason Jin 5364ece92f85SJason Jin /* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM, 5365ece92f85SJason Jin /* 0xc1 */ x86emuOp_opcC1_word_RM_MEM, 5366ece92f85SJason Jin /* 0xc2 */ x86emuOp_ret_near_IMM, 5367ece92f85SJason Jin /* 0xc3 */ x86emuOp_ret_near, 5368ece92f85SJason Jin /* 0xc4 */ x86emuOp_les_R_IMM, 5369ece92f85SJason Jin /* 0xc5 */ x86emuOp_lds_R_IMM, 5370ece92f85SJason Jin /* 0xc6 */ x86emuOp_mov_byte_RM_IMM, 5371ece92f85SJason Jin /* 0xc7 */ x86emuOp_mov_word_RM_IMM, 5372ece92f85SJason Jin /* 0xc8 */ x86emuOp_enter, 5373ece92f85SJason Jin /* 0xc9 */ x86emuOp_leave, 5374ece92f85SJason Jin /* 0xca */ x86emuOp_ret_far_IMM, 5375ece92f85SJason Jin /* 0xcb */ x86emuOp_ret_far, 5376ece92f85SJason Jin /* 0xcc */ x86emuOp_int3, 5377ece92f85SJason Jin /* 0xcd */ x86emuOp_int_IMM, 5378ece92f85SJason Jin /* 0xce */ x86emuOp_into, 5379ece92f85SJason Jin /* 0xcf */ x86emuOp_iret, 5380ece92f85SJason Jin 5381ece92f85SJason Jin /* 0xd0 */ x86emuOp_opcD0_byte_RM_1, 5382ece92f85SJason Jin /* 0xd1 */ x86emuOp_opcD1_word_RM_1, 5383ece92f85SJason Jin /* 0xd2 */ x86emuOp_opcD2_byte_RM_CL, 5384ece92f85SJason Jin /* 0xd3 */ x86emuOp_opcD3_word_RM_CL, 5385ece92f85SJason Jin /* 0xd4 */ x86emuOp_aam, 5386ece92f85SJason Jin /* 0xd5 */ x86emuOp_aad, 5387ece92f85SJason Jin /* 0xd6 */ x86emuOp_illegal_op, /* Undocumented SETALC instruction */ 5388ece92f85SJason Jin /* 0xd7 */ x86emuOp_xlat, 5389ece92f85SJason Jin /* 0xd8 */ NULL, /*x86emuOp_esc_coprocess_d8,*/ 5390ece92f85SJason Jin /* 0xd9 */ NULL, /*x86emuOp_esc_coprocess_d9,*/ 5391ece92f85SJason Jin /* 0xda */ NULL, /*x86emuOp_esc_coprocess_da,*/ 5392ece92f85SJason Jin /* 0xdb */ NULL, /*x86emuOp_esc_coprocess_db,*/ 5393ece92f85SJason Jin /* 0xdc */ NULL, /*x86emuOp_esc_coprocess_dc,*/ 5394ece92f85SJason Jin /* 0xdd */ NULL, /*x86emuOp_esc_coprocess_dd,*/ 5395ece92f85SJason Jin /* 0xde */ NULL, /*x86emuOp_esc_coprocess_de,*/ 5396ece92f85SJason Jin /* 0xdf */ NULL, /*x86emuOp_esc_coprocess_df,*/ 5397ece92f85SJason Jin 5398ece92f85SJason Jin /* 0xe0 */ x86emuOp_loopne, 5399ece92f85SJason Jin /* 0xe1 */ x86emuOp_loope, 5400ece92f85SJason Jin /* 0xe2 */ x86emuOp_loop, 5401ece92f85SJason Jin /* 0xe3 */ x86emuOp_jcxz, 5402ece92f85SJason Jin /* 0xe4 */ x86emuOp_in_byte_AL_IMM, 5403ece92f85SJason Jin /* 0xe5 */ x86emuOp_in_word_AX_IMM, 5404ece92f85SJason Jin /* 0xe6 */ x86emuOp_out_byte_IMM_AL, 5405ece92f85SJason Jin /* 0xe7 */ x86emuOp_out_word_IMM_AX, 5406ece92f85SJason Jin 5407ece92f85SJason Jin /* 0xe8 */ x86emuOp_call_near_IMM, 5408ece92f85SJason Jin /* 0xe9 */ x86emuOp_jump_near_IMM, 5409ece92f85SJason Jin /* 0xea */ x86emuOp_jump_far_IMM, 5410ece92f85SJason Jin /* 0xeb */ x86emuOp_jump_byte_IMM, 5411ece92f85SJason Jin /* 0xec */ x86emuOp_in_byte_AL_DX, 5412ece92f85SJason Jin /* 0xed */ x86emuOp_in_word_AX_DX, 5413ece92f85SJason Jin /* 0xee */ x86emuOp_out_byte_DX_AL, 5414ece92f85SJason Jin /* 0xef */ x86emuOp_out_word_DX_AX, 5415ece92f85SJason Jin 5416ece92f85SJason Jin /* 0xf0 */ x86emuOp_lock, 5417ece92f85SJason Jin /* 0xf1 */ x86emuOp_illegal_op, 5418ece92f85SJason Jin /* 0xf2 */ x86emuOp_repne, 5419ece92f85SJason Jin /* 0xf3 */ x86emuOp_repe, 5420ece92f85SJason Jin /* 0xf4 */ x86emuOp_halt, 5421ece92f85SJason Jin /* 0xf5 */ x86emuOp_cmc, 5422ece92f85SJason Jin /* 0xf6 */ x86emuOp_opcF6_byte_RM, 5423ece92f85SJason Jin /* 0xf7 */ x86emuOp_opcF7_word_RM, 5424ece92f85SJason Jin 5425ece92f85SJason Jin /* 0xf8 */ x86emuOp_clc, 5426ece92f85SJason Jin /* 0xf9 */ x86emuOp_stc, 5427ece92f85SJason Jin /* 0xfa */ x86emuOp_cli, 5428ece92f85SJason Jin /* 0xfb */ x86emuOp_sti, 5429ece92f85SJason Jin /* 0xfc */ x86emuOp_cld, 5430ece92f85SJason Jin /* 0xfd */ x86emuOp_std, 5431ece92f85SJason Jin /* 0xfe */ x86emuOp_opcFE_byte_RM, 5432ece92f85SJason Jin /* 0xff */ x86emuOp_opcFF_word_RM, 5433ece92f85SJason Jin }; 5434