op.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 1,047 行 · 第 1/2 页
C
1,047 行
/* * 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_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;}/* 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/* constant load & misc op *//* XXX: consistent names */void OPPROTO op_addl_T1_im(void){ T1 += PARAM1;}void OPPROTO op_movl_T1_A0(void){ T1 = A0;}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#define PARAMQ1 \({\ UREG64 __p;\ __p.l.v1 = PARAM1;\ __p.l.v0 = PARAM2;\ __p.q;\})#ifdef TARGET_X86_64void OPPROTO op_addq_A0_AL(void){ A0 = (A0 + (EAX & 0xff));}#endifvoid 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_cmpxchg8b(void){ helper_cmpxchg8b();}/* 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){ EDX = (EDX & ~0xffff) | (((int16_t)EAX >> 15) & 0xffff);}#ifdef TARGET_X86_64void OPPROTO op_movsqo_RDX_RAX(void){ EDX = (int64_t)EAX >> 63;}#endif/* string ops helpers */void OPPROTO op_addl_ESI_T0(void){ ESI = (uint32_t)(ESI + T0);}void OPPROTO op_addw_ESI_T0(void){ ESI = (ESI & ~0xffff) | ((ESI + T0) & 0xffff);}void OPPROTO op_addl_EDI_T0(void){ EDI = (uint32_t)(EDI + T0);}void OPPROTO op_addw_EDI_T0(void){ EDI = (EDI & ~0xffff) | ((EDI + T0) & 0xffff);}void OPPROTO op_decl_ECX(void){ ECX = (uint32_t)(ECX - 1);}void OPPROTO op_decw_ECX(void){ ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff);}#ifdef TARGET_X86_64void OPPROTO op_addq_ESI_T0(void){ ESI = (ESI + T0);}void OPPROTO op_addq_EDI_T0(void){ EDI = (EDI + T0);}void OPPROTO op_decq_ECX(void){ ECX--;}#endif/* bcd */void OPPROTO op_aam(void){ helper_aam(PARAM1);}void OPPROTO op_aad(void){ helper_aad(PARAM1);}void OPPROTO op_aaa(void){ helper_aaa();}void OPPROTO op_aas(void){ helper_aas();}void OPPROTO op_daa(void){ helper_daa();}void OPPROTO op_das(void){ helper_das();}/* segment handling */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?