⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 op.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  i386 micro operations *  *  Copyright (c) 2003 Fabrice Bellard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#define ASM_SOFTMMU#include "exec.h"/* n must be a constant to be efficient */static inline target_long lshift(target_long x, int n){    if (n >= 0)        return x << n;    else        return x >> (-n);}/* we define the various pieces of code used by the JIT */#define REG EAX#define REGNAME _EAX#include "opreg_template.h"#undef REG#undef REGNAME#define REG ECX#define REGNAME _ECX#include "opreg_template.h"#undef REG#undef REGNAME#define REG EDX#define REGNAME _EDX#include "opreg_template.h"#undef REG#undef REGNAME#define REG EBX#define REGNAME _EBX#include "opreg_template.h"#undef REG#undef REGNAME#define REG ESP#define REGNAME _ESP#include "opreg_template.h"#undef REG#undef REGNAME#define REG EBP#define REGNAME _EBP#include "opreg_template.h"#undef REG#undef REGNAME#define REG ESI#define REGNAME _ESI#include "opreg_template.h"#undef REG#undef REGNAME#define REG EDI#define REGNAME _EDI#include "opreg_template.h"#undef REG#undef REGNAME#ifdef TARGET_X86_64#define REG (env->regs[8])#define REGNAME _R8#include "opreg_template.h"#undef REG#undef REGNAME#define REG (env->regs[9])#define REGNAME _R9#include "opreg_template.h"#undef REG#undef REGNAME#define REG (env->regs[10])#define REGNAME _R10#include "opreg_template.h"#undef REG#undef REGNAME#define REG (env->regs[11])#define REGNAME _R11#include "opreg_template.h"#undef REG#undef REGNAME#define REG (env->regs[12])#define REGNAME _R12#include "opreg_template.h"#undef REG#undef REGNAME#define REG (env->regs[13])#define REGNAME _R13#include "opreg_template.h"#undef REG#undef REGNAME#define REG (env->regs[14])#define REGNAME _R14#include "opreg_template.h"#undef REG#undef REGNAME#define REG (env->regs[15])#define REGNAME _R15#include "opreg_template.h"#undef REG#undef REGNAME#endif/* operations with flags *//* update flags with T0 and T1 (add/sub case) */void OPPROTO op_update2_cc(void){    CC_SRC = T1;    CC_DST = T0;}/* update flags with T0 (logic operation case) */void OPPROTO op_update1_cc(void){    CC_DST = T0;}void OPPROTO op_update_neg_cc(void){    CC_SRC = -T0;    CC_DST = T0;}void OPPROTO op_cmpl_T0_T1_cc(void){    CC_SRC = T1;    CC_DST = T0 - T1;}void OPPROTO op_update_inc_cc(void){    CC_SRC = cc_table[CC_OP].compute_c();    CC_DST = T0;}void OPPROTO op_testl_T0_T1_cc(void){    CC_DST = T0 & T1;}/* operations without flags */void OPPROTO op_addl_T0_T1(void){    T0 += T1;}void OPPROTO op_orl_T0_T1(void){    T0 |= T1;}void OPPROTO op_andl_T0_T1(void){    T0 &= T1;}void OPPROTO op_subl_T0_T1(void){    T0 -= T1;}void OPPROTO op_xorl_T0_T1(void){    T0 ^= T1;}void OPPROTO op_negl_T0(void){    T0 = -T0;}void OPPROTO op_incl_T0(void){    T0++;}void OPPROTO op_decl_T0(void){    T0--;}void OPPROTO op_notl_T0(void){    T0 = ~T0;}void OPPROTO op_bswapl_T0(void){    T0 = bswap32(T0);}#ifdef TARGET_X86_64void OPPROTO op_bswapq_T0(void){    helper_bswapq_T0();}#endif/* multiply/divide *//* XXX: add eflags optimizations *//* XXX: add non P4 style flags */void OPPROTO op_mulb_AL_T0(void){    unsigned int res;    res = (uint8_t)EAX * (uint8_t)T0;    EAX = (EAX & ~0xffff) | res;    CC_DST = res;    CC_SRC = (res & 0xff00);}void OPPROTO op_imulb_AL_T0(void){    int res;    res = (int8_t)EAX * (int8_t)T0;    EAX = (EAX & ~0xffff) | (res & 0xffff);    CC_DST = res;    CC_SRC = (res != (int8_t)res);}void OPPROTO op_mulw_AX_T0(void){    unsigned int res;    res = (uint16_t)EAX * (uint16_t)T0;    EAX = (EAX & ~0xffff) | (res & 0xffff);    EDX = (EDX & ~0xffff) | ((res >> 16) & 0xffff);    CC_DST = res;    CC_SRC = res >> 16;}void OPPROTO op_imulw_AX_T0(void){    int res;    res = (int16_t)EAX * (int16_t)T0;    EAX = (EAX & ~0xffff) | (res & 0xffff);    EDX = (EDX & ~0xffff) | ((res >> 16) & 0xffff);    CC_DST = res;    CC_SRC = (res != (int16_t)res);}void OPPROTO op_mull_EAX_T0(void){    uint64_t res;    res = (uint64_t)((uint32_t)EAX) * (uint64_t)((uint32_t)T0);    EAX = (uint32_t)res;    EDX = (uint32_t)(res >> 32);    CC_DST = (uint32_t)res;    CC_SRC = (uint32_t)(res >> 32);}void OPPROTO op_imull_EAX_T0(void){    int64_t res;    res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T0);    EAX = (uint32_t)(res);    EDX = (uint32_t)(res >> 32);    CC_DST = res;    CC_SRC = (res != (int32_t)res);}void OPPROTO op_imulw_T0_T1(void){    int res;    res = (int16_t)T0 * (int16_t)T1;    T0 = res;    CC_DST = res;    CC_SRC = (res != (int16_t)res);}void OPPROTO op_imull_T0_T1(void){    int64_t res;    res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);    T0 = res;    CC_DST = res;    CC_SRC = (res != (int32_t)res);}#ifdef TARGET_X86_64void OPPROTO op_mulq_EAX_T0(void){    helper_mulq_EAX_T0();}void OPPROTO op_imulq_EAX_T0(void){    helper_imulq_EAX_T0();}void OPPROTO op_imulq_T0_T1(void){    helper_imulq_T0_T1();}#endif/* division, flags are undefined */void OPPROTO op_divb_AL_T0(void){    unsigned int num, den, q, r;    num = (EAX & 0xffff);    den = (T0 & 0xff);    if (den == 0) {        raise_exception(EXCP00_DIVZ);    }    q = (num / den);    if (q > 0xff)        raise_exception(EXCP00_DIVZ);    q &= 0xff;    r = (num % den) & 0xff;    EAX = (EAX & ~0xffff) | (r << 8) | q;}void OPPROTO op_idivb_AL_T0(void){    int num, den, q, r;    num = (int16_t)EAX;    den = (int8_t)T0;    if (den == 0) {        raise_exception(EXCP00_DIVZ);    }    q = (num / den);    if (q != (int8_t)q)        raise_exception(EXCP00_DIVZ);    q &= 0xff;    r = (num % den) & 0xff;    EAX = (EAX & ~0xffff) | (r << 8) | q;}void OPPROTO op_divw_AX_T0(void){    unsigned int num, den, q, r;    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);    den = (T0 & 0xffff);    if (den == 0) {        raise_exception(EXCP00_DIVZ);    }    q = (num / den);    if (q > 0xffff)        raise_exception(EXCP00_DIVZ);    q &= 0xffff;    r = (num % den) & 0xffff;    EAX = (EAX & ~0xffff) | q;    EDX = (EDX & ~0xffff) | r;}void OPPROTO op_idivw_AX_T0(void){    int num, den, q, r;    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);    den = (int16_t)T0;    if (den == 0) {        raise_exception(EXCP00_DIVZ);    }    q = (num / den);    if (q != (int16_t)q)        raise_exception(EXCP00_DIVZ);    q &= 0xffff;    r = (num % den) & 0xffff;    EAX = (EAX & ~0xffff) | q;    EDX = (EDX & ~0xffff) | r;}void OPPROTO op_divl_EAX_T0(void){    helper_divl_EAX_T0();}void OPPROTO op_idivl_EAX_T0(void){    helper_idivl_EAX_T0();}#ifdef TARGET_X86_64void OPPROTO op_divq_EAX_T0(void){    helper_divq_EAX_T0();}void OPPROTO op_idivq_EAX_T0(void){    helper_idivq_EAX_T0();}#endif/* constant load & misc op *//* XXX: consistent names */void OPPROTO op_movl_T0_imu(void){    T0 = (uint32_t)PARAM1;}void OPPROTO op_movl_T0_im(void){    T0 = (int32_t)PARAM1;}void OPPROTO op_addl_T0_im(void){    T0 += PARAM1;}void OPPROTO op_andl_T0_ffff(void){    T0 = T0 & 0xffff;}void OPPROTO op_andl_T0_im(void){    T0 = T0 & PARAM1;}void OPPROTO op_movl_T0_T1(void){    T0 = T1;}void OPPROTO op_movl_T1_imu(void){    T1 = (uint32_t)PARAM1;}void OPPROTO op_movl_T1_im(void){    T1 = (int32_t)PARAM1;}void OPPROTO op_addl_T1_im(void){    T1 += PARAM1;}void OPPROTO op_movl_T1_A0(void){    T1 = A0;}void OPPROTO op_movl_A0_im(void){    A0 = (uint32_t)PARAM1;}void OPPROTO op_addl_A0_im(void){    A0 = (uint32_t)(A0 + PARAM1);}void OPPROTO op_movl_A0_seg(void){    A0 = (uint32_t)*(target_ulong *)((char *)env + PARAM1);}void OPPROTO op_addl_A0_seg(void){    A0 = (uint32_t)(A0 + *(target_ulong *)((char *)env + PARAM1));}void OPPROTO op_addl_A0_AL(void){    A0 = (uint32_t)(A0 + (EAX & 0xff));}#ifdef WORDS_BIGENDIANtypedef union UREG64 {    struct { uint16_t v3, v2, v1, v0; } w;    struct { uint32_t v1, v0; } l;    uint64_t q;} UREG64;#elsetypedef union UREG64 {    struct { uint16_t v0, v1, v2, v3; } w;    struct { uint32_t v0, v1; } l;    uint64_t q;} UREG64;#endif#ifdef TARGET_X86_64#define PARAMQ1 \({\    UREG64 __p;\    __p.l.v1 = PARAM1;\    __p.l.v0 = PARAM2;\    __p.q;\}) void OPPROTO op_movq_T0_im64(void){    T0 = PARAMQ1;}void OPPROTO op_movq_T1_im64(void){    T1 = PARAMQ1;}void OPPROTO op_movq_A0_im(void){    A0 = (int32_t)PARAM1;}void OPPROTO op_movq_A0_im64(void){    A0 = PARAMQ1;}void OPPROTO op_addq_A0_im(void){    A0 = (A0 + (int32_t)PARAM1);}void OPPROTO op_addq_A0_im64(void){    A0 = (A0 + PARAMQ1);}void OPPROTO op_movq_A0_seg(void){    A0 = *(target_ulong *)((char *)env + PARAM1);}void OPPROTO op_addq_A0_seg(void){    A0 += *(target_ulong *)((char *)env + PARAM1);}void OPPROTO op_addq_A0_AL(void){    A0 = (A0 + (EAX & 0xff));}#endifvoid OPPROTO op_andl_A0_ffff(void){    A0 = A0 & 0xffff;}/* memory access */#define MEMSUFFIX _raw#include "ops_mem.h"#if !defined(CONFIG_USER_ONLY)#define MEMSUFFIX _kernel#include "ops_mem.h"#define MEMSUFFIX _user#include "ops_mem.h"#endif/* indirect jump */void OPPROTO op_jmp_T0(void){    EIP = T0;}void OPPROTO op_movl_eip_im(void){    EIP = (uint32_t)PARAM1;}#ifdef TARGET_X86_64void OPPROTO op_movq_eip_im(void){    EIP = (int32_t)PARAM1;}void OPPROTO op_movq_eip_im64(void){    EIP = PARAMQ1;}#endifvoid OPPROTO op_hlt(void){    helper_hlt();}void OPPROTO op_monitor(void){    helper_monitor();}void OPPROTO op_mwait(void){    helper_mwait();}void OPPROTO op_debug(void){    env->exception_index = EXCP_DEBUG;    cpu_loop_exit();}void OPPROTO op_raise_interrupt(void){    int intno, next_eip_addend;    intno = PARAM1;    next_eip_addend = PARAM2;    raise_interrupt(intno, 1, 0, next_eip_addend);}void OPPROTO op_raise_exception(void){    int exception_index;    exception_index = PARAM1;    raise_exception(exception_index);}void OPPROTO op_into(void){    int eflags;    eflags = cc_table[CC_OP].compute_all();    if (eflags & CC_O) {        raise_interrupt(EXCP04_INTO, 1, 0, PARAM1);    }    FORCE_RET();}void OPPROTO op_cli(void){    env->eflags &= ~IF_MASK;}void OPPROTO op_sti(void){    env->eflags |= IF_MASK;}void OPPROTO op_set_inhibit_irq(void){    env->hflags |= HF_INHIBIT_IRQ_MASK;}void OPPROTO op_reset_inhibit_irq(void){    env->hflags &= ~HF_INHIBIT_IRQ_MASK;}void OPPROTO op_rsm(void){    helper_rsm();}#if 0/* vm86plus instructions */void OPPROTO op_cli_vm(void){    env->eflags &= ~VIF_MASK;}void OPPROTO op_sti_vm(void){    env->eflags |= VIF_MASK;    if (env->eflags & VIP_MASK) {        EIP = PARAM1;        raise_exception(EXCP0D_GPF);    }    FORCE_RET();}#endifvoid OPPROTO op_boundw(void){    int low, high, v;    low = ldsw(A0);    high = ldsw(A0 + 2);    v = (int16_t)T0;    if (v < low || v > high) {        raise_exception(EXCP05_BOUND);    }    FORCE_RET();}void OPPROTO op_boundl(void){    int low, high, v;    low = ldl(A0);    high = ldl(A0 + 4);    v = T0;    if (v < low || v > high) {        raise_exception(EXCP05_BOUND);    }    FORCE_RET();}void OPPROTO op_cmpxchg8b(void){    helper_cmpxchg8b();}void OPPROTO op_movl_T0_0(void){    T0 = 0;}void OPPROTO op_exit_tb(void){    EXIT_TB();}/* multiple size ops */#define ldul ldl#define SHIFT 0#include "ops_template.h"#undef SHIFT#define SHIFT 1#include "ops_template.h"#undef SHIFT#define SHIFT 2#include "ops_template.h"#undef SHIFT#ifdef TARGET_X86_64#define SHIFT 3#include "ops_template.h"#undef SHIFT#endif/* sign extend */void OPPROTO op_movsbl_T0_T0(void){    T0 = (int8_t)T0;}void OPPROTO op_movzbl_T0_T0(void){    T0 = (uint8_t)T0;}void OPPROTO op_movswl_T0_T0(void){    T0 = (int16_t)T0;}void OPPROTO op_movzwl_T0_T0(void){    T0 = (uint16_t)T0;}void OPPROTO op_movswl_EAX_AX(void){    EAX = (uint32_t)((int16_t)EAX);}#ifdef TARGET_X86_64void OPPROTO op_movslq_T0_T0(void){    T0 = (int32_t)T0;}void OPPROTO op_movslq_RAX_EAX(void){    EAX = (int32_t)EAX;}#endifvoid OPPROTO op_movsbw_AX_AL(void){    EAX = (EAX & ~0xffff) | ((int8_t)EAX & 0xffff);}void OPPROTO op_movslq_EDX_EAX(void){    EDX = (uint32_t)((int32_t)EAX >> 31);}void OPPROTO op_movswl_DX_AX(void){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -