1ece92f85SJason Jin /**************************************************************************** 2ece92f85SJason Jin * 3ece92f85SJason Jin * Realmode X86 Emulator Library 4ece92f85SJason Jin * 5*4c2e3da8SKumar Gala * Copyright (C) 2007 Freescale Semiconductor, Inc. 6ece92f85SJason Jin * Jason Jin <Jason.jin@freescale.com> 7ece92f85SJason Jin * 8ece92f85SJason Jin * Copyright (C) 1991-2004 SciTech Software, Inc. 9ece92f85SJason Jin * Copyright (C) David Mosberger-Tang 10ece92f85SJason Jin * Copyright (C) 1999 Egbert Eich 11ece92f85SJason Jin * 12ece92f85SJason Jin * ======================================================================== 13ece92f85SJason Jin * 14ece92f85SJason Jin * Permission to use, copy, modify, distribute, and sell this software and 15ece92f85SJason Jin * its documentation for any purpose is hereby granted without fee, 16ece92f85SJason Jin * provided that the above copyright notice appear in all copies and that 17ece92f85SJason Jin * both that copyright notice and this permission notice appear in 18ece92f85SJason Jin * supporting documentation, and that the name of the authors not be used 19ece92f85SJason Jin * in advertising or publicity pertaining to distribution of the software 20ece92f85SJason Jin * without specific, written prior permission. The authors makes no 21ece92f85SJason Jin * representations about the suitability of this software for any purpose. 22ece92f85SJason Jin * It is provided "as is" without express or implied warranty. 23ece92f85SJason Jin * 24ece92f85SJason Jin * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 25ece92f85SJason Jin * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 26ece92f85SJason Jin * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 27ece92f85SJason Jin * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 28ece92f85SJason Jin * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 29ece92f85SJason Jin * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 30ece92f85SJason Jin * PERFORMANCE OF THIS SOFTWARE. 31ece92f85SJason Jin * 32ece92f85SJason Jin * ======================================================================== 33ece92f85SJason Jin * 34ece92f85SJason Jin * Language: ANSI C 35ece92f85SJason Jin * Environment: Any 36ece92f85SJason Jin * Developer: Kendall Bennett 37ece92f85SJason Jin * 38ece92f85SJason Jin * Description: This file includes subroutines to implement the decoding 39ece92f85SJason Jin * and emulation of all the x86 extended two-byte processor 40ece92f85SJason Jin * instructions. 41ece92f85SJason Jin * 42ece92f85SJason Jin * Jason port this file to u-boot. Put the function pointer into 43ece92f85SJason Jin * got2 sector. 44ece92f85SJason Jin * 45ece92f85SJason Jin ****************************************************************************/ 46ece92f85SJason Jin 4778cff50eSMichal Simek #include <common.h> 485b4de930SMichal Simek #include "x86emu/x86emui.h" 495b4de930SMichal Simek 50ece92f85SJason Jin /*----------------------------- Implementation ----------------------------*/ 51ece92f85SJason Jin 52ece92f85SJason Jin /**************************************************************************** 53ece92f85SJason Jin PARAMETERS: 54ece92f85SJason Jin op1 - Instruction op code 55ece92f85SJason Jin 56ece92f85SJason Jin REMARKS: 57ece92f85SJason Jin Handles illegal opcodes. 58ece92f85SJason Jin ****************************************************************************/ 59ece92f85SJason Jin void x86emuOp2_illegal_op( 60ece92f85SJason Jin u8 op2) 61ece92f85SJason Jin { 62ece92f85SJason Jin START_OF_INSTR(); 63ece92f85SJason Jin DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n"); 64ece92f85SJason Jin TRACE_REGS(); 65ece92f85SJason Jin printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n", 66ece92f85SJason Jin M.x86.R_CS, M.x86.R_IP-2,op2); 67ece92f85SJason Jin HALT_SYS(); 68ece92f85SJason Jin END_OF_INSTR(); 69ece92f85SJason Jin } 70ece92f85SJason Jin 71ece92f85SJason Jin #define xorl(a,b) ((a) && !(b)) || (!(a) && (b)) 72ece92f85SJason Jin 73ece92f85SJason Jin /**************************************************************************** 74ece92f85SJason Jin REMARKS: 75ece92f85SJason Jin Handles opcode 0x0f,0x80-0x8F 76ece92f85SJason Jin ****************************************************************************/ 77ece92f85SJason Jin int x86emu_check_jump_condition(u8 op) 78ece92f85SJason Jin { 79ece92f85SJason Jin switch (op) { 80ece92f85SJason Jin case 0x0: 81ece92f85SJason Jin DECODE_PRINTF("JO\t"); 82ece92f85SJason Jin return ACCESS_FLAG(F_OF); 83ece92f85SJason Jin case 0x1: 84ece92f85SJason Jin DECODE_PRINTF("JNO\t"); 85ece92f85SJason Jin return !ACCESS_FLAG(F_OF); 86ece92f85SJason Jin break; 87ece92f85SJason Jin case 0x2: 88ece92f85SJason Jin DECODE_PRINTF("JB\t"); 89ece92f85SJason Jin return ACCESS_FLAG(F_CF); 90ece92f85SJason Jin break; 91ece92f85SJason Jin case 0x3: 92ece92f85SJason Jin DECODE_PRINTF("JNB\t"); 93ece92f85SJason Jin return !ACCESS_FLAG(F_CF); 94ece92f85SJason Jin break; 95ece92f85SJason Jin case 0x4: 96ece92f85SJason Jin DECODE_PRINTF("JZ\t"); 97ece92f85SJason Jin return ACCESS_FLAG(F_ZF); 98ece92f85SJason Jin break; 99ece92f85SJason Jin case 0x5: 100ece92f85SJason Jin DECODE_PRINTF("JNZ\t"); 101ece92f85SJason Jin return !ACCESS_FLAG(F_ZF); 102ece92f85SJason Jin break; 103ece92f85SJason Jin case 0x6: 104ece92f85SJason Jin DECODE_PRINTF("JBE\t"); 105ece92f85SJason Jin return ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF); 106ece92f85SJason Jin break; 107ece92f85SJason Jin case 0x7: 108ece92f85SJason Jin DECODE_PRINTF("JNBE\t"); 109ece92f85SJason Jin return !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)); 110ece92f85SJason Jin break; 111ece92f85SJason Jin case 0x8: 112ece92f85SJason Jin DECODE_PRINTF("JS\t"); 113ece92f85SJason Jin return ACCESS_FLAG(F_SF); 114ece92f85SJason Jin break; 115ece92f85SJason Jin case 0x9: 116ece92f85SJason Jin DECODE_PRINTF("JNS\t"); 117ece92f85SJason Jin return !ACCESS_FLAG(F_SF); 118ece92f85SJason Jin break; 119ece92f85SJason Jin case 0xa: 120ece92f85SJason Jin DECODE_PRINTF("JP\t"); 121ece92f85SJason Jin return ACCESS_FLAG(F_PF); 122ece92f85SJason Jin break; 123ece92f85SJason Jin case 0xb: 124ece92f85SJason Jin DECODE_PRINTF("JNP\t"); 125ece92f85SJason Jin return !ACCESS_FLAG(F_PF); 126ece92f85SJason Jin break; 127ece92f85SJason Jin case 0xc: 128ece92f85SJason Jin DECODE_PRINTF("JL\t"); 129ece92f85SJason Jin return xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); 130ece92f85SJason Jin break; 131ece92f85SJason Jin case 0xd: 132ece92f85SJason Jin DECODE_PRINTF("JNL\t"); 133ece92f85SJason Jin return !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); 134ece92f85SJason Jin break; 135ece92f85SJason Jin case 0xe: 136ece92f85SJason Jin DECODE_PRINTF("JLE\t"); 137ece92f85SJason Jin return (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || 138ece92f85SJason Jin ACCESS_FLAG(F_ZF)); 139ece92f85SJason Jin break; 140ece92f85SJason Jin default: 141ece92f85SJason Jin DECODE_PRINTF("JNLE\t"); 142ece92f85SJason Jin return !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || 143ece92f85SJason Jin ACCESS_FLAG(F_ZF)); 144ece92f85SJason Jin } 145ece92f85SJason Jin } 146ece92f85SJason Jin 147ece92f85SJason Jin void x86emuOp2_long_jump(u8 op2) 148ece92f85SJason Jin { 149ece92f85SJason Jin s32 target; 150ece92f85SJason Jin int cond; 151ece92f85SJason Jin 152ece92f85SJason Jin /* conditional jump to word offset. */ 153ece92f85SJason Jin START_OF_INSTR(); 154ece92f85SJason Jin cond = x86emu_check_jump_condition(op2 & 0xF); 155ece92f85SJason Jin target = (s16) fetch_word_imm(); 156ece92f85SJason Jin target += (s16) M.x86.R_IP; 157ece92f85SJason Jin DECODE_PRINTF2("%04x\n", target); 158ece92f85SJason Jin TRACE_AND_STEP(); 159ece92f85SJason Jin if (cond) 160ece92f85SJason Jin M.x86.R_IP = (u16)target; 161ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 162ece92f85SJason Jin END_OF_INSTR(); 163ece92f85SJason Jin } 164ece92f85SJason Jin 165ece92f85SJason Jin /**************************************************************************** 166ece92f85SJason Jin REMARKS: 167ece92f85SJason Jin Handles opcode 0x0f,0x90-0x9F 168ece92f85SJason Jin ****************************************************************************/ 169ece92f85SJason Jin void x86emuOp2_set_byte(u8 op2) 170ece92f85SJason Jin { 171ece92f85SJason Jin int mod, rl, rh; 172ece92f85SJason Jin uint destoffset; 173ece92f85SJason Jin u8 *destreg; 174ece92f85SJason Jin char *name = 0; 175ece92f85SJason Jin int cond = 0; 176ece92f85SJason Jin 177ece92f85SJason Jin START_OF_INSTR(); 178ece92f85SJason Jin switch (op2) { 179ece92f85SJason Jin case 0x90: 180ece92f85SJason Jin name = "SETO\t"; 181ece92f85SJason Jin cond = ACCESS_FLAG(F_OF); 182ece92f85SJason Jin break; 183ece92f85SJason Jin case 0x91: 184ece92f85SJason Jin name = "SETNO\t"; 185ece92f85SJason Jin cond = !ACCESS_FLAG(F_OF); 186ece92f85SJason Jin break; 187ece92f85SJason Jin case 0x92: 188ece92f85SJason Jin name = "SETB\t"; 189ece92f85SJason Jin cond = ACCESS_FLAG(F_CF); 190ece92f85SJason Jin break; 191ece92f85SJason Jin case 0x93: 192ece92f85SJason Jin name = "SETNB\t"; 193ece92f85SJason Jin cond = !ACCESS_FLAG(F_CF); 194ece92f85SJason Jin break; 195ece92f85SJason Jin case 0x94: 196ece92f85SJason Jin name = "SETZ\t"; 197ece92f85SJason Jin cond = ACCESS_FLAG(F_ZF); 198ece92f85SJason Jin break; 199ece92f85SJason Jin case 0x95: 200ece92f85SJason Jin name = "SETNZ\t"; 201ece92f85SJason Jin cond = !ACCESS_FLAG(F_ZF); 202ece92f85SJason Jin break; 203ece92f85SJason Jin case 0x96: 204ece92f85SJason Jin name = "SETBE\t"; 205ece92f85SJason Jin cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF); 206ece92f85SJason Jin break; 207ece92f85SJason Jin case 0x97: 208ece92f85SJason Jin name = "SETNBE\t"; 209ece92f85SJason Jin cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)); 210ece92f85SJason Jin break; 211ece92f85SJason Jin case 0x98: 212ece92f85SJason Jin name = "SETS\t"; 213ece92f85SJason Jin cond = ACCESS_FLAG(F_SF); 214ece92f85SJason Jin break; 215ece92f85SJason Jin case 0x99: 216ece92f85SJason Jin name = "SETNS\t"; 217ece92f85SJason Jin cond = !ACCESS_FLAG(F_SF); 218ece92f85SJason Jin break; 219ece92f85SJason Jin case 0x9a: 220ece92f85SJason Jin name = "SETP\t"; 221ece92f85SJason Jin cond = ACCESS_FLAG(F_PF); 222ece92f85SJason Jin break; 223ece92f85SJason Jin case 0x9b: 224ece92f85SJason Jin name = "SETNP\t"; 225ece92f85SJason Jin cond = !ACCESS_FLAG(F_PF); 226ece92f85SJason Jin break; 227ece92f85SJason Jin case 0x9c: 228ece92f85SJason Jin name = "SETL\t"; 229ece92f85SJason Jin cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); 230ece92f85SJason Jin break; 231ece92f85SJason Jin case 0x9d: 232ece92f85SJason Jin name = "SETNL\t"; 233ece92f85SJason Jin cond = !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); 234ece92f85SJason Jin break; 235ece92f85SJason Jin case 0x9e: 236ece92f85SJason Jin name = "SETLE\t"; 237ece92f85SJason Jin cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || 238ece92f85SJason Jin ACCESS_FLAG(F_ZF)); 239ece92f85SJason Jin break; 240ece92f85SJason Jin case 0x9f: 241ece92f85SJason Jin name = "SETNLE\t"; 242ece92f85SJason Jin cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || 243ece92f85SJason Jin ACCESS_FLAG(F_ZF)); 244ece92f85SJason Jin break; 245ece92f85SJason Jin } 246ece92f85SJason Jin DECODE_PRINTF(name); 247ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 248ece92f85SJason Jin if (mod < 3) { 249ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 250ece92f85SJason Jin TRACE_AND_STEP(); 251ece92f85SJason Jin store_data_byte(destoffset, cond ? 0x01 : 0x00); 252ece92f85SJason Jin } else { /* register to register */ 253ece92f85SJason Jin destreg = DECODE_RM_BYTE_REGISTER(rl); 254ece92f85SJason Jin TRACE_AND_STEP(); 255ece92f85SJason Jin *destreg = cond ? 0x01 : 0x00; 256ece92f85SJason Jin } 257ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 258ece92f85SJason Jin END_OF_INSTR(); 259ece92f85SJason Jin } 260ece92f85SJason Jin 261ece92f85SJason Jin /**************************************************************************** 262ece92f85SJason Jin REMARKS: 263ece92f85SJason Jin Handles opcode 0x0f,0xa0 264ece92f85SJason Jin ****************************************************************************/ 265ece92f85SJason Jin void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2)) 266ece92f85SJason Jin { 267ece92f85SJason Jin START_OF_INSTR(); 268ece92f85SJason Jin DECODE_PRINTF("PUSH\tFS\n"); 269ece92f85SJason Jin TRACE_AND_STEP(); 270ece92f85SJason Jin push_word(M.x86.R_FS); 271ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 272ece92f85SJason Jin END_OF_INSTR(); 273ece92f85SJason Jin } 274ece92f85SJason Jin 275ece92f85SJason Jin /**************************************************************************** 276ece92f85SJason Jin REMARKS: 277ece92f85SJason Jin Handles opcode 0x0f,0xa1 278ece92f85SJason Jin ****************************************************************************/ 279ece92f85SJason Jin void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2)) 280ece92f85SJason Jin { 281ece92f85SJason Jin START_OF_INSTR(); 282ece92f85SJason Jin DECODE_PRINTF("POP\tFS\n"); 283ece92f85SJason Jin TRACE_AND_STEP(); 284ece92f85SJason Jin M.x86.R_FS = pop_word(); 285ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 286ece92f85SJason Jin END_OF_INSTR(); 287ece92f85SJason Jin } 288ece92f85SJason Jin 289ece92f85SJason Jin /**************************************************************************** 290ece92f85SJason Jin REMARKS: 291ece92f85SJason Jin Handles opcode 0x0f,0xa3 292ece92f85SJason Jin ****************************************************************************/ 293ece92f85SJason Jin void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2)) 294ece92f85SJason Jin { 295ece92f85SJason Jin int mod, rl, rh; 296ece92f85SJason Jin uint srcoffset; 297ece92f85SJason Jin int bit,disp; 298ece92f85SJason Jin 299ece92f85SJason Jin START_OF_INSTR(); 300ece92f85SJason Jin DECODE_PRINTF("BT\t"); 301ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 302ece92f85SJason Jin if (mod < 3) { 303ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 304ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 305ece92f85SJason Jin u32 srcval; 306ece92f85SJason Jin u32 *shiftreg; 307ece92f85SJason Jin 308ece92f85SJason Jin DECODE_PRINTF(","); 309ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh); 310ece92f85SJason Jin TRACE_AND_STEP(); 311ece92f85SJason Jin bit = *shiftreg & 0x1F; 312ece92f85SJason Jin disp = (s16)*shiftreg >> 5; 313ece92f85SJason Jin srcval = fetch_data_long(srcoffset+disp); 314ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF); 315ece92f85SJason Jin } else { 316ece92f85SJason Jin u16 srcval; 317ece92f85SJason Jin u16 *shiftreg; 318ece92f85SJason Jin 319ece92f85SJason Jin DECODE_PRINTF(","); 320ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh); 321ece92f85SJason Jin TRACE_AND_STEP(); 322ece92f85SJason Jin bit = *shiftreg & 0xF; 323ece92f85SJason Jin disp = (s16)*shiftreg >> 4; 324ece92f85SJason Jin srcval = fetch_data_word(srcoffset+disp); 325ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF); 326ece92f85SJason Jin } 327ece92f85SJason Jin } else { /* register to register */ 328ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 329ece92f85SJason Jin u32 *srcreg,*shiftreg; 330ece92f85SJason Jin 331ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl); 332ece92f85SJason Jin DECODE_PRINTF(","); 333ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh); 334ece92f85SJason Jin TRACE_AND_STEP(); 335ece92f85SJason Jin bit = *shiftreg & 0x1F; 336ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF); 337ece92f85SJason Jin } else { 338ece92f85SJason Jin u16 *srcreg,*shiftreg; 339ece92f85SJason Jin 340ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl); 341ece92f85SJason Jin DECODE_PRINTF(","); 342ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh); 343ece92f85SJason Jin TRACE_AND_STEP(); 344ece92f85SJason Jin bit = *shiftreg & 0xF; 345ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF); 346ece92f85SJason Jin } 347ece92f85SJason Jin } 348ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 349ece92f85SJason Jin END_OF_INSTR(); 350ece92f85SJason Jin } 351ece92f85SJason Jin 352ece92f85SJason Jin /**************************************************************************** 353ece92f85SJason Jin REMARKS: 354ece92f85SJason Jin Handles opcode 0x0f,0xa4 355ece92f85SJason Jin ****************************************************************************/ 356ece92f85SJason Jin void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2)) 357ece92f85SJason Jin { 358ece92f85SJason Jin int mod, rl, rh; 359ece92f85SJason Jin uint destoffset; 360ece92f85SJason Jin u8 shift; 361ece92f85SJason Jin 362ece92f85SJason Jin START_OF_INSTR(); 363ece92f85SJason Jin DECODE_PRINTF("SHLD\t"); 364ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 365ece92f85SJason Jin if (mod < 3) { 366ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 367ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 368ece92f85SJason Jin u32 destval; 369ece92f85SJason Jin u32 *shiftreg; 370ece92f85SJason Jin 371ece92f85SJason Jin DECODE_PRINTF(","); 372ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh); 373ece92f85SJason Jin DECODE_PRINTF(","); 374ece92f85SJason Jin shift = fetch_byte_imm(); 375ece92f85SJason Jin DECODE_PRINTF2("%d\n", shift); 376ece92f85SJason Jin TRACE_AND_STEP(); 377ece92f85SJason Jin destval = fetch_data_long(destoffset); 378ece92f85SJason Jin destval = shld_long(destval,*shiftreg,shift); 379ece92f85SJason Jin store_data_long(destoffset, destval); 380ece92f85SJason Jin } else { 381ece92f85SJason Jin u16 destval; 382ece92f85SJason Jin u16 *shiftreg; 383ece92f85SJason Jin 384ece92f85SJason Jin DECODE_PRINTF(","); 385ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh); 386ece92f85SJason Jin DECODE_PRINTF(","); 387ece92f85SJason Jin shift = fetch_byte_imm(); 388ece92f85SJason Jin DECODE_PRINTF2("%d\n", shift); 389ece92f85SJason Jin TRACE_AND_STEP(); 390ece92f85SJason Jin destval = fetch_data_word(destoffset); 391ece92f85SJason Jin destval = shld_word(destval,*shiftreg,shift); 392ece92f85SJason Jin store_data_word(destoffset, destval); 393ece92f85SJason Jin } 394ece92f85SJason Jin } else { /* register to register */ 395ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 396ece92f85SJason Jin u32 *destreg,*shiftreg; 397ece92f85SJason Jin 398ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 399ece92f85SJason Jin DECODE_PRINTF(","); 400ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh); 401ece92f85SJason Jin DECODE_PRINTF(","); 402ece92f85SJason Jin shift = fetch_byte_imm(); 403ece92f85SJason Jin DECODE_PRINTF2("%d\n", shift); 404ece92f85SJason Jin TRACE_AND_STEP(); 405ece92f85SJason Jin *destreg = shld_long(*destreg,*shiftreg,shift); 406ece92f85SJason Jin } else { 407ece92f85SJason Jin u16 *destreg,*shiftreg; 408ece92f85SJason Jin 409ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 410ece92f85SJason Jin DECODE_PRINTF(","); 411ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh); 412ece92f85SJason Jin DECODE_PRINTF(","); 413ece92f85SJason Jin shift = fetch_byte_imm(); 414ece92f85SJason Jin DECODE_PRINTF2("%d\n", shift); 415ece92f85SJason Jin TRACE_AND_STEP(); 416ece92f85SJason Jin *destreg = shld_word(*destreg,*shiftreg,shift); 417ece92f85SJason Jin } 418ece92f85SJason Jin } 419ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 420ece92f85SJason Jin END_OF_INSTR(); 421ece92f85SJason Jin } 422ece92f85SJason Jin 423ece92f85SJason Jin /**************************************************************************** 424ece92f85SJason Jin REMARKS: 425ece92f85SJason Jin Handles opcode 0x0f,0xa5 426ece92f85SJason Jin ****************************************************************************/ 427ece92f85SJason Jin void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2)) 428ece92f85SJason Jin { 429ece92f85SJason Jin int mod, rl, rh; 430ece92f85SJason Jin uint destoffset; 431ece92f85SJason Jin 432ece92f85SJason Jin START_OF_INSTR(); 433ece92f85SJason Jin DECODE_PRINTF("SHLD\t"); 434ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 435ece92f85SJason Jin if (mod < 3) { 436ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 437ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 438ece92f85SJason Jin u32 destval; 439ece92f85SJason Jin u32 *shiftreg; 440ece92f85SJason Jin 441ece92f85SJason Jin DECODE_PRINTF(","); 442ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh); 443ece92f85SJason Jin DECODE_PRINTF(",CL\n"); 444ece92f85SJason Jin TRACE_AND_STEP(); 445ece92f85SJason Jin destval = fetch_data_long(destoffset); 446ece92f85SJason Jin destval = shld_long(destval,*shiftreg,M.x86.R_CL); 447ece92f85SJason Jin store_data_long(destoffset, destval); 448ece92f85SJason Jin } else { 449ece92f85SJason Jin u16 destval; 450ece92f85SJason Jin u16 *shiftreg; 451ece92f85SJason Jin 452ece92f85SJason Jin DECODE_PRINTF(","); 453ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh); 454ece92f85SJason Jin DECODE_PRINTF(",CL\n"); 455ece92f85SJason Jin TRACE_AND_STEP(); 456ece92f85SJason Jin destval = fetch_data_word(destoffset); 457ece92f85SJason Jin destval = shld_word(destval,*shiftreg,M.x86.R_CL); 458ece92f85SJason Jin store_data_word(destoffset, destval); 459ece92f85SJason Jin } 460ece92f85SJason Jin } else { /* register to register */ 461ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 462ece92f85SJason Jin u32 *destreg,*shiftreg; 463ece92f85SJason Jin 464ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 465ece92f85SJason Jin DECODE_PRINTF(","); 466ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh); 467ece92f85SJason Jin DECODE_PRINTF(",CL\n"); 468ece92f85SJason Jin TRACE_AND_STEP(); 469ece92f85SJason Jin *destreg = shld_long(*destreg,*shiftreg,M.x86.R_CL); 470ece92f85SJason Jin } else { 471ece92f85SJason Jin u16 *destreg,*shiftreg; 472ece92f85SJason Jin 473ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 474ece92f85SJason Jin DECODE_PRINTF(","); 475ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh); 476ece92f85SJason Jin DECODE_PRINTF(",CL\n"); 477ece92f85SJason Jin TRACE_AND_STEP(); 478ece92f85SJason Jin *destreg = shld_word(*destreg,*shiftreg,M.x86.R_CL); 479ece92f85SJason Jin } 480ece92f85SJason Jin } 481ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 482ece92f85SJason Jin END_OF_INSTR(); 483ece92f85SJason Jin } 484ece92f85SJason Jin 485ece92f85SJason Jin /**************************************************************************** 486ece92f85SJason Jin REMARKS: 487ece92f85SJason Jin Handles opcode 0x0f,0xa8 488ece92f85SJason Jin ****************************************************************************/ 489ece92f85SJason Jin void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2)) 490ece92f85SJason Jin { 491ece92f85SJason Jin START_OF_INSTR(); 492ece92f85SJason Jin DECODE_PRINTF("PUSH\tGS\n"); 493ece92f85SJason Jin TRACE_AND_STEP(); 494ece92f85SJason Jin push_word(M.x86.R_GS); 495ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 496ece92f85SJason Jin END_OF_INSTR(); 497ece92f85SJason Jin } 498ece92f85SJason Jin 499ece92f85SJason Jin /**************************************************************************** 500ece92f85SJason Jin REMARKS: 501ece92f85SJason Jin Handles opcode 0x0f,0xa9 502ece92f85SJason Jin ****************************************************************************/ 503ece92f85SJason Jin void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2)) 504ece92f85SJason Jin { 505ece92f85SJason Jin START_OF_INSTR(); 506ece92f85SJason Jin DECODE_PRINTF("POP\tGS\n"); 507ece92f85SJason Jin TRACE_AND_STEP(); 508ece92f85SJason Jin M.x86.R_GS = pop_word(); 509ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 510ece92f85SJason Jin END_OF_INSTR(); 511ece92f85SJason Jin } 512ece92f85SJason Jin 513ece92f85SJason Jin /**************************************************************************** 514ece92f85SJason Jin REMARKS: 515ece92f85SJason Jin Handles opcode 0x0f,0xaa 516ece92f85SJason Jin ****************************************************************************/ 517ece92f85SJason Jin void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2)) 518ece92f85SJason Jin { 519ece92f85SJason Jin int mod, rl, rh; 520ece92f85SJason Jin uint srcoffset; 521ece92f85SJason Jin int bit,disp; 522ece92f85SJason Jin 523ece92f85SJason Jin START_OF_INSTR(); 524ece92f85SJason Jin DECODE_PRINTF("BTS\t"); 525ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 526ece92f85SJason Jin if (mod < 3) { 527ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 528ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 529ece92f85SJason Jin u32 srcval,mask; 530ece92f85SJason Jin u32 *shiftreg; 531ece92f85SJason Jin 532ece92f85SJason Jin DECODE_PRINTF(","); 533ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh); 534ece92f85SJason Jin TRACE_AND_STEP(); 535ece92f85SJason Jin bit = *shiftreg & 0x1F; 536ece92f85SJason Jin disp = (s16)*shiftreg >> 5; 537ece92f85SJason Jin srcval = fetch_data_long(srcoffset+disp); 538ece92f85SJason Jin mask = (0x1 << bit); 539ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & mask,F_CF); 540ece92f85SJason Jin store_data_long(srcoffset+disp, srcval | mask); 541ece92f85SJason Jin } else { 542ece92f85SJason Jin u16 srcval,mask; 543ece92f85SJason Jin u16 *shiftreg; 544ece92f85SJason Jin 545ece92f85SJason Jin DECODE_PRINTF(","); 546ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh); 547ece92f85SJason Jin TRACE_AND_STEP(); 548ece92f85SJason Jin bit = *shiftreg & 0xF; 549ece92f85SJason Jin disp = (s16)*shiftreg >> 4; 550ece92f85SJason Jin srcval = fetch_data_word(srcoffset+disp); 551ece92f85SJason Jin mask = (u16)(0x1 << bit); 552ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & mask,F_CF); 553ece92f85SJason Jin store_data_word(srcoffset+disp, srcval | mask); 554ece92f85SJason Jin } 555ece92f85SJason Jin } else { /* register to register */ 556ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 557ece92f85SJason Jin u32 *srcreg,*shiftreg; 558ece92f85SJason Jin u32 mask; 559ece92f85SJason Jin 560ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl); 561ece92f85SJason Jin DECODE_PRINTF(","); 562ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh); 563ece92f85SJason Jin TRACE_AND_STEP(); 564ece92f85SJason Jin bit = *shiftreg & 0x1F; 565ece92f85SJason Jin mask = (0x1 << bit); 566ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF); 567ece92f85SJason Jin *srcreg |= mask; 568ece92f85SJason Jin } else { 569ece92f85SJason Jin u16 *srcreg,*shiftreg; 570ece92f85SJason Jin u16 mask; 571ece92f85SJason Jin 572ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl); 573ece92f85SJason Jin DECODE_PRINTF(","); 574ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh); 575ece92f85SJason Jin TRACE_AND_STEP(); 576ece92f85SJason Jin bit = *shiftreg & 0xF; 577ece92f85SJason Jin mask = (u16)(0x1 << bit); 578ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF); 579ece92f85SJason Jin *srcreg |= mask; 580ece92f85SJason Jin } 581ece92f85SJason Jin } 582ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 583ece92f85SJason Jin END_OF_INSTR(); 584ece92f85SJason Jin } 585ece92f85SJason Jin 586ece92f85SJason Jin /**************************************************************************** 587ece92f85SJason Jin REMARKS: 588ece92f85SJason Jin Handles opcode 0x0f,0xac 589ece92f85SJason Jin ****************************************************************************/ 590ece92f85SJason Jin void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2)) 591ece92f85SJason Jin { 592ece92f85SJason Jin int mod, rl, rh; 593ece92f85SJason Jin uint destoffset; 594ece92f85SJason Jin u8 shift; 595ece92f85SJason Jin 596ece92f85SJason Jin START_OF_INSTR(); 597ece92f85SJason Jin DECODE_PRINTF("SHLD\t"); 598ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 599ece92f85SJason Jin if (mod < 3) { 600ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 601ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 602ece92f85SJason Jin u32 destval; 603ece92f85SJason Jin u32 *shiftreg; 604ece92f85SJason Jin 605ece92f85SJason Jin DECODE_PRINTF(","); 606ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh); 607ece92f85SJason Jin DECODE_PRINTF(","); 608ece92f85SJason Jin shift = fetch_byte_imm(); 609ece92f85SJason Jin DECODE_PRINTF2("%d\n", shift); 610ece92f85SJason Jin TRACE_AND_STEP(); 611ece92f85SJason Jin destval = fetch_data_long(destoffset); 612ece92f85SJason Jin destval = shrd_long(destval,*shiftreg,shift); 613ece92f85SJason Jin store_data_long(destoffset, destval); 614ece92f85SJason Jin } else { 615ece92f85SJason Jin u16 destval; 616ece92f85SJason Jin u16 *shiftreg; 617ece92f85SJason Jin 618ece92f85SJason Jin DECODE_PRINTF(","); 619ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh); 620ece92f85SJason Jin DECODE_PRINTF(","); 621ece92f85SJason Jin shift = fetch_byte_imm(); 622ece92f85SJason Jin DECODE_PRINTF2("%d\n", shift); 623ece92f85SJason Jin TRACE_AND_STEP(); 624ece92f85SJason Jin destval = fetch_data_word(destoffset); 625ece92f85SJason Jin destval = shrd_word(destval,*shiftreg,shift); 626ece92f85SJason Jin store_data_word(destoffset, destval); 627ece92f85SJason Jin } 628ece92f85SJason Jin } else { /* register to register */ 629ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 630ece92f85SJason Jin u32 *destreg,*shiftreg; 631ece92f85SJason Jin 632ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 633ece92f85SJason Jin DECODE_PRINTF(","); 634ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh); 635ece92f85SJason Jin DECODE_PRINTF(","); 636ece92f85SJason Jin shift = fetch_byte_imm(); 637ece92f85SJason Jin DECODE_PRINTF2("%d\n", shift); 638ece92f85SJason Jin TRACE_AND_STEP(); 639ece92f85SJason Jin *destreg = shrd_long(*destreg,*shiftreg,shift); 640ece92f85SJason Jin } else { 641ece92f85SJason Jin u16 *destreg,*shiftreg; 642ece92f85SJason Jin 643ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 644ece92f85SJason Jin DECODE_PRINTF(","); 645ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh); 646ece92f85SJason Jin DECODE_PRINTF(","); 647ece92f85SJason Jin shift = fetch_byte_imm(); 648ece92f85SJason Jin DECODE_PRINTF2("%d\n", shift); 649ece92f85SJason Jin TRACE_AND_STEP(); 650ece92f85SJason Jin *destreg = shrd_word(*destreg,*shiftreg,shift); 651ece92f85SJason Jin } 652ece92f85SJason Jin } 653ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 654ece92f85SJason Jin END_OF_INSTR(); 655ece92f85SJason Jin } 656ece92f85SJason Jin 657ece92f85SJason Jin /**************************************************************************** 658ece92f85SJason Jin REMARKS: 659ece92f85SJason Jin Handles opcode 0x0f,0xad 660ece92f85SJason Jin ****************************************************************************/ 661ece92f85SJason Jin void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2)) 662ece92f85SJason Jin { 663ece92f85SJason Jin int mod, rl, rh; 664ece92f85SJason Jin uint destoffset; 665ece92f85SJason Jin 666ece92f85SJason Jin START_OF_INSTR(); 667ece92f85SJason Jin DECODE_PRINTF("SHLD\t"); 668ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 669ece92f85SJason Jin if (mod < 3) { 670ece92f85SJason Jin destoffset = decode_rmXX_address(mod, rl); 671ece92f85SJason Jin DECODE_PRINTF(","); 672ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 673ece92f85SJason Jin u32 destval; 674ece92f85SJason Jin u32 *shiftreg; 675ece92f85SJason Jin 676ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh); 677ece92f85SJason Jin DECODE_PRINTF(",CL\n"); 678ece92f85SJason Jin TRACE_AND_STEP(); 679ece92f85SJason Jin destval = fetch_data_long(destoffset); 680ece92f85SJason Jin destval = shrd_long(destval,*shiftreg,M.x86.R_CL); 681ece92f85SJason Jin store_data_long(destoffset, destval); 682ece92f85SJason Jin } else { 683ece92f85SJason Jin u16 destval; 684ece92f85SJason Jin u16 *shiftreg; 685ece92f85SJason Jin 686ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh); 687ece92f85SJason Jin DECODE_PRINTF(",CL\n"); 688ece92f85SJason Jin TRACE_AND_STEP(); 689ece92f85SJason Jin destval = fetch_data_word(destoffset); 690ece92f85SJason Jin destval = shrd_word(destval,*shiftreg,M.x86.R_CL); 691ece92f85SJason Jin store_data_word(destoffset, destval); 692ece92f85SJason Jin } 693ece92f85SJason Jin } else { /* register to register */ 694ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 695ece92f85SJason Jin u32 *destreg,*shiftreg; 696ece92f85SJason Jin 697ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rl); 698ece92f85SJason Jin DECODE_PRINTF(","); 699ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh); 700ece92f85SJason Jin DECODE_PRINTF(",CL\n"); 701ece92f85SJason Jin TRACE_AND_STEP(); 702ece92f85SJason Jin *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL); 703ece92f85SJason Jin } else { 704ece92f85SJason Jin u16 *destreg,*shiftreg; 705ece92f85SJason Jin 706ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rl); 707ece92f85SJason Jin DECODE_PRINTF(","); 708ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh); 709ece92f85SJason Jin DECODE_PRINTF(",CL\n"); 710ece92f85SJason Jin TRACE_AND_STEP(); 711ece92f85SJason Jin *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL); 712ece92f85SJason Jin } 713ece92f85SJason Jin } 714ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 715ece92f85SJason Jin END_OF_INSTR(); 716ece92f85SJason Jin } 717ece92f85SJason Jin 718ece92f85SJason Jin /**************************************************************************** 719ece92f85SJason Jin REMARKS: 720ece92f85SJason Jin Handles opcode 0x0f,0xaf 721ece92f85SJason Jin ****************************************************************************/ 722ece92f85SJason Jin void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2)) 723ece92f85SJason Jin { 724ece92f85SJason Jin int mod, rl, rh; 725ece92f85SJason Jin uint srcoffset; 726ece92f85SJason Jin 727ece92f85SJason Jin START_OF_INSTR(); 728ece92f85SJason Jin DECODE_PRINTF("IMUL\t"); 729ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 730ece92f85SJason Jin if (mod < 3) { 731ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 732ece92f85SJason Jin u32 *destreg; 733ece92f85SJason Jin u32 srcval; 734ece92f85SJason Jin u32 res_lo,res_hi; 735ece92f85SJason Jin 736ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh); 737ece92f85SJason Jin DECODE_PRINTF(","); 738ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 739ece92f85SJason Jin srcval = fetch_data_long(srcoffset); 740ece92f85SJason Jin TRACE_AND_STEP(); 741ece92f85SJason Jin imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval); 742ece92f85SJason Jin if (res_hi != 0) { 743ece92f85SJason Jin SET_FLAG(F_CF); 744ece92f85SJason Jin SET_FLAG(F_OF); 745ece92f85SJason Jin } else { 746ece92f85SJason Jin CLEAR_FLAG(F_CF); 747ece92f85SJason Jin CLEAR_FLAG(F_OF); 748ece92f85SJason Jin } 749ece92f85SJason Jin *destreg = (u32)res_lo; 750ece92f85SJason Jin } else { 751ece92f85SJason Jin u16 *destreg; 752ece92f85SJason Jin u16 srcval; 753ece92f85SJason Jin u32 res; 754ece92f85SJason Jin 755ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh); 756ece92f85SJason Jin DECODE_PRINTF(","); 757ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 758ece92f85SJason Jin srcval = fetch_data_word(srcoffset); 759ece92f85SJason Jin TRACE_AND_STEP(); 760ece92f85SJason Jin res = (s16)*destreg * (s16)srcval; 761ece92f85SJason Jin if (res > 0xFFFF) { 762ece92f85SJason Jin SET_FLAG(F_CF); 763ece92f85SJason Jin SET_FLAG(F_OF); 764ece92f85SJason Jin } else { 765ece92f85SJason Jin CLEAR_FLAG(F_CF); 766ece92f85SJason Jin CLEAR_FLAG(F_OF); 767ece92f85SJason Jin } 768ece92f85SJason Jin *destreg = (u16)res; 769ece92f85SJason Jin } 770ece92f85SJason Jin } else { /* register to register */ 771ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 772ece92f85SJason Jin u32 *destreg,*srcreg; 773ece92f85SJason Jin u32 res_lo,res_hi; 774ece92f85SJason Jin 775ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh); 776ece92f85SJason Jin DECODE_PRINTF(","); 777ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl); 778ece92f85SJason Jin TRACE_AND_STEP(); 779ece92f85SJason Jin imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg); 780ece92f85SJason Jin if (res_hi != 0) { 781ece92f85SJason Jin SET_FLAG(F_CF); 782ece92f85SJason Jin SET_FLAG(F_OF); 783ece92f85SJason Jin } else { 784ece92f85SJason Jin CLEAR_FLAG(F_CF); 785ece92f85SJason Jin CLEAR_FLAG(F_OF); 786ece92f85SJason Jin } 787ece92f85SJason Jin *destreg = (u32)res_lo; 788ece92f85SJason Jin } else { 789ece92f85SJason Jin u16 *destreg,*srcreg; 790ece92f85SJason Jin u32 res; 791ece92f85SJason Jin 792ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh); 793ece92f85SJason Jin DECODE_PRINTF(","); 794ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl); 795ece92f85SJason Jin res = (s16)*destreg * (s16)*srcreg; 796ece92f85SJason Jin if (res > 0xFFFF) { 797ece92f85SJason Jin SET_FLAG(F_CF); 798ece92f85SJason Jin SET_FLAG(F_OF); 799ece92f85SJason Jin } else { 800ece92f85SJason Jin CLEAR_FLAG(F_CF); 801ece92f85SJason Jin CLEAR_FLAG(F_OF); 802ece92f85SJason Jin } 803ece92f85SJason Jin *destreg = (u16)res; 804ece92f85SJason Jin } 805ece92f85SJason Jin } 806ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 807ece92f85SJason Jin END_OF_INSTR(); 808ece92f85SJason Jin } 809ece92f85SJason Jin 810ece92f85SJason Jin /**************************************************************************** 811ece92f85SJason Jin REMARKS: 812ece92f85SJason Jin Handles opcode 0x0f,0xb2 813ece92f85SJason Jin ****************************************************************************/ 814ece92f85SJason Jin void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2)) 815ece92f85SJason Jin { 816ece92f85SJason Jin int mod, rh, rl; 817ece92f85SJason Jin u16 *dstreg; 818ece92f85SJason Jin uint srcoffset; 819ece92f85SJason Jin 820ece92f85SJason Jin START_OF_INSTR(); 821ece92f85SJason Jin DECODE_PRINTF("LSS\t"); 822ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 823ece92f85SJason Jin if (mod < 3) { 824ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh); 825ece92f85SJason Jin DECODE_PRINTF(","); 826ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 827ece92f85SJason Jin DECODE_PRINTF("\n"); 828ece92f85SJason Jin TRACE_AND_STEP(); 829ece92f85SJason Jin *dstreg = fetch_data_word(srcoffset); 830ece92f85SJason Jin M.x86.R_SS = fetch_data_word(srcoffset + 2); 831ece92f85SJason Jin } else { /* register to register */ 832ece92f85SJason Jin /* UNDEFINED! */ 833ece92f85SJason Jin TRACE_AND_STEP(); 834ece92f85SJason Jin } 835ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 836ece92f85SJason Jin END_OF_INSTR(); 837ece92f85SJason Jin } 838ece92f85SJason Jin 839ece92f85SJason Jin /**************************************************************************** 840ece92f85SJason Jin REMARKS: 841ece92f85SJason Jin Handles opcode 0x0f,0xb3 842ece92f85SJason Jin ****************************************************************************/ 843ece92f85SJason Jin void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2)) 844ece92f85SJason Jin { 845ece92f85SJason Jin int mod, rl, rh; 846ece92f85SJason Jin uint srcoffset; 847ece92f85SJason Jin int bit,disp; 848ece92f85SJason Jin 849ece92f85SJason Jin START_OF_INSTR(); 850ece92f85SJason Jin DECODE_PRINTF("BTR\t"); 851ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 852ece92f85SJason Jin if (mod < 3) { 853ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 854ece92f85SJason Jin DECODE_PRINTF(","); 855ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 856ece92f85SJason Jin u32 srcval,mask; 857ece92f85SJason Jin u32 *shiftreg; 858ece92f85SJason Jin 859ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh); 860ece92f85SJason Jin TRACE_AND_STEP(); 861ece92f85SJason Jin bit = *shiftreg & 0x1F; 862ece92f85SJason Jin disp = (s16)*shiftreg >> 5; 863ece92f85SJason Jin srcval = fetch_data_long(srcoffset+disp); 864ece92f85SJason Jin mask = (0x1 << bit); 865ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & mask,F_CF); 866ece92f85SJason Jin store_data_long(srcoffset+disp, srcval & ~mask); 867ece92f85SJason Jin } else { 868ece92f85SJason Jin u16 srcval,mask; 869ece92f85SJason Jin u16 *shiftreg; 870ece92f85SJason Jin 871ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh); 872ece92f85SJason Jin TRACE_AND_STEP(); 873ece92f85SJason Jin bit = *shiftreg & 0xF; 874ece92f85SJason Jin disp = (s16)*shiftreg >> 4; 875ece92f85SJason Jin srcval = fetch_data_word(srcoffset+disp); 876ece92f85SJason Jin mask = (u16)(0x1 << bit); 877ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & mask,F_CF); 878ece92f85SJason Jin store_data_word(srcoffset+disp, (u16)(srcval & ~mask)); 879ece92f85SJason Jin } 880ece92f85SJason Jin } else { /* register to register */ 881ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 882ece92f85SJason Jin u32 *srcreg,*shiftreg; 883ece92f85SJason Jin u32 mask; 884ece92f85SJason Jin 885ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl); 886ece92f85SJason Jin DECODE_PRINTF(","); 887ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh); 888ece92f85SJason Jin TRACE_AND_STEP(); 889ece92f85SJason Jin bit = *shiftreg & 0x1F; 890ece92f85SJason Jin mask = (0x1 << bit); 891ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF); 892ece92f85SJason Jin *srcreg &= ~mask; 893ece92f85SJason Jin } else { 894ece92f85SJason Jin u16 *srcreg,*shiftreg; 895ece92f85SJason Jin u16 mask; 896ece92f85SJason Jin 897ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl); 898ece92f85SJason Jin DECODE_PRINTF(","); 899ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh); 900ece92f85SJason Jin TRACE_AND_STEP(); 901ece92f85SJason Jin bit = *shiftreg & 0xF; 902ece92f85SJason Jin mask = (u16)(0x1 << bit); 903ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF); 904ece92f85SJason Jin *srcreg &= ~mask; 905ece92f85SJason Jin } 906ece92f85SJason Jin } 907ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 908ece92f85SJason Jin END_OF_INSTR(); 909ece92f85SJason Jin } 910ece92f85SJason Jin 911ece92f85SJason Jin /**************************************************************************** 912ece92f85SJason Jin REMARKS: 913ece92f85SJason Jin Handles opcode 0x0f,0xb4 914ece92f85SJason Jin ****************************************************************************/ 915ece92f85SJason Jin void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2)) 916ece92f85SJason Jin { 917ece92f85SJason Jin int mod, rh, rl; 918ece92f85SJason Jin u16 *dstreg; 919ece92f85SJason Jin uint srcoffset; 920ece92f85SJason Jin 921ece92f85SJason Jin START_OF_INSTR(); 922ece92f85SJason Jin DECODE_PRINTF("LFS\t"); 923ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 924ece92f85SJason Jin if (mod < 3) { 925ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh); 926ece92f85SJason Jin DECODE_PRINTF(","); 927ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 928ece92f85SJason Jin DECODE_PRINTF("\n"); 929ece92f85SJason Jin TRACE_AND_STEP(); 930ece92f85SJason Jin *dstreg = fetch_data_word(srcoffset); 931ece92f85SJason Jin M.x86.R_FS = fetch_data_word(srcoffset + 2); 932ece92f85SJason Jin } else { /* register to register */ 933ece92f85SJason Jin /* UNDEFINED! */ 934ece92f85SJason Jin TRACE_AND_STEP(); 935ece92f85SJason Jin } 936ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 937ece92f85SJason Jin END_OF_INSTR(); 938ece92f85SJason Jin } 939ece92f85SJason Jin 940ece92f85SJason Jin /**************************************************************************** 941ece92f85SJason Jin REMARKS: 942ece92f85SJason Jin Handles opcode 0x0f,0xb5 943ece92f85SJason Jin ****************************************************************************/ 944ece92f85SJason Jin void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2)) 945ece92f85SJason Jin { 946ece92f85SJason Jin int mod, rh, rl; 947ece92f85SJason Jin u16 *dstreg; 948ece92f85SJason Jin uint srcoffset; 949ece92f85SJason Jin 950ece92f85SJason Jin START_OF_INSTR(); 951ece92f85SJason Jin DECODE_PRINTF("LGS\t"); 952ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 953ece92f85SJason Jin if (mod < 3) { 954ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh); 955ece92f85SJason Jin DECODE_PRINTF(","); 956ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 957ece92f85SJason Jin DECODE_PRINTF("\n"); 958ece92f85SJason Jin TRACE_AND_STEP(); 959ece92f85SJason Jin *dstreg = fetch_data_word(srcoffset); 960ece92f85SJason Jin M.x86.R_GS = fetch_data_word(srcoffset + 2); 961ece92f85SJason Jin } else { /* register to register */ 962ece92f85SJason Jin /* UNDEFINED! */ 963ece92f85SJason Jin TRACE_AND_STEP(); 964ece92f85SJason Jin } 965ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 966ece92f85SJason Jin END_OF_INSTR(); 967ece92f85SJason Jin } 968ece92f85SJason Jin 969ece92f85SJason Jin /**************************************************************************** 970ece92f85SJason Jin REMARKS: 971ece92f85SJason Jin Handles opcode 0x0f,0xb6 972ece92f85SJason Jin ****************************************************************************/ 973ece92f85SJason Jin void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2)) 974ece92f85SJason Jin { 975ece92f85SJason Jin int mod, rl, rh; 976ece92f85SJason Jin uint srcoffset; 977ece92f85SJason Jin 978ece92f85SJason Jin START_OF_INSTR(); 979ece92f85SJason Jin DECODE_PRINTF("MOVZX\t"); 980ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 981ece92f85SJason Jin if (mod < 3) { 982ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 983ece92f85SJason Jin u32 *destreg; 984ece92f85SJason Jin u32 srcval; 985ece92f85SJason Jin 986ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh); 987ece92f85SJason Jin DECODE_PRINTF(","); 988ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 989ece92f85SJason Jin srcval = fetch_data_byte(srcoffset); 990ece92f85SJason Jin DECODE_PRINTF("\n"); 991ece92f85SJason Jin TRACE_AND_STEP(); 992ece92f85SJason Jin *destreg = srcval; 993ece92f85SJason Jin } else { 994ece92f85SJason Jin u16 *destreg; 995ece92f85SJason Jin u16 srcval; 996ece92f85SJason Jin 997ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh); 998ece92f85SJason Jin DECODE_PRINTF(","); 999ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 1000ece92f85SJason Jin srcval = fetch_data_byte(srcoffset); 1001ece92f85SJason Jin DECODE_PRINTF("\n"); 1002ece92f85SJason Jin TRACE_AND_STEP(); 1003ece92f85SJason Jin *destreg = srcval; 1004ece92f85SJason Jin } 1005ece92f85SJason Jin } else { /* register to register */ 1006ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1007ece92f85SJason Jin u32 *destreg; 1008ece92f85SJason Jin u8 *srcreg; 1009ece92f85SJason Jin 1010ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh); 1011ece92f85SJason Jin DECODE_PRINTF(","); 1012ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rl); 1013ece92f85SJason Jin DECODE_PRINTF("\n"); 1014ece92f85SJason Jin TRACE_AND_STEP(); 1015ece92f85SJason Jin *destreg = *srcreg; 1016ece92f85SJason Jin } else { 1017ece92f85SJason Jin u16 *destreg; 1018ece92f85SJason Jin u8 *srcreg; 1019ece92f85SJason Jin 1020ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh); 1021ece92f85SJason Jin DECODE_PRINTF(","); 1022ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rl); 1023ece92f85SJason Jin DECODE_PRINTF("\n"); 1024ece92f85SJason Jin TRACE_AND_STEP(); 1025ece92f85SJason Jin *destreg = *srcreg; 1026ece92f85SJason Jin } 1027ece92f85SJason Jin } 1028ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1029ece92f85SJason Jin END_OF_INSTR(); 1030ece92f85SJason Jin } 1031ece92f85SJason Jin 1032ece92f85SJason Jin /**************************************************************************** 1033ece92f85SJason Jin REMARKS: 1034ece92f85SJason Jin Handles opcode 0x0f,0xb7 1035ece92f85SJason Jin ****************************************************************************/ 1036ece92f85SJason Jin void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2)) 1037ece92f85SJason Jin { 1038ece92f85SJason Jin int mod, rl, rh; 1039ece92f85SJason Jin uint srcoffset; 1040ece92f85SJason Jin u32 *destreg; 1041ece92f85SJason Jin u32 srcval; 1042ece92f85SJason Jin u16 *srcreg; 1043ece92f85SJason Jin 1044ece92f85SJason Jin START_OF_INSTR(); 1045ece92f85SJason Jin DECODE_PRINTF("MOVZX\t"); 1046ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1047ece92f85SJason Jin if (mod < 3) { 1048ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh); 1049ece92f85SJason Jin DECODE_PRINTF(","); 1050ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 1051ece92f85SJason Jin srcval = fetch_data_word(srcoffset); 1052ece92f85SJason Jin DECODE_PRINTF("\n"); 1053ece92f85SJason Jin TRACE_AND_STEP(); 1054ece92f85SJason Jin *destreg = srcval; 1055ece92f85SJason Jin } else { /* register to register */ 1056ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh); 1057ece92f85SJason Jin DECODE_PRINTF(","); 1058ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl); 1059ece92f85SJason Jin DECODE_PRINTF("\n"); 1060ece92f85SJason Jin TRACE_AND_STEP(); 1061ece92f85SJason Jin *destreg = *srcreg; 1062ece92f85SJason Jin } 1063ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1064ece92f85SJason Jin END_OF_INSTR(); 1065ece92f85SJason Jin } 1066ece92f85SJason Jin 1067ece92f85SJason Jin /**************************************************************************** 1068ece92f85SJason Jin REMARKS: 1069ece92f85SJason Jin Handles opcode 0x0f,0xba 1070ece92f85SJason Jin ****************************************************************************/ 1071ece92f85SJason Jin void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2)) 1072ece92f85SJason Jin { 1073ece92f85SJason Jin int mod, rl, rh; 1074ece92f85SJason Jin uint srcoffset; 1075ece92f85SJason Jin u8 shift; 1076ece92f85SJason Jin int bit; 1077ece92f85SJason Jin 1078ece92f85SJason Jin START_OF_INSTR(); 1079ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1080ece92f85SJason Jin switch (rh) { 1081ece92f85SJason Jin case 4: 1082ece92f85SJason Jin DECODE_PRINTF("BT\t"); 1083ece92f85SJason Jin break; 1084ece92f85SJason Jin case 5: 1085ece92f85SJason Jin DECODE_PRINTF("BTS\t"); 1086ece92f85SJason Jin break; 1087ece92f85SJason Jin case 6: 1088ece92f85SJason Jin DECODE_PRINTF("BTR\t"); 1089ece92f85SJason Jin break; 1090ece92f85SJason Jin case 7: 1091ece92f85SJason Jin DECODE_PRINTF("BTC\t"); 1092ece92f85SJason Jin break; 1093ece92f85SJason Jin default: 1094ece92f85SJason Jin DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n"); 1095ece92f85SJason Jin TRACE_REGS(); 1096ece92f85SJason Jin printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n", 1097ece92f85SJason Jin M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl); 1098ece92f85SJason Jin HALT_SYS(); 1099ece92f85SJason Jin } 1100ece92f85SJason Jin if (mod < 3) { 1101ece92f85SJason Jin 1102ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 1103ece92f85SJason Jin shift = fetch_byte_imm(); 1104ece92f85SJason Jin DECODE_PRINTF2(",%d\n", shift); 1105ece92f85SJason Jin TRACE_AND_STEP(); 1106ece92f85SJason Jin 1107ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1108ece92f85SJason Jin u32 srcval, mask; 1109ece92f85SJason Jin 1110ece92f85SJason Jin bit = shift & 0x1F; 1111ece92f85SJason Jin srcval = fetch_data_long(srcoffset); 1112ece92f85SJason Jin mask = (0x1 << bit); 1113ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & mask,F_CF); 1114ece92f85SJason Jin switch (rh) { 1115ece92f85SJason Jin case 5: 1116ece92f85SJason Jin store_data_long(srcoffset, srcval | mask); 1117ece92f85SJason Jin break; 1118ece92f85SJason Jin case 6: 1119ece92f85SJason Jin store_data_long(srcoffset, srcval & ~mask); 1120ece92f85SJason Jin break; 1121ece92f85SJason Jin case 7: 1122ece92f85SJason Jin store_data_long(srcoffset, srcval ^ mask); 1123ece92f85SJason Jin break; 1124ece92f85SJason Jin default: 1125ece92f85SJason Jin break; 1126ece92f85SJason Jin } 1127ece92f85SJason Jin } else { 1128ece92f85SJason Jin u16 srcval, mask; 1129ece92f85SJason Jin 1130ece92f85SJason Jin bit = shift & 0xF; 1131ece92f85SJason Jin srcval = fetch_data_word(srcoffset); 1132ece92f85SJason Jin mask = (0x1 << bit); 1133ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & mask,F_CF); 1134ece92f85SJason Jin switch (rh) { 1135ece92f85SJason Jin case 5: 1136ece92f85SJason Jin store_data_word(srcoffset, srcval | mask); 1137ece92f85SJason Jin break; 1138ece92f85SJason Jin case 6: 1139ece92f85SJason Jin store_data_word(srcoffset, srcval & ~mask); 1140ece92f85SJason Jin break; 1141ece92f85SJason Jin case 7: 1142ece92f85SJason Jin store_data_word(srcoffset, srcval ^ mask); 1143ece92f85SJason Jin break; 1144ece92f85SJason Jin default: 1145ece92f85SJason Jin break; 1146ece92f85SJason Jin } 1147ece92f85SJason Jin } 1148ece92f85SJason Jin } else { /* register to register */ 1149ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1150ece92f85SJason Jin u32 *srcreg; 1151ece92f85SJason Jin u32 mask; 1152ece92f85SJason Jin 1153ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl); 1154ece92f85SJason Jin shift = fetch_byte_imm(); 1155ece92f85SJason Jin DECODE_PRINTF2(",%d\n", shift); 1156ece92f85SJason Jin TRACE_AND_STEP(); 1157ece92f85SJason Jin bit = shift & 0x1F; 1158ece92f85SJason Jin mask = (0x1 << bit); 1159ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF); 1160ece92f85SJason Jin switch (rh) { 1161ece92f85SJason Jin case 5: 1162ece92f85SJason Jin *srcreg |= mask; 1163ece92f85SJason Jin break; 1164ece92f85SJason Jin case 6: 1165ece92f85SJason Jin *srcreg &= ~mask; 1166ece92f85SJason Jin break; 1167ece92f85SJason Jin case 7: 1168ece92f85SJason Jin *srcreg ^= mask; 1169ece92f85SJason Jin break; 1170ece92f85SJason Jin default: 1171ece92f85SJason Jin break; 1172ece92f85SJason Jin } 1173ece92f85SJason Jin } else { 1174ece92f85SJason Jin u16 *srcreg; 1175ece92f85SJason Jin u16 mask; 1176ece92f85SJason Jin 1177ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl); 1178ece92f85SJason Jin shift = fetch_byte_imm(); 1179ece92f85SJason Jin DECODE_PRINTF2(",%d\n", shift); 1180ece92f85SJason Jin TRACE_AND_STEP(); 1181ece92f85SJason Jin bit = shift & 0xF; 1182ece92f85SJason Jin mask = (0x1 << bit); 1183ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF); 1184ece92f85SJason Jin switch (rh) { 1185ece92f85SJason Jin case 5: 1186ece92f85SJason Jin *srcreg |= mask; 1187ece92f85SJason Jin break; 1188ece92f85SJason Jin case 6: 1189ece92f85SJason Jin *srcreg &= ~mask; 1190ece92f85SJason Jin break; 1191ece92f85SJason Jin case 7: 1192ece92f85SJason Jin *srcreg ^= mask; 1193ece92f85SJason Jin break; 1194ece92f85SJason Jin default: 1195ece92f85SJason Jin break; 1196ece92f85SJason Jin } 1197ece92f85SJason Jin } 1198ece92f85SJason Jin } 1199ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1200ece92f85SJason Jin END_OF_INSTR(); 1201ece92f85SJason Jin } 1202ece92f85SJason Jin 1203ece92f85SJason Jin /**************************************************************************** 1204ece92f85SJason Jin REMARKS: 1205ece92f85SJason Jin Handles opcode 0x0f,0xbb 1206ece92f85SJason Jin ****************************************************************************/ 1207ece92f85SJason Jin void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2)) 1208ece92f85SJason Jin { 1209ece92f85SJason Jin int mod, rl, rh; 1210ece92f85SJason Jin uint srcoffset; 1211ece92f85SJason Jin int bit,disp; 1212ece92f85SJason Jin 1213ece92f85SJason Jin START_OF_INSTR(); 1214ece92f85SJason Jin DECODE_PRINTF("BTC\t"); 1215ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1216ece92f85SJason Jin if (mod < 3) { 1217ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 1218ece92f85SJason Jin DECODE_PRINTF(","); 1219ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1220ece92f85SJason Jin u32 srcval,mask; 1221ece92f85SJason Jin u32 *shiftreg; 1222ece92f85SJason Jin 1223ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh); 1224ece92f85SJason Jin TRACE_AND_STEP(); 1225ece92f85SJason Jin bit = *shiftreg & 0x1F; 1226ece92f85SJason Jin disp = (s16)*shiftreg >> 5; 1227ece92f85SJason Jin srcval = fetch_data_long(srcoffset+disp); 1228ece92f85SJason Jin mask = (0x1 << bit); 1229ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & mask,F_CF); 1230ece92f85SJason Jin store_data_long(srcoffset+disp, srcval ^ mask); 1231ece92f85SJason Jin } else { 1232ece92f85SJason Jin u16 srcval,mask; 1233ece92f85SJason Jin u16 *shiftreg; 1234ece92f85SJason Jin 1235ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh); 1236ece92f85SJason Jin TRACE_AND_STEP(); 1237ece92f85SJason Jin bit = *shiftreg & 0xF; 1238ece92f85SJason Jin disp = (s16)*shiftreg >> 4; 1239ece92f85SJason Jin srcval = fetch_data_word(srcoffset+disp); 1240ece92f85SJason Jin mask = (u16)(0x1 << bit); 1241ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval & mask,F_CF); 1242ece92f85SJason Jin store_data_word(srcoffset+disp, (u16)(srcval ^ mask)); 1243ece92f85SJason Jin } 1244ece92f85SJason Jin } else { /* register to register */ 1245ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1246ece92f85SJason Jin u32 *srcreg,*shiftreg; 1247ece92f85SJason Jin u32 mask; 1248ece92f85SJason Jin 1249ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl); 1250ece92f85SJason Jin DECODE_PRINTF(","); 1251ece92f85SJason Jin shiftreg = DECODE_RM_LONG_REGISTER(rh); 1252ece92f85SJason Jin TRACE_AND_STEP(); 1253ece92f85SJason Jin bit = *shiftreg & 0x1F; 1254ece92f85SJason Jin mask = (0x1 << bit); 1255ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF); 1256ece92f85SJason Jin *srcreg ^= mask; 1257ece92f85SJason Jin } else { 1258ece92f85SJason Jin u16 *srcreg,*shiftreg; 1259ece92f85SJason Jin u16 mask; 1260ece92f85SJason Jin 1261ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl); 1262ece92f85SJason Jin DECODE_PRINTF(","); 1263ece92f85SJason Jin shiftreg = DECODE_RM_WORD_REGISTER(rh); 1264ece92f85SJason Jin TRACE_AND_STEP(); 1265ece92f85SJason Jin bit = *shiftreg & 0xF; 1266ece92f85SJason Jin mask = (u16)(0x1 << bit); 1267ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF); 1268ece92f85SJason Jin *srcreg ^= mask; 1269ece92f85SJason Jin } 1270ece92f85SJason Jin } 1271ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1272ece92f85SJason Jin END_OF_INSTR(); 1273ece92f85SJason Jin } 1274ece92f85SJason Jin 1275ece92f85SJason Jin /**************************************************************************** 1276ece92f85SJason Jin REMARKS: 1277ece92f85SJason Jin Handles opcode 0x0f,0xbc 1278ece92f85SJason Jin ****************************************************************************/ 1279ece92f85SJason Jin void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2)) 1280ece92f85SJason Jin { 1281ece92f85SJason Jin int mod, rl, rh; 1282ece92f85SJason Jin uint srcoffset; 1283ece92f85SJason Jin 1284ece92f85SJason Jin START_OF_INSTR(); 1285ece92f85SJason Jin DECODE_PRINTF("BSF\n"); 1286ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1287ece92f85SJason Jin if (mod < 3) { 1288ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 1289ece92f85SJason Jin DECODE_PRINTF(","); 1290ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1291ece92f85SJason Jin u32 srcval, *dstreg; 1292ece92f85SJason Jin 1293ece92f85SJason Jin dstreg = DECODE_RM_LONG_REGISTER(rh); 1294ece92f85SJason Jin TRACE_AND_STEP(); 1295ece92f85SJason Jin srcval = fetch_data_long(srcoffset); 1296ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 1297ece92f85SJason Jin for(*dstreg = 0; *dstreg < 32; (*dstreg)++) 1298ece92f85SJason Jin if ((srcval >> *dstreg) & 1) break; 1299ece92f85SJason Jin } else { 1300ece92f85SJason Jin u16 srcval, *dstreg; 1301ece92f85SJason Jin 1302ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh); 1303ece92f85SJason Jin TRACE_AND_STEP(); 1304ece92f85SJason Jin srcval = fetch_data_word(srcoffset); 1305ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 1306ece92f85SJason Jin for(*dstreg = 0; *dstreg < 16; (*dstreg)++) 1307ece92f85SJason Jin if ((srcval >> *dstreg) & 1) break; 1308ece92f85SJason Jin } 1309ece92f85SJason Jin } else { /* register to register */ 1310ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1311ece92f85SJason Jin u32 *srcreg, *dstreg; 1312ece92f85SJason Jin 1313ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl); 1314ece92f85SJason Jin DECODE_PRINTF(","); 1315ece92f85SJason Jin dstreg = DECODE_RM_LONG_REGISTER(rh); 1316ece92f85SJason Jin TRACE_AND_STEP(); 1317ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF); 1318ece92f85SJason Jin for(*dstreg = 0; *dstreg < 32; (*dstreg)++) 1319ece92f85SJason Jin if ((*srcreg >> *dstreg) & 1) break; 1320ece92f85SJason Jin } else { 1321ece92f85SJason Jin u16 *srcreg, *dstreg; 1322ece92f85SJason Jin 1323ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl); 1324ece92f85SJason Jin DECODE_PRINTF(","); 1325ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh); 1326ece92f85SJason Jin TRACE_AND_STEP(); 1327ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF); 1328ece92f85SJason Jin for(*dstreg = 0; *dstreg < 16; (*dstreg)++) 1329ece92f85SJason Jin if ((*srcreg >> *dstreg) & 1) break; 1330ece92f85SJason Jin } 1331ece92f85SJason Jin } 1332ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1333ece92f85SJason Jin END_OF_INSTR(); 1334ece92f85SJason Jin } 1335ece92f85SJason Jin 1336ece92f85SJason Jin /**************************************************************************** 1337ece92f85SJason Jin REMARKS: 1338ece92f85SJason Jin Handles opcode 0x0f,0xbd 1339ece92f85SJason Jin ****************************************************************************/ 1340ece92f85SJason Jin void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2)) 1341ece92f85SJason Jin { 1342ece92f85SJason Jin int mod, rl, rh; 1343ece92f85SJason Jin uint srcoffset; 1344ece92f85SJason Jin 1345ece92f85SJason Jin START_OF_INSTR(); 1346ece92f85SJason Jin DECODE_PRINTF("BSF\n"); 1347ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1348ece92f85SJason Jin if (mod < 3) { 1349ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 1350ece92f85SJason Jin DECODE_PRINTF(","); 1351ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1352ece92f85SJason Jin u32 srcval, *dstreg; 1353ece92f85SJason Jin 1354ece92f85SJason Jin dstreg = DECODE_RM_LONG_REGISTER(rh); 1355ece92f85SJason Jin TRACE_AND_STEP(); 1356ece92f85SJason Jin srcval = fetch_data_long(srcoffset); 1357ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 1358ece92f85SJason Jin for(*dstreg = 31; *dstreg > 0; (*dstreg)--) 1359ece92f85SJason Jin if ((srcval >> *dstreg) & 1) break; 1360ece92f85SJason Jin } else { 1361ece92f85SJason Jin u16 srcval, *dstreg; 1362ece92f85SJason Jin 1363ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh); 1364ece92f85SJason Jin TRACE_AND_STEP(); 1365ece92f85SJason Jin srcval = fetch_data_word(srcoffset); 1366ece92f85SJason Jin CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 1367ece92f85SJason Jin for(*dstreg = 15; *dstreg > 0; (*dstreg)--) 1368ece92f85SJason Jin if ((srcval >> *dstreg) & 1) break; 1369ece92f85SJason Jin } 1370ece92f85SJason Jin } else { /* register to register */ 1371ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1372ece92f85SJason Jin u32 *srcreg, *dstreg; 1373ece92f85SJason Jin 1374ece92f85SJason Jin srcreg = DECODE_RM_LONG_REGISTER(rl); 1375ece92f85SJason Jin DECODE_PRINTF(","); 1376ece92f85SJason Jin dstreg = DECODE_RM_LONG_REGISTER(rh); 1377ece92f85SJason Jin TRACE_AND_STEP(); 1378ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF); 1379ece92f85SJason Jin for(*dstreg = 31; *dstreg > 0; (*dstreg)--) 1380ece92f85SJason Jin if ((*srcreg >> *dstreg) & 1) break; 1381ece92f85SJason Jin } else { 1382ece92f85SJason Jin u16 *srcreg, *dstreg; 1383ece92f85SJason Jin 1384ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl); 1385ece92f85SJason Jin DECODE_PRINTF(","); 1386ece92f85SJason Jin dstreg = DECODE_RM_WORD_REGISTER(rh); 1387ece92f85SJason Jin TRACE_AND_STEP(); 1388ece92f85SJason Jin CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF); 1389ece92f85SJason Jin for(*dstreg = 15; *dstreg > 0; (*dstreg)--) 1390ece92f85SJason Jin if ((*srcreg >> *dstreg) & 1) break; 1391ece92f85SJason Jin } 1392ece92f85SJason Jin } 1393ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1394ece92f85SJason Jin END_OF_INSTR(); 1395ece92f85SJason Jin } 1396ece92f85SJason Jin 1397ece92f85SJason Jin /**************************************************************************** 1398ece92f85SJason Jin REMARKS: 1399ece92f85SJason Jin Handles opcode 0x0f,0xbe 1400ece92f85SJason Jin ****************************************************************************/ 1401ece92f85SJason Jin void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2)) 1402ece92f85SJason Jin { 1403ece92f85SJason Jin int mod, rl, rh; 1404ece92f85SJason Jin uint srcoffset; 1405ece92f85SJason Jin 1406ece92f85SJason Jin START_OF_INSTR(); 1407ece92f85SJason Jin DECODE_PRINTF("MOVSX\t"); 1408ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1409ece92f85SJason Jin if (mod < 3) { 1410ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1411ece92f85SJason Jin u32 *destreg; 1412ece92f85SJason Jin u32 srcval; 1413ece92f85SJason Jin 1414ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh); 1415ece92f85SJason Jin DECODE_PRINTF(","); 1416ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 1417ece92f85SJason Jin srcval = (s32)((s8)fetch_data_byte(srcoffset)); 1418ece92f85SJason Jin DECODE_PRINTF("\n"); 1419ece92f85SJason Jin TRACE_AND_STEP(); 1420ece92f85SJason Jin *destreg = srcval; 1421ece92f85SJason Jin } else { 1422ece92f85SJason Jin u16 *destreg; 1423ece92f85SJason Jin u16 srcval; 1424ece92f85SJason Jin 1425ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh); 1426ece92f85SJason Jin DECODE_PRINTF(","); 1427ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 1428ece92f85SJason Jin srcval = (s16)((s8)fetch_data_byte(srcoffset)); 1429ece92f85SJason Jin DECODE_PRINTF("\n"); 1430ece92f85SJason Jin TRACE_AND_STEP(); 1431ece92f85SJason Jin *destreg = srcval; 1432ece92f85SJason Jin } 1433ece92f85SJason Jin } else { /* register to register */ 1434ece92f85SJason Jin if (M.x86.mode & SYSMODE_PREFIX_DATA) { 1435ece92f85SJason Jin u32 *destreg; 1436ece92f85SJason Jin u8 *srcreg; 1437ece92f85SJason Jin 1438ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh); 1439ece92f85SJason Jin DECODE_PRINTF(","); 1440ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rl); 1441ece92f85SJason Jin DECODE_PRINTF("\n"); 1442ece92f85SJason Jin TRACE_AND_STEP(); 1443ece92f85SJason Jin *destreg = (s32)((s8)*srcreg); 1444ece92f85SJason Jin } else { 1445ece92f85SJason Jin u16 *destreg; 1446ece92f85SJason Jin u8 *srcreg; 1447ece92f85SJason Jin 1448ece92f85SJason Jin destreg = DECODE_RM_WORD_REGISTER(rh); 1449ece92f85SJason Jin DECODE_PRINTF(","); 1450ece92f85SJason Jin srcreg = DECODE_RM_BYTE_REGISTER(rl); 1451ece92f85SJason Jin DECODE_PRINTF("\n"); 1452ece92f85SJason Jin TRACE_AND_STEP(); 1453ece92f85SJason Jin *destreg = (s16)((s8)*srcreg); 1454ece92f85SJason Jin } 1455ece92f85SJason Jin } 1456ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1457ece92f85SJason Jin END_OF_INSTR(); 1458ece92f85SJason Jin } 1459ece92f85SJason Jin 1460ece92f85SJason Jin /**************************************************************************** 1461ece92f85SJason Jin REMARKS: 1462ece92f85SJason Jin Handles opcode 0x0f,0xbf 1463ece92f85SJason Jin ****************************************************************************/ 1464ece92f85SJason Jin void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2)) 1465ece92f85SJason Jin { 1466ece92f85SJason Jin int mod, rl, rh; 1467ece92f85SJason Jin uint srcoffset; 1468ece92f85SJason Jin u32 *destreg; 1469ece92f85SJason Jin u32 srcval; 1470ece92f85SJason Jin u16 *srcreg; 1471ece92f85SJason Jin 1472ece92f85SJason Jin START_OF_INSTR(); 1473ece92f85SJason Jin DECODE_PRINTF("MOVSX\t"); 1474ece92f85SJason Jin FETCH_DECODE_MODRM(mod, rh, rl); 1475ece92f85SJason Jin if (mod < 3) { 1476ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh); 1477ece92f85SJason Jin DECODE_PRINTF(","); 1478ece92f85SJason Jin srcoffset = decode_rmXX_address(mod, rl); 1479ece92f85SJason Jin srcval = (s32)((s16)fetch_data_word(srcoffset)); 1480ece92f85SJason Jin DECODE_PRINTF("\n"); 1481ece92f85SJason Jin TRACE_AND_STEP(); 1482ece92f85SJason Jin *destreg = srcval; 1483ece92f85SJason Jin } else { /* register to register */ 1484ece92f85SJason Jin destreg = DECODE_RM_LONG_REGISTER(rh); 1485ece92f85SJason Jin DECODE_PRINTF(","); 1486ece92f85SJason Jin srcreg = DECODE_RM_WORD_REGISTER(rl); 1487ece92f85SJason Jin DECODE_PRINTF("\n"); 1488ece92f85SJason Jin TRACE_AND_STEP(); 1489ece92f85SJason Jin *destreg = (s32)((s16)*srcreg); 1490ece92f85SJason Jin } 1491ece92f85SJason Jin DECODE_CLEAR_SEGOVR(); 1492ece92f85SJason Jin END_OF_INSTR(); 1493ece92f85SJason Jin } 1494ece92f85SJason Jin 1495ece92f85SJason Jin /*************************************************************************** 1496ece92f85SJason Jin * Double byte operation code table: 1497ece92f85SJason Jin **************************************************************************/ 149830c6a241SAnatolij Gustschin void (*x86emu_optab2[256])(u8) __attribute__((section(GOT2_TYPE))) = 1499ece92f85SJason Jin { 1500ece92f85SJason Jin /* 0x00 */ x86emuOp2_illegal_op, /* Group F (ring 0 PM) */ 1501ece92f85SJason Jin /* 0x01 */ x86emuOp2_illegal_op, /* Group G (ring 0 PM) */ 1502ece92f85SJason Jin /* 0x02 */ x86emuOp2_illegal_op, /* lar (ring 0 PM) */ 1503ece92f85SJason Jin /* 0x03 */ x86emuOp2_illegal_op, /* lsl (ring 0 PM) */ 1504ece92f85SJason Jin /* 0x04 */ x86emuOp2_illegal_op, 1505ece92f85SJason Jin /* 0x05 */ x86emuOp2_illegal_op, /* loadall (undocumented) */ 1506ece92f85SJason Jin /* 0x06 */ x86emuOp2_illegal_op, /* clts (ring 0 PM) */ 1507ece92f85SJason Jin /* 0x07 */ x86emuOp2_illegal_op, /* loadall (undocumented) */ 1508ece92f85SJason Jin /* 0x08 */ x86emuOp2_illegal_op, /* invd (ring 0 PM) */ 1509ece92f85SJason Jin /* 0x09 */ x86emuOp2_illegal_op, /* wbinvd (ring 0 PM) */ 1510ece92f85SJason Jin /* 0x0a */ x86emuOp2_illegal_op, 1511ece92f85SJason Jin /* 0x0b */ x86emuOp2_illegal_op, 1512ece92f85SJason Jin /* 0x0c */ x86emuOp2_illegal_op, 1513ece92f85SJason Jin /* 0x0d */ x86emuOp2_illegal_op, 1514ece92f85SJason Jin /* 0x0e */ x86emuOp2_illegal_op, 1515ece92f85SJason Jin /* 0x0f */ x86emuOp2_illegal_op, 1516ece92f85SJason Jin 1517ece92f85SJason Jin /* 0x10 */ x86emuOp2_illegal_op, 1518ece92f85SJason Jin /* 0x11 */ x86emuOp2_illegal_op, 1519ece92f85SJason Jin /* 0x12 */ x86emuOp2_illegal_op, 1520ece92f85SJason Jin /* 0x13 */ x86emuOp2_illegal_op, 1521ece92f85SJason Jin /* 0x14 */ x86emuOp2_illegal_op, 1522ece92f85SJason Jin /* 0x15 */ x86emuOp2_illegal_op, 1523ece92f85SJason Jin /* 0x16 */ x86emuOp2_illegal_op, 1524ece92f85SJason Jin /* 0x17 */ x86emuOp2_illegal_op, 1525ece92f85SJason Jin /* 0x18 */ x86emuOp2_illegal_op, 1526ece92f85SJason Jin /* 0x19 */ x86emuOp2_illegal_op, 1527ece92f85SJason Jin /* 0x1a */ x86emuOp2_illegal_op, 1528ece92f85SJason Jin /* 0x1b */ x86emuOp2_illegal_op, 1529ece92f85SJason Jin /* 0x1c */ x86emuOp2_illegal_op, 1530ece92f85SJason Jin /* 0x1d */ x86emuOp2_illegal_op, 1531ece92f85SJason Jin /* 0x1e */ x86emuOp2_illegal_op, 1532ece92f85SJason Jin /* 0x1f */ x86emuOp2_illegal_op, 1533ece92f85SJason Jin 1534ece92f85SJason Jin /* 0x20 */ x86emuOp2_illegal_op, /* mov reg32,creg (ring 0 PM) */ 1535ece92f85SJason Jin /* 0x21 */ x86emuOp2_illegal_op, /* mov reg32,dreg (ring 0 PM) */ 1536ece92f85SJason Jin /* 0x22 */ x86emuOp2_illegal_op, /* mov creg,reg32 (ring 0 PM) */ 1537ece92f85SJason Jin /* 0x23 */ x86emuOp2_illegal_op, /* mov dreg,reg32 (ring 0 PM) */ 1538ece92f85SJason Jin /* 0x24 */ x86emuOp2_illegal_op, /* mov reg32,treg (ring 0 PM) */ 1539ece92f85SJason Jin /* 0x25 */ x86emuOp2_illegal_op, 1540ece92f85SJason Jin /* 0x26 */ x86emuOp2_illegal_op, /* mov treg,reg32 (ring 0 PM) */ 1541ece92f85SJason Jin /* 0x27 */ x86emuOp2_illegal_op, 1542ece92f85SJason Jin /* 0x28 */ x86emuOp2_illegal_op, 1543ece92f85SJason Jin /* 0x29 */ x86emuOp2_illegal_op, 1544ece92f85SJason Jin /* 0x2a */ x86emuOp2_illegal_op, 1545ece92f85SJason Jin /* 0x2b */ x86emuOp2_illegal_op, 1546ece92f85SJason Jin /* 0x2c */ x86emuOp2_illegal_op, 1547ece92f85SJason Jin /* 0x2d */ x86emuOp2_illegal_op, 1548ece92f85SJason Jin /* 0x2e */ x86emuOp2_illegal_op, 1549ece92f85SJason Jin /* 0x2f */ x86emuOp2_illegal_op, 1550ece92f85SJason Jin 1551ece92f85SJason Jin /* 0x30 */ x86emuOp2_illegal_op, 1552ece92f85SJason Jin /* 0x31 */ x86emuOp2_illegal_op, 1553ece92f85SJason Jin /* 0x32 */ x86emuOp2_illegal_op, 1554ece92f85SJason Jin /* 0x33 */ x86emuOp2_illegal_op, 1555ece92f85SJason Jin /* 0x34 */ x86emuOp2_illegal_op, 1556ece92f85SJason Jin /* 0x35 */ x86emuOp2_illegal_op, 1557ece92f85SJason Jin /* 0x36 */ x86emuOp2_illegal_op, 1558ece92f85SJason Jin /* 0x37 */ x86emuOp2_illegal_op, 1559ece92f85SJason Jin /* 0x38 */ x86emuOp2_illegal_op, 1560ece92f85SJason Jin /* 0x39 */ x86emuOp2_illegal_op, 1561ece92f85SJason Jin /* 0x3a */ x86emuOp2_illegal_op, 1562ece92f85SJason Jin /* 0x3b */ x86emuOp2_illegal_op, 1563ece92f85SJason Jin /* 0x3c */ x86emuOp2_illegal_op, 1564ece92f85SJason Jin /* 0x3d */ x86emuOp2_illegal_op, 1565ece92f85SJason Jin /* 0x3e */ x86emuOp2_illegal_op, 1566ece92f85SJason Jin /* 0x3f */ x86emuOp2_illegal_op, 1567ece92f85SJason Jin 1568ece92f85SJason Jin /* 0x40 */ x86emuOp2_illegal_op, 1569ece92f85SJason Jin /* 0x41 */ x86emuOp2_illegal_op, 1570ece92f85SJason Jin /* 0x42 */ x86emuOp2_illegal_op, 1571ece92f85SJason Jin /* 0x43 */ x86emuOp2_illegal_op, 1572ece92f85SJason Jin /* 0x44 */ x86emuOp2_illegal_op, 1573ece92f85SJason Jin /* 0x45 */ x86emuOp2_illegal_op, 1574ece92f85SJason Jin /* 0x46 */ x86emuOp2_illegal_op, 1575ece92f85SJason Jin /* 0x47 */ x86emuOp2_illegal_op, 1576ece92f85SJason Jin /* 0x48 */ x86emuOp2_illegal_op, 1577ece92f85SJason Jin /* 0x49 */ x86emuOp2_illegal_op, 1578ece92f85SJason Jin /* 0x4a */ x86emuOp2_illegal_op, 1579ece92f85SJason Jin /* 0x4b */ x86emuOp2_illegal_op, 1580ece92f85SJason Jin /* 0x4c */ x86emuOp2_illegal_op, 1581ece92f85SJason Jin /* 0x4d */ x86emuOp2_illegal_op, 1582ece92f85SJason Jin /* 0x4e */ x86emuOp2_illegal_op, 1583ece92f85SJason Jin /* 0x4f */ x86emuOp2_illegal_op, 1584ece92f85SJason Jin 1585ece92f85SJason Jin /* 0x50 */ x86emuOp2_illegal_op, 1586ece92f85SJason Jin /* 0x51 */ x86emuOp2_illegal_op, 1587ece92f85SJason Jin /* 0x52 */ x86emuOp2_illegal_op, 1588ece92f85SJason Jin /* 0x53 */ x86emuOp2_illegal_op, 1589ece92f85SJason Jin /* 0x54 */ x86emuOp2_illegal_op, 1590ece92f85SJason Jin /* 0x55 */ x86emuOp2_illegal_op, 1591ece92f85SJason Jin /* 0x56 */ x86emuOp2_illegal_op, 1592ece92f85SJason Jin /* 0x57 */ x86emuOp2_illegal_op, 1593ece92f85SJason Jin /* 0x58 */ x86emuOp2_illegal_op, 1594ece92f85SJason Jin /* 0x59 */ x86emuOp2_illegal_op, 1595ece92f85SJason Jin /* 0x5a */ x86emuOp2_illegal_op, 1596ece92f85SJason Jin /* 0x5b */ x86emuOp2_illegal_op, 1597ece92f85SJason Jin /* 0x5c */ x86emuOp2_illegal_op, 1598ece92f85SJason Jin /* 0x5d */ x86emuOp2_illegal_op, 1599ece92f85SJason Jin /* 0x5e */ x86emuOp2_illegal_op, 1600ece92f85SJason Jin /* 0x5f */ x86emuOp2_illegal_op, 1601ece92f85SJason Jin 1602ece92f85SJason Jin /* 0x60 */ x86emuOp2_illegal_op, 1603ece92f85SJason Jin /* 0x61 */ x86emuOp2_illegal_op, 1604ece92f85SJason Jin /* 0x62 */ x86emuOp2_illegal_op, 1605ece92f85SJason Jin /* 0x63 */ x86emuOp2_illegal_op, 1606ece92f85SJason Jin /* 0x64 */ x86emuOp2_illegal_op, 1607ece92f85SJason Jin /* 0x65 */ x86emuOp2_illegal_op, 1608ece92f85SJason Jin /* 0x66 */ x86emuOp2_illegal_op, 1609ece92f85SJason Jin /* 0x67 */ x86emuOp2_illegal_op, 1610ece92f85SJason Jin /* 0x68 */ x86emuOp2_illegal_op, 1611ece92f85SJason Jin /* 0x69 */ x86emuOp2_illegal_op, 1612ece92f85SJason Jin /* 0x6a */ x86emuOp2_illegal_op, 1613ece92f85SJason Jin /* 0x6b */ x86emuOp2_illegal_op, 1614ece92f85SJason Jin /* 0x6c */ x86emuOp2_illegal_op, 1615ece92f85SJason Jin /* 0x6d */ x86emuOp2_illegal_op, 1616ece92f85SJason Jin /* 0x6e */ x86emuOp2_illegal_op, 1617ece92f85SJason Jin /* 0x6f */ x86emuOp2_illegal_op, 1618ece92f85SJason Jin 1619ece92f85SJason Jin /* 0x70 */ x86emuOp2_illegal_op, 1620ece92f85SJason Jin /* 0x71 */ x86emuOp2_illegal_op, 1621ece92f85SJason Jin /* 0x72 */ x86emuOp2_illegal_op, 1622ece92f85SJason Jin /* 0x73 */ x86emuOp2_illegal_op, 1623ece92f85SJason Jin /* 0x74 */ x86emuOp2_illegal_op, 1624ece92f85SJason Jin /* 0x75 */ x86emuOp2_illegal_op, 1625ece92f85SJason Jin /* 0x76 */ x86emuOp2_illegal_op, 1626ece92f85SJason Jin /* 0x77 */ x86emuOp2_illegal_op, 1627ece92f85SJason Jin /* 0x78 */ x86emuOp2_illegal_op, 1628ece92f85SJason Jin /* 0x79 */ x86emuOp2_illegal_op, 1629ece92f85SJason Jin /* 0x7a */ x86emuOp2_illegal_op, 1630ece92f85SJason Jin /* 0x7b */ x86emuOp2_illegal_op, 1631ece92f85SJason Jin /* 0x7c */ x86emuOp2_illegal_op, 1632ece92f85SJason Jin /* 0x7d */ x86emuOp2_illegal_op, 1633ece92f85SJason Jin /* 0x7e */ x86emuOp2_illegal_op, 1634ece92f85SJason Jin /* 0x7f */ x86emuOp2_illegal_op, 1635ece92f85SJason Jin 1636ece92f85SJason Jin /* 0x80 */ x86emuOp2_long_jump, 1637ece92f85SJason Jin /* 0x81 */ x86emuOp2_long_jump, 1638ece92f85SJason Jin /* 0x82 */ x86emuOp2_long_jump, 1639ece92f85SJason Jin /* 0x83 */ x86emuOp2_long_jump, 1640ece92f85SJason Jin /* 0x84 */ x86emuOp2_long_jump, 1641ece92f85SJason Jin /* 0x85 */ x86emuOp2_long_jump, 1642ece92f85SJason Jin /* 0x86 */ x86emuOp2_long_jump, 1643ece92f85SJason Jin /* 0x87 */ x86emuOp2_long_jump, 1644ece92f85SJason Jin /* 0x88 */ x86emuOp2_long_jump, 1645ece92f85SJason Jin /* 0x89 */ x86emuOp2_long_jump, 1646ece92f85SJason Jin /* 0x8a */ x86emuOp2_long_jump, 1647ece92f85SJason Jin /* 0x8b */ x86emuOp2_long_jump, 1648ece92f85SJason Jin /* 0x8c */ x86emuOp2_long_jump, 1649ece92f85SJason Jin /* 0x8d */ x86emuOp2_long_jump, 1650ece92f85SJason Jin /* 0x8e */ x86emuOp2_long_jump, 1651ece92f85SJason Jin /* 0x8f */ x86emuOp2_long_jump, 1652ece92f85SJason Jin 1653ece92f85SJason Jin /* 0x90 */ x86emuOp2_set_byte, 1654ece92f85SJason Jin /* 0x91 */ x86emuOp2_set_byte, 1655ece92f85SJason Jin /* 0x92 */ x86emuOp2_set_byte, 1656ece92f85SJason Jin /* 0x93 */ x86emuOp2_set_byte, 1657ece92f85SJason Jin /* 0x94 */ x86emuOp2_set_byte, 1658ece92f85SJason Jin /* 0x95 */ x86emuOp2_set_byte, 1659ece92f85SJason Jin /* 0x96 */ x86emuOp2_set_byte, 1660ece92f85SJason Jin /* 0x97 */ x86emuOp2_set_byte, 1661ece92f85SJason Jin /* 0x98 */ x86emuOp2_set_byte, 1662ece92f85SJason Jin /* 0x99 */ x86emuOp2_set_byte, 1663ece92f85SJason Jin /* 0x9a */ x86emuOp2_set_byte, 1664ece92f85SJason Jin /* 0x9b */ x86emuOp2_set_byte, 1665ece92f85SJason Jin /* 0x9c */ x86emuOp2_set_byte, 1666ece92f85SJason Jin /* 0x9d */ x86emuOp2_set_byte, 1667ece92f85SJason Jin /* 0x9e */ x86emuOp2_set_byte, 1668ece92f85SJason Jin /* 0x9f */ x86emuOp2_set_byte, 1669ece92f85SJason Jin 1670ece92f85SJason Jin /* 0xa0 */ x86emuOp2_push_FS, 1671ece92f85SJason Jin /* 0xa1 */ x86emuOp2_pop_FS, 1672ece92f85SJason Jin /* 0xa2 */ x86emuOp2_illegal_op, 1673ece92f85SJason Jin /* 0xa3 */ x86emuOp2_bt_R, 1674ece92f85SJason Jin /* 0xa4 */ x86emuOp2_shld_IMM, 1675ece92f85SJason Jin /* 0xa5 */ x86emuOp2_shld_CL, 1676ece92f85SJason Jin /* 0xa6 */ x86emuOp2_illegal_op, 1677ece92f85SJason Jin /* 0xa7 */ x86emuOp2_illegal_op, 1678ece92f85SJason Jin /* 0xa8 */ x86emuOp2_push_GS, 1679ece92f85SJason Jin /* 0xa9 */ x86emuOp2_pop_GS, 1680ece92f85SJason Jin /* 0xaa */ x86emuOp2_illegal_op, 1681ece92f85SJason Jin /* 0xab */ x86emuOp2_bt_R, 1682ece92f85SJason Jin /* 0xac */ x86emuOp2_shrd_IMM, 1683ece92f85SJason Jin /* 0xad */ x86emuOp2_shrd_CL, 1684ece92f85SJason Jin /* 0xae */ x86emuOp2_illegal_op, 1685ece92f85SJason Jin /* 0xaf */ x86emuOp2_imul_R_RM, 1686ece92f85SJason Jin 1687ece92f85SJason Jin /* 0xb0 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */ 1688ece92f85SJason Jin /* 0xb1 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */ 1689ece92f85SJason Jin /* 0xb2 */ x86emuOp2_lss_R_IMM, 1690ece92f85SJason Jin /* 0xb3 */ x86emuOp2_btr_R, 1691ece92f85SJason Jin /* 0xb4 */ x86emuOp2_lfs_R_IMM, 1692ece92f85SJason Jin /* 0xb5 */ x86emuOp2_lgs_R_IMM, 1693ece92f85SJason Jin /* 0xb6 */ x86emuOp2_movzx_byte_R_RM, 1694ece92f85SJason Jin /* 0xb7 */ x86emuOp2_movzx_word_R_RM, 1695ece92f85SJason Jin /* 0xb8 */ x86emuOp2_illegal_op, 1696ece92f85SJason Jin /* 0xb9 */ x86emuOp2_illegal_op, 1697ece92f85SJason Jin /* 0xba */ x86emuOp2_btX_I, 1698ece92f85SJason Jin /* 0xbb */ x86emuOp2_btc_R, 1699ece92f85SJason Jin /* 0xbc */ x86emuOp2_bsf, 1700ece92f85SJason Jin /* 0xbd */ x86emuOp2_bsr, 1701ece92f85SJason Jin /* 0xbe */ x86emuOp2_movsx_byte_R_RM, 1702ece92f85SJason Jin /* 0xbf */ x86emuOp2_movsx_word_R_RM, 1703ece92f85SJason Jin 1704ece92f85SJason Jin /* 0xc0 */ x86emuOp2_illegal_op, /* TODO: xadd */ 1705ece92f85SJason Jin /* 0xc1 */ x86emuOp2_illegal_op, /* TODO: xadd */ 1706ece92f85SJason Jin /* 0xc2 */ x86emuOp2_illegal_op, 1707ece92f85SJason Jin /* 0xc3 */ x86emuOp2_illegal_op, 1708ece92f85SJason Jin /* 0xc4 */ x86emuOp2_illegal_op, 1709ece92f85SJason Jin /* 0xc5 */ x86emuOp2_illegal_op, 1710ece92f85SJason Jin /* 0xc6 */ x86emuOp2_illegal_op, 1711ece92f85SJason Jin /* 0xc7 */ x86emuOp2_illegal_op, 1712ece92f85SJason Jin /* 0xc8 */ x86emuOp2_illegal_op, /* TODO: bswap */ 1713ece92f85SJason Jin /* 0xc9 */ x86emuOp2_illegal_op, /* TODO: bswap */ 1714ece92f85SJason Jin /* 0xca */ x86emuOp2_illegal_op, /* TODO: bswap */ 1715ece92f85SJason Jin /* 0xcb */ x86emuOp2_illegal_op, /* TODO: bswap */ 1716ece92f85SJason Jin /* 0xcc */ x86emuOp2_illegal_op, /* TODO: bswap */ 1717ece92f85SJason Jin /* 0xcd */ x86emuOp2_illegal_op, /* TODO: bswap */ 1718ece92f85SJason Jin /* 0xce */ x86emuOp2_illegal_op, /* TODO: bswap */ 1719ece92f85SJason Jin /* 0xcf */ x86emuOp2_illegal_op, /* TODO: bswap */ 1720ece92f85SJason Jin 1721ece92f85SJason Jin /* 0xd0 */ x86emuOp2_illegal_op, 1722ece92f85SJason Jin /* 0xd1 */ x86emuOp2_illegal_op, 1723ece92f85SJason Jin /* 0xd2 */ x86emuOp2_illegal_op, 1724ece92f85SJason Jin /* 0xd3 */ x86emuOp2_illegal_op, 1725ece92f85SJason Jin /* 0xd4 */ x86emuOp2_illegal_op, 1726ece92f85SJason Jin /* 0xd5 */ x86emuOp2_illegal_op, 1727ece92f85SJason Jin /* 0xd6 */ x86emuOp2_illegal_op, 1728ece92f85SJason Jin /* 0xd7 */ x86emuOp2_illegal_op, 1729ece92f85SJason Jin /* 0xd8 */ x86emuOp2_illegal_op, 1730ece92f85SJason Jin /* 0xd9 */ x86emuOp2_illegal_op, 1731ece92f85SJason Jin /* 0xda */ x86emuOp2_illegal_op, 1732ece92f85SJason Jin /* 0xdb */ x86emuOp2_illegal_op, 1733ece92f85SJason Jin /* 0xdc */ x86emuOp2_illegal_op, 1734ece92f85SJason Jin /* 0xdd */ x86emuOp2_illegal_op, 1735ece92f85SJason Jin /* 0xde */ x86emuOp2_illegal_op, 1736ece92f85SJason Jin /* 0xdf */ x86emuOp2_illegal_op, 1737ece92f85SJason Jin 1738ece92f85SJason Jin /* 0xe0 */ x86emuOp2_illegal_op, 1739ece92f85SJason Jin /* 0xe1 */ x86emuOp2_illegal_op, 1740ece92f85SJason Jin /* 0xe2 */ x86emuOp2_illegal_op, 1741ece92f85SJason Jin /* 0xe3 */ x86emuOp2_illegal_op, 1742ece92f85SJason Jin /* 0xe4 */ x86emuOp2_illegal_op, 1743ece92f85SJason Jin /* 0xe5 */ x86emuOp2_illegal_op, 1744ece92f85SJason Jin /* 0xe6 */ x86emuOp2_illegal_op, 1745ece92f85SJason Jin /* 0xe7 */ x86emuOp2_illegal_op, 1746ece92f85SJason Jin /* 0xe8 */ x86emuOp2_illegal_op, 1747ece92f85SJason Jin /* 0xe9 */ x86emuOp2_illegal_op, 1748ece92f85SJason Jin /* 0xea */ x86emuOp2_illegal_op, 1749ece92f85SJason Jin /* 0xeb */ x86emuOp2_illegal_op, 1750ece92f85SJason Jin /* 0xec */ x86emuOp2_illegal_op, 1751ece92f85SJason Jin /* 0xed */ x86emuOp2_illegal_op, 1752ece92f85SJason Jin /* 0xee */ x86emuOp2_illegal_op, 1753ece92f85SJason Jin /* 0xef */ x86emuOp2_illegal_op, 1754ece92f85SJason Jin 1755ece92f85SJason Jin /* 0xf0 */ x86emuOp2_illegal_op, 1756ece92f85SJason Jin /* 0xf1 */ x86emuOp2_illegal_op, 1757ece92f85SJason Jin /* 0xf2 */ x86emuOp2_illegal_op, 1758ece92f85SJason Jin /* 0xf3 */ x86emuOp2_illegal_op, 1759ece92f85SJason Jin /* 0xf4 */ x86emuOp2_illegal_op, 1760ece92f85SJason Jin /* 0xf5 */ x86emuOp2_illegal_op, 1761ece92f85SJason Jin /* 0xf6 */ x86emuOp2_illegal_op, 1762ece92f85SJason Jin /* 0xf7 */ x86emuOp2_illegal_op, 1763ece92f85SJason Jin /* 0xf8 */ x86emuOp2_illegal_op, 1764ece92f85SJason Jin /* 0xf9 */ x86emuOp2_illegal_op, 1765ece92f85SJason Jin /* 0xfa */ x86emuOp2_illegal_op, 1766ece92f85SJason Jin /* 0xfb */ x86emuOp2_illegal_op, 1767ece92f85SJason Jin /* 0xfc */ x86emuOp2_illegal_op, 1768ece92f85SJason Jin /* 0xfd */ x86emuOp2_illegal_op, 1769ece92f85SJason Jin /* 0xfe */ x86emuOp2_illegal_op, 1770ece92f85SJason Jin /* 0xff */ x86emuOp2_illegal_op, 1771ece92f85SJason Jin }; 1772