translate.c

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

C
2,495
字号
{#if !defined(CONFIG_USER_ONLY)    if(s->flags & (1ULL << INTERCEPT_IOIO_PROT)) {        if (s->cc_op != CC_OP_DYNAMIC)            gen_op_set_cc_op(s->cc_op);        SVM_movq_T1_im(s->pc - s->cs_base);        gen_jmp_im(pc_start - s->cs_base);        gen_op_geneflags();        gen_op_svm_check_intercept_io((uint32_t)(type >> 32), (uint32_t)type);        s->cc_op = CC_OP_DYNAMIC;        /* FIXME: maybe we could move the io intercept vector to the TB as well                  so we know if this is an EOB or not ... let's assume it's not                  for now. */    }#endif    return 0;}static inline int svm_is_rep(int prefixes){    return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);}static inline intgen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,                              uint64_t type, uint64_t param){    if(!(s->flags & (INTERCEPT_SVM_MASK)))	/* no SVM activated */        return 0;    switch(type) {        /* CRx and DRx reads/writes */        case SVM_EXIT_READ_CR0 ... SVM_EXIT_EXCP_BASE - 1:            if (s->cc_op != CC_OP_DYNAMIC) {                gen_op_set_cc_op(s->cc_op);                s->cc_op = CC_OP_DYNAMIC;            }            gen_jmp_im(pc_start - s->cs_base);            SVM_movq_T1_im(param);            gen_op_geneflags();            gen_op_svm_check_intercept_param((uint32_t)(type >> 32), (uint32_t)type);            /* this is a special case as we do not know if the interception occurs               so we assume there was none */            return 0;        case SVM_EXIT_MSR:            if(s->flags & (1ULL << INTERCEPT_MSR_PROT)) {                if (s->cc_op != CC_OP_DYNAMIC) {                    gen_op_set_cc_op(s->cc_op);                    s->cc_op = CC_OP_DYNAMIC;                }                gen_jmp_im(pc_start - s->cs_base);                SVM_movq_T1_im(param);                gen_op_geneflags();                gen_op_svm_check_intercept_param((uint32_t)(type >> 32), (uint32_t)type);                /* this is a special case as we do not know if the interception occurs                   so we assume there was none */                return 0;            }            break;        default:            if(s->flags & (1ULL << ((type - SVM_EXIT_INTR) + INTERCEPT_INTR))) {                if (s->cc_op != CC_OP_DYNAMIC) {                    gen_op_set_cc_op(s->cc_op);		    s->cc_op = CC_OP_EFLAGS;                }                gen_jmp_im(pc_start - s->cs_base);                SVM_movq_T1_im(param);                gen_op_geneflags();                gen_op_svm_vmexit(type >> 32, type);                /* we can optimize this one so TBs don't get longer                   than up to vmexit */                gen_eob(s);                return 1;            }    }    return 0;}static inline intgen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type){    return gen_svm_check_intercept_param(s, pc_start, type, 0);}static inline void gen_stack_update(DisasContext *s, int addend){#ifdef TARGET_X86_64    if (CODE64(s)) {        gen_op_addq_ESP_im(addend);    } else#endif    if (s->ss32) {        gen_op_addl_ESP_im(addend);    } else {        gen_op_addw_ESP_im(addend);    }}/* generate a push. It depends on ss32, addseg and dflag */static void gen_push_T0(DisasContext *s){#ifdef TARGET_X86_64    if (CODE64(s)) {        gen_op_movq_A0_reg(R_ESP);        if (s->dflag) {            gen_op_addq_A0_im(-8);            gen_op_st_T0_A0(OT_QUAD + s->mem_index);        } else {            gen_op_addq_A0_im(-2);            gen_op_st_T0_A0(OT_WORD + s->mem_index);        }        gen_op_mov_reg_A0(2, R_ESP);    } else#endif    {        gen_op_movl_A0_reg(R_ESP);        if (!s->dflag)            gen_op_addl_A0_im(-2);        else            gen_op_addl_A0_im(-4);        if (s->ss32) {            if (s->addseg) {                gen_op_movl_T1_A0();                gen_op_addl_A0_seg(R_SS);            }        } else {            gen_op_andl_A0_ffff();            gen_op_movl_T1_A0();            gen_op_addl_A0_seg(R_SS);        }        gen_op_st_T0_A0(s->dflag + 1 + s->mem_index);        if (s->ss32 && !s->addseg)            gen_op_mov_reg_A0(1, R_ESP);        else            gen_op_mov_reg_T1(s->ss32 + 1, R_ESP);    }}/* generate a push. It depends on ss32, addseg and dflag *//* slower version for T1, only used for call Ev */static void gen_push_T1(DisasContext *s){#ifdef TARGET_X86_64    if (CODE64(s)) {        gen_op_movq_A0_reg(R_ESP);        if (s->dflag) {            gen_op_addq_A0_im(-8);            gen_op_st_T1_A0(OT_QUAD + s->mem_index);        } else {            gen_op_addq_A0_im(-2);            gen_op_st_T0_A0(OT_WORD + s->mem_index);        }        gen_op_mov_reg_A0(2, R_ESP);    } else#endif    {        gen_op_movl_A0_reg(R_ESP);        if (!s->dflag)            gen_op_addl_A0_im(-2);        else            gen_op_addl_A0_im(-4);        if (s->ss32) {            if (s->addseg) {                gen_op_addl_A0_seg(R_SS);            }        } else {            gen_op_andl_A0_ffff();            gen_op_addl_A0_seg(R_SS);        }        gen_op_st_T1_A0(s->dflag + 1 + s->mem_index);        if (s->ss32 && !s->addseg)            gen_op_mov_reg_A0(1, R_ESP);        else            gen_stack_update(s, (-2) << s->dflag);    }}/* two step pop is necessary for precise exceptions */static void gen_pop_T0(DisasContext *s){#ifdef TARGET_X86_64    if (CODE64(s)) {        gen_op_movq_A0_reg(R_ESP);        gen_op_ld_T0_A0((s->dflag ? OT_QUAD : OT_WORD) + s->mem_index);    } else#endif    {        gen_op_movl_A0_reg(R_ESP);        if (s->ss32) {            if (s->addseg)                gen_op_addl_A0_seg(R_SS);        } else {            gen_op_andl_A0_ffff();            gen_op_addl_A0_seg(R_SS);        }        gen_op_ld_T0_A0(s->dflag + 1 + s->mem_index);    }}static void gen_pop_update(DisasContext *s){#ifdef TARGET_X86_64    if (CODE64(s) && s->dflag) {        gen_stack_update(s, 8);    } else#endif    {        gen_stack_update(s, 2 << s->dflag);    }}static void gen_stack_A0(DisasContext *s){    gen_op_movl_A0_reg(R_ESP);    if (!s->ss32)        gen_op_andl_A0_ffff();    gen_op_movl_T1_A0();    if (s->addseg)        gen_op_addl_A0_seg(R_SS);}/* NOTE: wrap around in 16 bit not fully handled */static void gen_pusha(DisasContext *s){    int i;    gen_op_movl_A0_reg(R_ESP);    gen_op_addl_A0_im(-16 <<  s->dflag);    if (!s->ss32)        gen_op_andl_A0_ffff();    gen_op_movl_T1_A0();    if (s->addseg)        gen_op_addl_A0_seg(R_SS);    for(i = 0;i < 8; i++) {        gen_op_mov_TN_reg(OT_LONG, 0, 7 - i);        gen_op_st_T0_A0(OT_WORD + s->dflag + s->mem_index);        gen_op_addl_A0_im(2 <<  s->dflag);    }    gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);}/* NOTE: wrap around in 16 bit not fully handled */static void gen_popa(DisasContext *s){    int i;    gen_op_movl_A0_reg(R_ESP);    if (!s->ss32)        gen_op_andl_A0_ffff();    gen_op_movl_T1_A0();    gen_op_addl_T1_im(16 <<  s->dflag);    if (s->addseg)        gen_op_addl_A0_seg(R_SS);    for(i = 0;i < 8; i++) {        /* ESP is not reloaded */        if (i != 3) {            gen_op_ld_T0_A0(OT_WORD + s->dflag + s->mem_index);            gen_op_mov_reg_T0(OT_WORD + s->dflag, 7 - i);        }        gen_op_addl_A0_im(2 <<  s->dflag);    }    gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);}static void gen_enter(DisasContext *s, int esp_addend, int level){    int ot, opsize;    level &= 0x1f;#ifdef TARGET_X86_64    if (CODE64(s)) {        ot = s->dflag ? OT_QUAD : OT_WORD;        opsize = 1 << ot;        gen_op_movl_A0_reg(R_ESP);        gen_op_addq_A0_im(-opsize);        gen_op_movl_T1_A0();        /* push bp */        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);        gen_op_st_T0_A0(ot + s->mem_index);        if (level) {            /* XXX: must save state */            tcg_gen_helper_0_2(helper_enter64_level,                               tcg_const_i32(level),                               tcg_const_i32((ot == OT_QUAD)));        }        gen_op_mov_reg_T1(ot, R_EBP);        gen_op_addl_T1_im( -esp_addend + (-opsize * level) );        gen_op_mov_reg_T1(OT_QUAD, R_ESP);    } else#endif    {        ot = s->dflag + OT_WORD;        opsize = 2 << s->dflag;        gen_op_movl_A0_reg(R_ESP);        gen_op_addl_A0_im(-opsize);        if (!s->ss32)            gen_op_andl_A0_ffff();        gen_op_movl_T1_A0();        if (s->addseg)            gen_op_addl_A0_seg(R_SS);        /* push bp */        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);        gen_op_st_T0_A0(ot + s->mem_index);        if (level) {            /* XXX: must save state */            tcg_gen_helper_0_2(helper_enter_level,                               tcg_const_i32(level),                               tcg_const_i32(s->dflag));        }        gen_op_mov_reg_T1(ot, R_EBP);        gen_op_addl_T1_im( -esp_addend + (-opsize * level) );        gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);    }}static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip){    if (s->cc_op != CC_OP_DYNAMIC)        gen_op_set_cc_op(s->cc_op);    gen_jmp_im(cur_eip);    tcg_gen_helper_0_1(helper_raise_exception, tcg_const_i32(trapno));    s->is_jmp = 3;}/* an interrupt is different from an exception because of the   privilege checks */static void gen_interrupt(DisasContext *s, int intno,                          target_ulong cur_eip, target_ulong next_eip){    if (s->cc_op != CC_OP_DYNAMIC)        gen_op_set_cc_op(s->cc_op);    gen_jmp_im(cur_eip);    tcg_gen_helper_0_2(helper_raise_interrupt,                        tcg_const_i32(intno),                        tcg_const_i32(next_eip - cur_eip));    s->is_jmp = 3;}static void gen_debug(DisasContext *s, target_ulong cur_eip){    if (s->cc_op != CC_OP_DYNAMIC)        gen_op_set_cc_op(s->cc_op);    gen_jmp_im(cur_eip);    tcg_gen_helper_0_0(helper_debug);    s->is_jmp = 3;}/* generate a generic end of block. Trace exception is also generated   if needed */static void gen_eob(DisasContext *s){    if (s->cc_op != CC_OP_DYNAMIC)        gen_op_set_cc_op(s->cc_op);    if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {        tcg_gen_helper_0_0(helper_reset_inhibit_irq);    }    if (s->singlestep_enabled) {        tcg_gen_helper_0_0(helper_debug);    } else if (s->tf) {	tcg_gen_helper_0_0(helper_single_step);    } else {        tcg_gen_exit_tb(0);    }    s->is_jmp = 3;}/* generate a jump to eip. No segment change must happen before as a   direct call to the next block may occur */static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num){    if (s->jmp_opt) {        if (s->cc_op != CC_OP_DYNAMIC) {            gen_op_set_cc_op(s->cc_op);            s->cc_op = CC_OP_DYNAMIC;        }        gen_goto_tb(s, tb_num, eip);        s->is_jmp = 3;    } else {        gen_jmp_im(eip);        gen_eob(s);    }}static void gen_jmp(DisasContext *s, target_ulong eip){    gen_jmp_tb(s, eip, 0);}static inline void gen_ldq_env_A0(int idx, int offset){    int mem_index = (idx >> 2) - 1;    tcg_gen_qemu_ld64(cpu_tmp1, cpu_A0, mem_index);    tcg_gen_st_i64(cpu_tmp1, cpu_env, offset);}static inline void gen_stq_env_A0(int idx, int offset){    int mem_index = (idx >> 2) - 1;    tcg_gen_ld_i64(cpu_tmp1, cpu_env, offset);    tcg_gen_qemu_st64(cpu_tmp1, cpu_A0, mem_index);}static inline void gen_ldo_env_A0(int idx, int offset){    int mem_index = (idx >> 2) - 1;    tcg_gen_qemu_ld64(cpu_tmp1, cpu_A0, mem_index);    tcg_gen_st_i64(cpu_tmp1, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);    tcg_gen_qemu_ld64(cpu_tmp1, cpu_tmp0, mem_index);    tcg_gen_st_i64(cpu_tmp1, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));}static inline void gen_sto_env_A0(int idx, int offset){    int mem_index = (idx >> 2) - 1;    tcg_gen_ld_i64(cpu_tmp1, cpu_env, offset + offsetof(XMMReg, XMM_Q(0)));    tcg_gen_qemu_st64(cpu_tmp1, cpu_A0, mem_index);    tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);    tcg_gen_ld_i64(cpu_tmp1, cpu_env, offset + offsetof(XMMReg, XMM_Q(1)));    tcg_gen_qemu_st64(cpu_tmp1, cpu_tmp0, mem_index);}static inline void gen_op_movo(int d_offset, int s_offset){    tcg_gen_ld_i64(cpu_tmp1, cpu_env, s_offset);    tcg_gen_st_i64(cpu_tmp1, cpu_env, d_offset);    tcg_gen_ld_i64(cpu_tmp1, cpu_env, s_offset + 8);    tcg_gen_st_i64(cpu_tmp1, cpu_env, d_offset + 8);}static inline void gen_op_movq(int d_offset, int s_offset){    tcg_gen_ld_i64(cpu_tmp1, cpu_env, s_offset);    tcg_gen_st_i64(cpu_tmp1, cpu_env, d_offset);}static inline void gen_op_movl(int d_offset, int s_offset){    tcg_gen_ld_i32(cpu_tmp2, cpu_env, s_offset);    tcg_gen_st_i32(cpu_tmp2, cpu_env, d_offset);}static inline void gen_op_movq_env_0(int d_offset){    tcg_gen_movi_i64(cpu_tmp1, 0);    tcg_gen_st_i64(cpu_tmp1, cpu_env, d_offset);}#define SSE_SPECIAL ((void *)1)#define SSE_DUMMY ((void *)2)#define MMX_OP2(x) { helper_ ## x ## _mmx, helper_ ## x ## _xmm }#define SSE_FOP(x) { helper_ ## x ## ps, helper_ ## x ## pd, \                     helper_ ## x ## ss, helper_ ## x ## sd, }static void *sse_op_table1[256][4] = {    /* 3DNow! extensions */    [0x0e] = { SSE_DUMMY }, /* femms */    [0x0f] = { SSE_DUMMY }, /* pf... */    /* pure SSE operations */    [0x10] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */    [0x11] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movups, movupd, movss, movsd */    [0x12] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* movlps, movlpd, movsldup, movddup */    [0x13] = { SSE_SPECIAL, SSE_SPECIAL },  /* movlps, movlpd */    [0x14] = { helper_punpckldq_xmm, helper_punpcklqdq_xmm },    [0x15] = { helper_punpckhdq_xmm, helper_punpckhqdq_xmm },    [0x16] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd, movshdup */    [0x17] = { SSE_SPECIAL, SSE_SPECIAL },  /* movhps, movhpd */    [0x28] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */    [0x29] = { SSE_SPECIAL, SSE_SPECIAL },  /* movaps, movapd */    [0x2a] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtpi2ps, cvtpi2pd, cvtsi2ss, cvtsi2sd */    [0x2b] = { SSE_SPECIAL, SSE_SPECIAL },  /* movntps, movntpd */    [0x2c] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvttps2pi, cvttpd2pi, cvttsd2si, cvttss2si */    [0x2d] = { SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL, SSE_SPECIAL }, /* cvtps2pi, cvtpd2pi, cvtsd2si, cvtss2si */    [0x2e] = { helper_ucomiss, helper_ucomisd },    [0x2f] = { helper_comiss, helper_comisd },    [0x50] = { SSE_SPECIAL, SSE_SPECIAL }, /* movmskps, movmskpd */    [0x51] = SSE_FOP(sqrt),    [0x52] = { helper_rsqrtps, NULL, helper_rsqrtss, NULL },    [0x53] = { helper_rcpps, NULL, helper_rcpss, NULL },    [0x54] = { helper_pand_xmm, helper_pand_xmm }, /* andps, andpd */    [0x55] = { helper_pandn_xmm, helper_pandn_xmm }, /* andnps, andnpd */    [0x56] = { helper_por_xmm, helper_por_xmm }, /* orps, orpd */    [0x57] = { helper_pxor_xmm, helper_pxor_xmm }, /* xorps, xorpd */    [0x58] = SSE_FOP(add),    [0x59] = SSE_FOP(mul),    [0x5a] = { helper_cvtps2pd, helper_cvtpd2ps,               helper_cvtss2sd, helper_cvtsd2ss },    [0x5b] = { helper_cvtdq2ps, helper_cvtps2dq, helper_cvttps2dq },    [0x5c] = SSE_FOP(sub),    [0x5d] = SSE_FOP(min),    [0x5e] = SSE_FOP(div),    [0x5f] = SSE_FOP(max),    [0xc2] = SSE_FOP(cmpeq),    [0xc6] = { helper_sh

⌨️ 快捷键说明

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