translate.c

来自「xen虚拟机源代码安装包」· C语言 代码 · 共 2,495 行 · 第 1/5 页

C
2,495
字号
#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( )};static GenOpFunc *gen_op_arithc_mem_T0_T1_cc[3 * 4][2] = {    DEF_ARITHC(_raw)#ifndef CONFIG_USER_ONLY    DEF_ARITHC(_kernel)    DEF_ARITHC(_user)#endif};static const int cc_op_arithb[8] = {    CC_OP_ADDB,    CC_OP_LOGICB,    CC_OP_ADDB,    CC_OP_SUBB,    CC_OP_LOGICB,    CC_OP_SUBB,    CC_OP_LOGICB,    CC_OP_SUBB,};#define DEF_CMPXCHG(SUFFIX)\    gen_op_cmpxchgb ## SUFFIX ## _T0_T1_EAX_cc,\    gen_op_cmpxchgw ## SUFFIX ## _T0_T1_EAX_cc,\    gen_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc,\    X86_64_ONLY(gen_op_cmpxchgq ## SUFFIX ## _T0_T1_EAX_cc),static GenOpFunc *gen_op_cmpxchg_T0_T1_EAX_cc[4] = {    DEF_CMPXCHG( )};static GenOpFunc *gen_op_cmpxchg_mem_T0_T1_EAX_cc[3 * 4] = {    DEF_CMPXCHG(_raw)#ifndef CONFIG_USER_ONLY    DEF_CMPXCHG(_kernel)    DEF_CMPXCHG(_user)#endif};#define DEF_SHIFT(SUFFIX)\    {\        gen_op_rolb ## SUFFIX ## _T0_T1_cc,\        gen_op_rorb ## SUFFIX ## _T0_T1_cc,\        gen_op_rclb ## SUFFIX ## _T0_T1_cc,\        gen_op_rcrb ## SUFFIX ## _T0_T1_cc,\        gen_op_shlb ## SUFFIX ## _T0_T1_cc,\        gen_op_shrb ## SUFFIX ## _T0_T1_cc,\        gen_op_shlb ## SUFFIX ## _T0_T1_cc,\        gen_op_sarb ## SUFFIX ## _T0_T1_cc,\    },\    {\        gen_op_rolw ## SUFFIX ## _T0_T1_cc,\        gen_op_rorw ## SUFFIX ## _T0_T1_cc,\        gen_op_rclw ## SUFFIX ## _T0_T1_cc,\        gen_op_rcrw ## SUFFIX ## _T0_T1_cc,\        gen_op_shlw ## SUFFIX ## _T0_T1_cc,\        gen_op_shrw ## SUFFIX ## _T0_T1_cc,\        gen_op_shlw ## SUFFIX ## _T0_T1_cc,\        gen_op_sarw ## SUFFIX ## _T0_T1_cc,\    },\    {\        gen_op_roll ## SUFFIX ## _T0_T1_cc,\        gen_op_rorl ## SUFFIX ## _T0_T1_cc,\        gen_op_rcll ## SUFFIX ## _T0_T1_cc,\        gen_op_rcrl ## SUFFIX ## _T0_T1_cc,\        gen_op_shll ## SUFFIX ## _T0_T1_cc,\        gen_op_shrl ## SUFFIX ## _T0_T1_cc,\        gen_op_shll ## SUFFIX ## _T0_T1_cc,\        gen_op_sarl ## SUFFIX ## _T0_T1_cc,\    },\    {\        X86_64_ONLY(gen_op_rolq ## SUFFIX ## _T0_T1_cc),\        X86_64_ONLY(gen_op_rorq ## SUFFIX ## _T0_T1_cc),\        X86_64_ONLY(gen_op_rclq ## SUFFIX ## _T0_T1_cc),\        X86_64_ONLY(gen_op_rcrq ## SUFFIX ## _T0_T1_cc),\        X86_64_ONLY(gen_op_shlq ## SUFFIX ## _T0_T1_cc),\        X86_64_ONLY(gen_op_shrq ## SUFFIX ## _T0_T1_cc),\        X86_64_ONLY(gen_op_shlq ## SUFFIX ## _T0_T1_cc),\        X86_64_ONLY(gen_op_sarq ## SUFFIX ## _T0_T1_cc),\    },static GenOpFunc *gen_op_shift_T0_T1_cc[4][8] = {    DEF_SHIFT( )};static GenOpFunc *gen_op_shift_mem_T0_T1_cc[3 * 4][8] = {    DEF_SHIFT(_raw)#ifndef CONFIG_USER_ONLY    DEF_SHIFT(_kernel)    DEF_SHIFT(_user)#endif};#define DEF_SHIFTD(SUFFIX, op)\    {\        NULL,\        NULL,\    },\    {\        gen_op_shldw ## SUFFIX ## _T0_T1_ ## op ## _cc,\        gen_op_shrdw ## SUFFIX ## _T0_T1_ ## op ## _cc,\     },\    {\        gen_op_shldl ## SUFFIX ## _T0_T1_ ## op ## _cc,\        gen_op_shrdl ## SUFFIX ## _T0_T1_ ## op ## _cc,\    },\    {\X86_64_DEF(gen_op_shldq ## SUFFIX ## _T0_T1_ ## op ## _cc,\           gen_op_shrdq ## SUFFIX ## _T0_T1_ ## op ## _cc,)\    },static GenOpFunc1 *gen_op_shiftd_T0_T1_im_cc[4][2] = {    DEF_SHIFTD(, im)};static GenOpFunc *gen_op_shiftd_T0_T1_ECX_cc[4][2] = {    DEF_SHIFTD(, ECX)};static GenOpFunc1 *gen_op_shiftd_mem_T0_T1_im_cc[3 * 4][2] = {    DEF_SHIFTD(_raw, im)#ifndef CONFIG_USER_ONLY    DEF_SHIFTD(_kernel, im)    DEF_SHIFTD(_user, im)#endif};static GenOpFunc *gen_op_shiftd_mem_T0_T1_ECX_cc[3 * 4][2] = {    DEF_SHIFTD(_raw, ECX)#ifndef CONFIG_USER_ONLY    DEF_SHIFTD(_kernel, ECX)    DEF_SHIFTD(_user, ECX)#endif};static GenOpFunc *gen_op_btx_T0_T1_cc[3][4] = {    [0] = {        gen_op_btw_T0_T1_cc,        gen_op_btsw_T0_T1_cc,        gen_op_btrw_T0_T1_cc,        gen_op_btcw_T0_T1_cc,    },    [1] = {        gen_op_btl_T0_T1_cc,        gen_op_btsl_T0_T1_cc,        gen_op_btrl_T0_T1_cc,        gen_op_btcl_T0_T1_cc,    },#ifdef TARGET_X86_64    [2] = {        gen_op_btq_T0_T1_cc,        gen_op_btsq_T0_T1_cc,        gen_op_btrq_T0_T1_cc,        gen_op_btcq_T0_T1_cc,    },#endif};static GenOpFunc *gen_op_add_bit_A0_T1[3] = {    gen_op_add_bitw_A0_T1,    gen_op_add_bitl_A0_T1,    X86_64_ONLY(gen_op_add_bitq_A0_T1),};static GenOpFunc *gen_op_bsx_T0_cc[3][2] = {    [0] = {        gen_op_bsfw_T0_cc,        gen_op_bsrw_T0_cc,    },    [1] = {        gen_op_bsfl_T0_cc,        gen_op_bsrl_T0_cc,    },#ifdef TARGET_X86_64    [2] = {        gen_op_bsfq_T0_cc,        gen_op_bsrq_T0_cc,    },#endif};static inline void gen_op_lds_T0_A0(int idx){    int mem_index = (idx >> 2) - 1;    switch(idx & 3) {    case 0:        tcg_gen_qemu_ld8s(cpu_T[0], cpu_A0, mem_index);        break;    case 1:        tcg_gen_qemu_ld16s(cpu_T[0], cpu_A0, mem_index);        break;    default:    case 2:        tcg_gen_qemu_ld32s(cpu_T[0], cpu_A0, mem_index);        break;    }}/* sign does not matter, except for lidt/lgdt call (TODO: fix it) */static inline void gen_op_ld_T0_A0(int idx){    int mem_index = (idx >> 2) - 1;    switch(idx & 3) {    case 0:        tcg_gen_qemu_ld8u(cpu_T[0], cpu_A0, mem_index);        break;    case 1:        tcg_gen_qemu_ld16u(cpu_T[0], cpu_A0, mem_index);        break;    case 2:        tcg_gen_qemu_ld32u(cpu_T[0], cpu_A0, mem_index);        break;    default:    case 3:        tcg_gen_qemu_ld64(cpu_T[0], cpu_A0, mem_index);        break;    }}static inline void gen_op_ldu_T0_A0(int idx){    gen_op_ld_T0_A0(idx);}static inline void gen_op_ld_T1_A0(int idx){    int mem_index = (idx >> 2) - 1;    switch(idx & 3) {    case 0:        tcg_gen_qemu_ld8u(cpu_T[1], cpu_A0, mem_index);        break;    case 1:        tcg_gen_qemu_ld16u(cpu_T[1], cpu_A0, mem_index);        break;    case 2:        tcg_gen_qemu_ld32u(cpu_T[1], cpu_A0, mem_index);        break;    default:    case 3:        tcg_gen_qemu_ld64(cpu_T[1], cpu_A0, mem_index);        break;    }}static inline void gen_op_st_T0_A0(int idx){    int mem_index = (idx >> 2) - 1;    switch(idx & 3) {    case 0:        tcg_gen_qemu_st8(cpu_T[0], cpu_A0, mem_index);        break;    case 1:        tcg_gen_qemu_st16(cpu_T[0], cpu_A0, mem_index);        break;    case 2:        tcg_gen_qemu_st32(cpu_T[0], cpu_A0, mem_index);        break;    default:    case 3:        tcg_gen_qemu_st64(cpu_T[0], cpu_A0, mem_index);        break;    }}static inline void gen_op_st_T1_A0(int idx){    int mem_index = (idx >> 2) - 1;    switch(idx & 3) {    case 0:        tcg_gen_qemu_st8(cpu_T[1], cpu_A0, mem_index);        break;    case 1:        tcg_gen_qemu_st16(cpu_T[1], cpu_A0, mem_index);        break;    case 2:        tcg_gen_qemu_st32(cpu_T[1], cpu_A0, mem_index);        break;    default:    case 3:        tcg_gen_qemu_st64(cpu_T[1], cpu_A0, mem_index);        break;    }}static inline void gen_jmp_im(target_ulong pc){    tcg_gen_movi_tl(cpu_tmp0, pc);    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, eip));}static inline void gen_string_movl_A0_ESI(DisasContext *s){    int override;    override = s->override;#ifdef TARGET_X86_64    if (s->aflag == 2) {        if (override >= 0) {            gen_op_movq_A0_seg(override);            gen_op_addq_A0_reg_sN(0, R_ESI);        } else {            gen_op_movq_A0_reg(R_ESI);        }    } else#endif    if (s->aflag) {        /* 32 bit address */        if (s->addseg && override < 0)            override = R_DS;        if (override >= 0) {            gen_op_movl_A0_seg(override);            gen_op_addl_A0_reg_sN(0, R_ESI);        } else {            gen_op_movl_A0_reg(R_ESI);        }    } else {        /* 16 address, always override */        if (override < 0)            override = R_DS;        gen_op_movl_A0_reg(R_ESI);        gen_op_andl_A0_ffff();        gen_op_addl_A0_seg(override);    }}static inline void gen_string_movl_A0_EDI(DisasContext *s){#ifdef TARGET_X86_64    if (s->aflag == 2) {        gen_op_movq_A0_reg(R_EDI);    } else#endif    if (s->aflag) {        if (s->addseg) {            gen_op_movl_A0_seg(R_ES);            gen_op_addl_A0_reg_sN(0, R_EDI);        } else {            gen_op_movl_A0_reg(R_EDI);        }    } else {        gen_op_movl_A0_reg(R_EDI);        gen_op_andl_A0_ffff();        gen_op_addl_A0_seg(R_ES);    }}static GenOpFunc *gen_op_movl_T0_Dshift[4] = {    gen_op_movl_T0_Dshiftb,    gen_op_movl_T0_Dshiftw,    gen_op_movl_T0_Dshiftl,    X86_64_ONLY(gen_op_movl_T0_Dshiftq),};static GenOpFunc1 *gen_op_jnz_ecx[3] = {    gen_op_jnz_ecxw,    gen_op_jnz_ecxl,    X86_64_ONLY(gen_op_jnz_ecxq),};static GenOpFunc1 *gen_op_jz_ecx[3] = {    gen_op_jz_ecxw,    gen_op_jz_ecxl,    X86_64_ONLY(gen_op_jz_ecxq),};static GenOpFunc *gen_op_dec_ECX[3] = {    gen_op_decw_ECX,    gen_op_decl_ECX,    X86_64_ONLY(gen_op_decq_ECX),};static GenOpFunc1 *gen_op_string_jnz_sub[2][4] = {    {        gen_op_jnz_subb,        gen_op_jnz_subw,        gen_op_jnz_subl,        X86_64_ONLY(gen_op_jnz_subq),    },    {        gen_op_jz_subb,        gen_op_jz_subw,        gen_op_jz_subl,        X86_64_ONLY(gen_op_jz_subq),    },};static GenOpFunc *gen_op_in_DX_T0[3] = {    gen_op_inb_DX_T0,    gen_op_inw_DX_T0,    gen_op_inl_DX_T0,};static GenOpFunc *gen_op_out_DX_T0[3] = {    gen_op_outb_DX_T0,    gen_op_outw_DX_T0,    gen_op_outl_DX_T0,};static GenOpFunc *gen_op_in[3] = {    gen_op_inb_T0_T1,    gen_op_inw_T0_T1,    gen_op_inl_T0_T1,};static GenOpFunc *gen_op_out[3] = {    gen_op_outb_T0_T1,    gen_op_outw_T0_T1,    gen_op_outl_T0_T1,};static GenOpFunc *gen_check_io_T0[3] = {    gen_op_check_iob_T0,    gen_op_check_iow_T0,    gen_op_check_iol_T0,};static GenOpFunc *gen_check_io_DX[3] = {    gen_op_check_iob_DX,    gen_op_check_iow_DX,    gen_op_check_iol_DX,};static void gen_check_io(DisasContext *s, int ot, int use_dx, target_ulong cur_eip){    if (s->pe && (s->cpl > s->iopl || s->vm86)) {        if (s->cc_op != CC_OP_DYNAMIC)            gen_op_set_cc_op(s->cc_op);        gen_jmp_im(cur_eip);        if (use_dx)            gen_check_io_DX[ot]();        else            gen_check_io_T0[ot]();    }}static inline void gen_movs(DisasContext *s, int ot){    gen_string_movl_A0_ESI(s);    gen_op_ld_T0_A0(ot + s->mem_index);    gen_string_movl_A0_EDI(s);    gen_op_st_T0_A0(ot + s->mem_index);    gen_op_movl_T0_Dshift[ot]();#ifdef TARGET_X86_64    if (s->aflag == 2) {        gen_op_addq_ESI_T0();        gen_op_addq_EDI_T0();    } else#endif    if (s->aflag) {        gen_op_addl_ESI_T0();        gen_op_addl_EDI_T0();    } else {        gen_op_addw_ESI_T0();        gen_op_addw_EDI_T0();    }}static inline void gen_update_cc_op(DisasContext *s){    if (s->cc_op != CC_OP_DYNAMIC) {        gen_op_set_cc_op(s->cc_op);        s->cc_op = CC_OP_DYNAMIC;    }}/* XXX: does not work with gdbstub "ice" single step - not a   serious problem */static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip){    int l1, l2;    l1 = gen_new_label();    l2 = gen_new_label();    gen_op_jnz_ecx[s->aflag](l1);    gen_set_label(l2);    gen_jmp_tb(s, next_eip, 1);    gen_set_label(l1);    return l2;}

⌨️ 快捷键说明

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