📄 translate.c
字号:
/* * i386 translation * * 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 */#include <stdarg.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <inttypes.h>#include <signal.h>#include <assert.h>#include "cpu.h"#include "exec-all.h"#include "disas.h"/* XXX: move that elsewhere */static uint16_t *gen_opc_ptr;static uint32_t *gen_opparam_ptr;#define PREFIX_REPZ 0x01#define PREFIX_REPNZ 0x02#define PREFIX_LOCK 0x04#define PREFIX_DATA 0x08#define PREFIX_ADR 0x10#ifdef TARGET_X86_64#define X86_64_ONLY(x) x#define X86_64_DEF(x...) x#define CODE64(s) ((s)->code64)#define REX_X(s) ((s)->rex_x)#define REX_B(s) ((s)->rex_b)/* XXX: gcc generates push/pop in some opcodes, so we cannot use them */#if 1#define BUGGY_64(x) NULL#endif#else#define X86_64_ONLY(x) NULL#define X86_64_DEF(x...)#define CODE64(s) 0#define REX_X(s) 0#define REX_B(s) 0#endif#ifdef TARGET_X86_64static int x86_64_hregs;#endif#ifdef USE_DIRECT_JUMP#define TBPARAM(x)#else#define TBPARAM(x) (long)(x)#endiftypedef struct DisasContext { /* current insn context */ int override; /* -1 if no override */ int prefix; int aflag, dflag; target_ulong pc; /* pc = eip + cs_base */ int is_jmp; /* 1 = means jump (stop translation), 2 means CPU static state change (stop translation) */ /* current block context */ target_ulong cs_base; /* base of CS segment */ int pe; /* protected mode */ int code32; /* 32 bit code segment */#ifdef TARGET_X86_64 int lma; /* long mode active */ int code64; /* 64 bit code segment */ int rex_x, rex_b;#endif int ss32; /* 32 bit stack segment */ int cc_op; /* current CC operation */ int addseg; /* non zero if either DS/ES/SS have a non zero base */ int f_st; /* currently unused */ int vm86; /* vm86 mode */ int cpl; int iopl; int tf; /* TF cpu flag */ int singlestep_enabled; /* "hardware" single step enabled */ int jmp_opt; /* use direct block chaining for direct jumps */ int mem_index; /* select memory access functions */ int flags; /* all execution flags */ struct TranslationBlock *tb; int popl_esp_hack; /* for correct popl with esp base handling */ int rip_offset; /* only used in x86_64, but left for simplicity */ int cpuid_features; int cpuid_ext_features;} DisasContext;static void gen_eob(DisasContext *s);static void gen_jmp(DisasContext *s, target_ulong eip);static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);/* i386 arith/logic operations */enum { OP_ADDL, OP_ORL, OP_ADCL, OP_SBBL, OP_ANDL, OP_SUBL, OP_XORL, OP_CMPL,};/* i386 shift ops */enum { OP_ROL, OP_ROR, OP_RCL, OP_RCR, OP_SHL, OP_SHR, OP_SHL1, /* undocumented */ OP_SAR = 7,};enum {#define DEF(s, n, copy_size) INDEX_op_ ## s,#include "opc.h"#undef DEF NB_OPS,};#include "gen-op.h"/* operand size */enum { OT_BYTE = 0, OT_WORD, OT_LONG, OT_QUAD,};enum { /* I386 int registers */ OR_EAX, /* MUST be even numbered */ OR_ECX, OR_EDX, OR_EBX, OR_ESP, OR_EBP, OR_ESI, OR_EDI, OR_TMP0 = 16, /* temporary operand register */ OR_TMP1, OR_A0, /* temporary register used when doing address evaluation */};#ifdef TARGET_X86_64#define NB_OP_SIZES 4#define DEF_REGS(prefix, suffix) \ prefix ## EAX ## suffix,\ prefix ## ECX ## suffix,\ prefix ## EDX ## suffix,\ prefix ## EBX ## suffix,\ prefix ## ESP ## suffix,\ prefix ## EBP ## suffix,\ prefix ## ESI ## suffix,\ prefix ## EDI ## suffix,\ prefix ## R8 ## suffix,\ prefix ## R9 ## suffix,\ prefix ## R10 ## suffix,\ prefix ## R11 ## suffix,\ prefix ## R12 ## suffix,\ prefix ## R13 ## suffix,\ prefix ## R14 ## suffix,\ prefix ## R15 ## suffix,#define DEF_BREGS(prefixb, prefixh, suffix) \ \static void prefixb ## ESP ## suffix ## _wrapper(void) \{ \ if (x86_64_hregs) \ prefixb ## ESP ## suffix (); \ else \ prefixh ## EAX ## suffix (); \} \ \static void prefixb ## EBP ## suffix ## _wrapper(void) \{ \ if (x86_64_hregs) \ prefixb ## EBP ## suffix (); \ else \ prefixh ## ECX ## suffix (); \} \ \static void prefixb ## ESI ## suffix ## _wrapper(void) \{ \ if (x86_64_hregs) \ prefixb ## ESI ## suffix (); \ else \ prefixh ## EDX ## suffix (); \} \ \static void prefixb ## EDI ## suffix ## _wrapper(void) \{ \ if (x86_64_hregs) \ prefixb ## EDI ## suffix (); \ else \ prefixh ## EBX ## suffix (); \}DEF_BREGS(gen_op_movb_, gen_op_movh_, _T0)DEF_BREGS(gen_op_movb_, gen_op_movh_, _T1)DEF_BREGS(gen_op_movl_T0_, gen_op_movh_T0_, )DEF_BREGS(gen_op_movl_T1_, gen_op_movh_T1_, )#else /* !TARGET_X86_64 */#define NB_OP_SIZES 3#define DEF_REGS(prefix, suffix) \ prefix ## EAX ## suffix,\ prefix ## ECX ## suffix,\ prefix ## EDX ## suffix,\ prefix ## EBX ## suffix,\ prefix ## ESP ## suffix,\ prefix ## EBP ## suffix,\ prefix ## ESI ## suffix,\ prefix ## EDI ## suffix,#endif /* !TARGET_X86_64 */static GenOpFunc *gen_op_mov_reg_T0[NB_OP_SIZES][CPU_NB_REGS] = { [OT_BYTE] = { gen_op_movb_EAX_T0, gen_op_movb_ECX_T0, gen_op_movb_EDX_T0, gen_op_movb_EBX_T0,#ifdef TARGET_X86_64 gen_op_movb_ESP_T0_wrapper, gen_op_movb_EBP_T0_wrapper, gen_op_movb_ESI_T0_wrapper, gen_op_movb_EDI_T0_wrapper, gen_op_movb_R8_T0, gen_op_movb_R9_T0, gen_op_movb_R10_T0, gen_op_movb_R11_T0, gen_op_movb_R12_T0, gen_op_movb_R13_T0, gen_op_movb_R14_T0, gen_op_movb_R15_T0,#else gen_op_movh_EAX_T0, gen_op_movh_ECX_T0, gen_op_movh_EDX_T0, gen_op_movh_EBX_T0,#endif }, [OT_WORD] = { DEF_REGS(gen_op_movw_, _T0) }, [OT_LONG] = { DEF_REGS(gen_op_movl_, _T0) },#ifdef TARGET_X86_64 [OT_QUAD] = { DEF_REGS(gen_op_movq_, _T0) },#endif};static GenOpFunc *gen_op_mov_reg_T1[NB_OP_SIZES][CPU_NB_REGS] = { [OT_BYTE] = { gen_op_movb_EAX_T1, gen_op_movb_ECX_T1, gen_op_movb_EDX_T1, gen_op_movb_EBX_T1,#ifdef TARGET_X86_64 gen_op_movb_ESP_T1_wrapper, gen_op_movb_EBP_T1_wrapper, gen_op_movb_ESI_T1_wrapper, gen_op_movb_EDI_T1_wrapper, gen_op_movb_R8_T1, gen_op_movb_R9_T1, gen_op_movb_R10_T1, gen_op_movb_R11_T1, gen_op_movb_R12_T1, gen_op_movb_R13_T1, gen_op_movb_R14_T1, gen_op_movb_R15_T1,#else gen_op_movh_EAX_T1, gen_op_movh_ECX_T1, gen_op_movh_EDX_T1, gen_op_movh_EBX_T1,#endif }, [OT_WORD] = { DEF_REGS(gen_op_movw_, _T1) }, [OT_LONG] = { DEF_REGS(gen_op_movl_, _T1) },#ifdef TARGET_X86_64 [OT_QUAD] = { DEF_REGS(gen_op_movq_, _T1) },#endif};static GenOpFunc *gen_op_mov_reg_A0[NB_OP_SIZES - 1][CPU_NB_REGS] = { [0] = { DEF_REGS(gen_op_movw_, _A0) }, [1] = { DEF_REGS(gen_op_movl_, _A0) },#ifdef TARGET_X86_64 [2] = { DEF_REGS(gen_op_movq_, _A0) },#endif};static GenOpFunc *gen_op_mov_TN_reg[NB_OP_SIZES][2][CPU_NB_REGS] = { [OT_BYTE] = { { gen_op_movl_T0_EAX, gen_op_movl_T0_ECX, gen_op_movl_T0_EDX, gen_op_movl_T0_EBX,#ifdef TARGET_X86_64 gen_op_movl_T0_ESP_wrapper, gen_op_movl_T0_EBP_wrapper, gen_op_movl_T0_ESI_wrapper, gen_op_movl_T0_EDI_wrapper, gen_op_movl_T0_R8, gen_op_movl_T0_R9, gen_op_movl_T0_R10, gen_op_movl_T0_R11, gen_op_movl_T0_R12, gen_op_movl_T0_R13, gen_op_movl_T0_R14, gen_op_movl_T0_R15,#else gen_op_movh_T0_EAX, gen_op_movh_T0_ECX, gen_op_movh_T0_EDX, gen_op_movh_T0_EBX,#endif }, { gen_op_movl_T1_EAX, gen_op_movl_T1_ECX, gen_op_movl_T1_EDX, gen_op_movl_T1_EBX,#ifdef TARGET_X86_64 gen_op_movl_T1_ESP_wrapper, gen_op_movl_T1_EBP_wrapper, gen_op_movl_T1_ESI_wrapper, gen_op_movl_T1_EDI_wrapper, gen_op_movl_T1_R8, gen_op_movl_T1_R9, gen_op_movl_T1_R10, gen_op_movl_T1_R11, gen_op_movl_T1_R12, gen_op_movl_T1_R13, gen_op_movl_T1_R14, gen_op_movl_T1_R15,#else gen_op_movh_T1_EAX, gen_op_movh_T1_ECX, gen_op_movh_T1_EDX, gen_op_movh_T1_EBX,#endif }, }, [OT_WORD] = { { DEF_REGS(gen_op_movl_T0_, ) }, { DEF_REGS(gen_op_movl_T1_, ) }, }, [OT_LONG] = { { DEF_REGS(gen_op_movl_T0_, ) }, { DEF_REGS(gen_op_movl_T1_, ) }, },#ifdef TARGET_X86_64 [OT_QUAD] = { { DEF_REGS(gen_op_movl_T0_, ) }, { DEF_REGS(gen_op_movl_T1_, ) }, },#endif};static GenOpFunc *gen_op_movl_A0_reg[CPU_NB_REGS] = { DEF_REGS(gen_op_movl_A0_, )};static GenOpFunc *gen_op_addl_A0_reg_sN[4][CPU_NB_REGS] = { [0] = { DEF_REGS(gen_op_addl_A0_, ) }, [1] = { DEF_REGS(gen_op_addl_A0_, _s1) }, [2] = { DEF_REGS(gen_op_addl_A0_, _s2) }, [3] = { DEF_REGS(gen_op_addl_A0_, _s3) },};#ifdef TARGET_X86_64static GenOpFunc *gen_op_movq_A0_reg[CPU_NB_REGS] = { DEF_REGS(gen_op_movq_A0_, )};static GenOpFunc *gen_op_addq_A0_reg_sN[4][CPU_NB_REGS] = { [0] = { DEF_REGS(gen_op_addq_A0_, ) }, [1] = { DEF_REGS(gen_op_addq_A0_, _s1) }, [2] = { DEF_REGS(gen_op_addq_A0_, _s2) }, [3] = { DEF_REGS(gen_op_addq_A0_, _s3) },};#endifstatic GenOpFunc *gen_op_cmov_reg_T1_T0[NB_OP_SIZES - 1][CPU_NB_REGS] = { [0] = { DEF_REGS(gen_op_cmovw_, _T1_T0) }, [1] = { DEF_REGS(gen_op_cmovl_, _T1_T0) },#ifdef TARGET_X86_64 [2] = { DEF_REGS(gen_op_cmovq_, _T1_T0) },#endif};static GenOpFunc *gen_op_arith_T0_T1_cc[8] = { NULL, gen_op_orl_T0_T1, NULL, NULL, gen_op_andl_T0_T1, NULL, gen_op_xorl_T0_T1, NULL,};#define DEF_ARITHC(SUFFIX)\ {\ gen_op_adcb ## SUFFIX ## _T0_T1_cc,\ gen_op_sbbb ## SUFFIX ## _T0_T1_cc,\ },\ {\ gen_op_adcw ## SUFFIX ## _T0_T1_cc,\ gen_op_sbbw ## SUFFIX ## _T0_T1_cc,\ },\ {\ gen_op_adcl ## SUFFIX ## _T0_T1_cc,\ gen_op_sbbl ## SUFFIX ## _T0_T1_cc,\ },\ {\ X86_64_ONLY(gen_op_adcq ## SUFFIX ## _T0_T1_cc),\ X86_64_ONLY(gen_op_sbbq ## SUFFIX ## _T0_T1_cc),\ },static GenOpFunc *gen_op_arithc_T0_T1_cc[4][2] = { DEF_ARITHC( )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -