?? ops2.c
字號(hào):
/****************************************************************************** Realmode X86 Emulator Library** Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.* Jason Jin <Jason.jin@freescale.com>** Copyright (C) 1991-2004 SciTech Software, Inc.* Copyright (C) David Mosberger-Tang* Copyright (C) 1999 Egbert Eich** ========================================================================** Permission to use, copy, modify, distribute, and sell this software and* its documentation for any purpose is hereby granted without fee,* provided that the above copyright notice appear in all copies and that* both that copyright notice and this permission notice appear in* supporting documentation, and that the name of the authors not be used* in advertising or publicity pertaining to distribution of the software* without specific, written prior permission. The authors makes no* representations about the suitability of this software for any purpose.* It is provided "as is" without express or implied warranty.** THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR* PERFORMANCE OF THIS SOFTWARE.** ========================================================================** Language: ANSI C* Environment: Any* Developer: Kendall Bennett** Description: This file includes subroutines to implement the decoding* and emulation of all the x86 extended two-byte processor* instructions.** Jason port this file to u-boot. Put the function pointer into* got2 sector.*****************************************************************************/#include <common.h>#include "x86emu/x86emui.h"/*----------------------------- Implementation ----------------------------*//****************************************************************************PARAMETERS:op1 - Instruction op codeREMARKS:Handles illegal opcodes.****************************************************************************/void x86emuOp2_illegal_op( u8 op2){ START_OF_INSTR(); DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n"); TRACE_REGS(); printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n", M.x86.R_CS, M.x86.R_IP-2,op2); HALT_SYS(); END_OF_INSTR();}#define xorl(a,b) ((a) && !(b)) || (!(a) && (b))/****************************************************************************REMARKS:Handles opcode 0x0f,0x80-0x8F****************************************************************************/int x86emu_check_jump_condition(u8 op){ switch (op) { case 0x0: DECODE_PRINTF("JO\t"); return ACCESS_FLAG(F_OF); case 0x1: DECODE_PRINTF("JNO\t"); return !ACCESS_FLAG(F_OF); break; case 0x2: DECODE_PRINTF("JB\t"); return ACCESS_FLAG(F_CF); break; case 0x3: DECODE_PRINTF("JNB\t"); return !ACCESS_FLAG(F_CF); break; case 0x4: DECODE_PRINTF("JZ\t"); return ACCESS_FLAG(F_ZF); break; case 0x5: DECODE_PRINTF("JNZ\t"); return !ACCESS_FLAG(F_ZF); break; case 0x6: DECODE_PRINTF("JBE\t"); return ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF); break; case 0x7: DECODE_PRINTF("JNBE\t"); return !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)); break; case 0x8: DECODE_PRINTF("JS\t"); return ACCESS_FLAG(F_SF); break; case 0x9: DECODE_PRINTF("JNS\t"); return !ACCESS_FLAG(F_SF); break; case 0xa: DECODE_PRINTF("JP\t"); return ACCESS_FLAG(F_PF); break; case 0xb: DECODE_PRINTF("JNP\t"); return !ACCESS_FLAG(F_PF); break; case 0xc: DECODE_PRINTF("JL\t"); return xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); break; case 0xd: DECODE_PRINTF("JNL\t"); return !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); break; case 0xe: DECODE_PRINTF("JLE\t"); return (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || ACCESS_FLAG(F_ZF)); break; default: DECODE_PRINTF("JNLE\t"); return !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || ACCESS_FLAG(F_ZF)); }}void x86emuOp2_long_jump(u8 op2){ s32 target; int cond; /* conditional jump to word offset. */ START_OF_INSTR(); cond = x86emu_check_jump_condition(op2 & 0xF); target = (s16) fetch_word_imm(); target += (s16) M.x86.R_IP; DECODE_PRINTF2("%04x\n", target); TRACE_AND_STEP(); if (cond) M.x86.R_IP = (u16)target; DECODE_CLEAR_SEGOVR(); END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x0f,0x90-0x9F****************************************************************************/void x86emuOp2_set_byte(u8 op2){ int mod, rl, rh; uint destoffset; u8 *destreg; char *name = 0; int cond = 0; START_OF_INSTR(); switch (op2) { case 0x90: name = "SETO\t"; cond = ACCESS_FLAG(F_OF); break; case 0x91: name = "SETNO\t"; cond = !ACCESS_FLAG(F_OF); break; case 0x92: name = "SETB\t"; cond = ACCESS_FLAG(F_CF); break; case 0x93: name = "SETNB\t"; cond = !ACCESS_FLAG(F_CF); break; case 0x94: name = "SETZ\t"; cond = ACCESS_FLAG(F_ZF); break; case 0x95: name = "SETNZ\t"; cond = !ACCESS_FLAG(F_ZF); break; case 0x96: name = "SETBE\t"; cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF); break; case 0x97: name = "SETNBE\t"; cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)); break; case 0x98: name = "SETS\t"; cond = ACCESS_FLAG(F_SF); break; case 0x99: name = "SETNS\t"; cond = !ACCESS_FLAG(F_SF); break; case 0x9a: name = "SETP\t"; cond = ACCESS_FLAG(F_PF); break; case 0x9b: name = "SETNP\t"; cond = !ACCESS_FLAG(F_PF); break; case 0x9c: name = "SETL\t"; cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); break; case 0x9d: name = "SETNL\t"; cond = !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); break; case 0x9e: name = "SETLE\t"; cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || ACCESS_FLAG(F_ZF)); break; case 0x9f: name = "SETNLE\t"; cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || ACCESS_FLAG(F_ZF)); break; } DECODE_PRINTF(name); FETCH_DECODE_MODRM(mod, rh, rl); if (mod < 3) { destoffset = decode_rmXX_address(mod, rl); TRACE_AND_STEP(); store_data_byte(destoffset, cond ? 0x01 : 0x00); } else { /* register to register */ destreg = DECODE_RM_BYTE_REGISTER(rl); TRACE_AND_STEP(); *destreg = cond ? 0x01 : 0x00; } DECODE_CLEAR_SEGOVR(); END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x0f,0xa0****************************************************************************/void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2)){ START_OF_INSTR(); DECODE_PRINTF("PUSH\tFS\n"); TRACE_AND_STEP(); push_word(M.x86.R_FS); DECODE_CLEAR_SEGOVR(); END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x0f,0xa1****************************************************************************/void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2)){ START_OF_INSTR(); DECODE_PRINTF("POP\tFS\n"); TRACE_AND_STEP(); M.x86.R_FS = pop_word(); DECODE_CLEAR_SEGOVR(); END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x0f,0xa3****************************************************************************/void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2)){ int mod, rl, rh; uint srcoffset; int bit,disp; START_OF_INSTR(); DECODE_PRINTF("BT\t"); FETCH_DECODE_MODRM(mod, rh, rl); if (mod < 3) { srcoffset = decode_rmXX_address(mod, rl); if (M.x86.mode & SYSMODE_PREFIX_DATA) { u32 srcval; u32 *shiftreg; DECODE_PRINTF(","); shiftreg = DECODE_RM_LONG_REGISTER(rh); TRACE_AND_STEP(); bit = *shiftreg & 0x1F; disp = (s16)*shiftreg >> 5; srcval = fetch_data_long(srcoffset+disp); CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF); } else { u16 srcval; u16 *shiftreg; DECODE_PRINTF(","); shiftreg = DECODE_RM_WORD_REGISTER(rh); TRACE_AND_STEP(); bit = *shiftreg & 0xF; disp = (s16)*shiftreg >> 4; srcval = fetch_data_word(srcoffset+disp); CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF); } } else { /* register to register */ if (M.x86.mode & SYSMODE_PREFIX_DATA) { u32 *srcreg,*shiftreg; srcreg = DECODE_RM_LONG_REGISTER(rl); DECODE_PRINTF(","); shiftreg = DECODE_RM_LONG_REGISTER(rh); TRACE_AND_STEP(); bit = *shiftreg & 0x1F; CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF); } else { u16 *srcreg,*shiftreg; srcreg = DECODE_RM_WORD_REGISTER(rl); DECODE_PRINTF(","); shiftreg = DECODE_RM_WORD_REGISTER(rh); TRACE_AND_STEP(); bit = *shiftreg & 0xF; CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF); } } DECODE_CLEAR_SEGOVR(); END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x0f,0xa4****************************************************************************/void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2)){ int mod, rl, rh; uint destoffset; u8 shift; START_OF_INSTR(); DECODE_PRINTF("SHLD\t"); FETCH_DECODE_MODRM(mod, rh, rl); if (mod < 3) { destoffset = decode_rmXX_address(mod, rl); if (M.x86.mode & SYSMODE_PREFIX_DATA) { u32 destval; u32 *shiftreg; DECODE_PRINTF(","); shiftreg = DECODE_RM_LONG_REGISTER(rh); DECODE_PRINTF(","); shift = fetch_byte_imm(); DECODE_PRINTF2("%d\n", shift); TRACE_AND_STEP(); destval = fetch_data_long(destoffset); destval = shld_long(destval,*shiftreg,shift); store_data_long(destoffset, destval); } else { u16 destval; u16 *shiftreg; DECODE_PRINTF(","); shiftreg = DECODE_RM_WORD_REGISTER(rh); DECODE_PRINTF(","); shift = fetch_byte_imm(); DECODE_PRINTF2("%d\n", shift); TRACE_AND_STEP(); destval = fetch_data_word(destoffset); destval = shld_word(destval,*shiftreg,shift); store_data_word(destoffset, destval); } } else { /* register to register */ if (M.x86.mode & SYSMODE_PREFIX_DATA) { u32 *destreg,*shiftreg; destreg = DECODE_RM_LONG_REGISTER(rl); DECODE_PRINTF(","); shiftreg = DECODE_RM_LONG_REGISTER(rh); DECODE_PRINTF(","); shift = fetch_byte_imm(); DECODE_PRINTF2("%d\n", shift); TRACE_AND_STEP(); *destreg = shld_long(*destreg,*shiftreg,shift); } else { u16 *destreg,*shiftreg; destreg = DECODE_RM_WORD_REGISTER(rl); DECODE_PRINTF(","); shiftreg = DECODE_RM_WORD_REGISTER(rh); DECODE_PRINTF(","); shift = fetch_byte_imm(); DECODE_PRINTF2("%d\n", shift); TRACE_AND_STEP(); *destreg = shld_word(*destreg,*shiftreg,shift); } } DECODE_CLEAR_SEGOVR(); END_OF_INSTR();}/****************************************************************************REMARKS:Handles opcode 0x0f,0xa5****************************************************************************/void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2)){ int mod, rl, rh; uint destoffset; START_OF_INSTR(); DECODE_PRINTF("SHLD\t"); FETCH_DECODE_MODRM(mod, rh, rl); if (mod < 3) { destoffset = decode_rmXX_address(mod, rl); if (M.x86.mode & SYSMODE_PREFIX_DATA) { u32 destval; u32 *shiftreg; DECODE_PRINTF(","); shiftreg = DECODE_RM_LONG_REGISTER(rh); DECODE_PRINTF(",CL\n");
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -