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

📄 translate.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
}static inline void gen_movl_reg_TN(int reg, int t){    if (reg)	gen_op_movl_reg_TN[t][reg] ();    else	gen_movl_imm_TN(t, 0);}static inline void gen_movl_reg_T0(int reg){    gen_movl_reg_TN(reg, 0);}static inline void gen_movl_reg_T1(int reg){    gen_movl_reg_TN(reg, 1);}static inline void gen_movl_reg_T2(int reg){    gen_movl_reg_TN(reg, 2);}static inline void gen_movl_TN_reg(int reg, int t){    if (reg)	gen_op_movl_TN_reg[t][reg] ();}static inline void gen_movl_T0_reg(int reg){    gen_movl_TN_reg(reg, 0);}static inline void gen_movl_T1_reg(int reg){    gen_movl_TN_reg(reg, 1);}static inline void gen_jmp_im(target_ulong pc){#ifdef TARGET_SPARC64    if (pc == (uint32_t)pc) {        gen_op_jmp_im(pc);    } else {        gen_op_jmp_im64(pc >> 32, pc);    }#else    gen_op_jmp_im(pc);#endif}static inline void gen_movl_npc_im(target_ulong npc){#ifdef TARGET_SPARC64    if (npc == (uint32_t)npc) {        gen_op_movl_npc_im(npc);    } else {        gen_op_movq_npc_im64(npc >> 32, npc);    }#else    gen_op_movl_npc_im(npc);#endif}static inline void gen_goto_tb(DisasContext *s, int tb_num,                                target_ulong pc, target_ulong npc){    TranslationBlock *tb;    tb = s->tb;    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {        /* jump to same page: we can use a direct jump */        if (tb_num == 0)            gen_op_goto_tb0(TBPARAM(tb));        else            gen_op_goto_tb1(TBPARAM(tb));        gen_jmp_im(pc);        gen_movl_npc_im(npc);        gen_op_movl_T0_im((long)tb + tb_num);        gen_op_exit_tb();    } else {        /* jump to another page: currently not optimized */        gen_jmp_im(pc);        gen_movl_npc_im(npc);        gen_op_movl_T0_0();        gen_op_exit_tb();    }}static inline void gen_branch2(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2){    int l1;    l1 = gen_new_label();    gen_op_jz_T2_label(l1);    gen_goto_tb(dc, 0, pc1, pc1 + 4);    gen_set_label(l1);    gen_goto_tb(dc, 1, pc2, pc2 + 4);}static inline void gen_branch_a(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2){    int l1;    l1 = gen_new_label();    gen_op_jz_T2_label(l1);    gen_goto_tb(dc, 0, pc2, pc1);    gen_set_label(l1);    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);}static inline void gen_branch(DisasContext *dc, long tb, target_ulong pc, target_ulong npc){    gen_goto_tb(dc, 0, pc, npc);}static inline void gen_generic_branch(DisasContext *dc, target_ulong npc1, target_ulong npc2){    int l1, l2;    l1 = gen_new_label();    l2 = gen_new_label();    gen_op_jz_T2_label(l1);    gen_movl_npc_im(npc1);    gen_op_jmp_label(l2);    gen_set_label(l1);    gen_movl_npc_im(npc2);    gen_set_label(l2);}/* call this function before using T2 as it may have been set for a jump */static inline void flush_T2(DisasContext * dc){    if (dc->npc == JUMP_PC) {        gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);        dc->npc = DYNAMIC_PC;    }}static inline void save_npc(DisasContext * dc){    if (dc->npc == JUMP_PC) {        gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);        dc->npc = DYNAMIC_PC;    } else if (dc->npc != DYNAMIC_PC) {        gen_movl_npc_im(dc->npc);    }}static inline void save_state(DisasContext * dc){    gen_jmp_im(dc->pc);    save_npc(dc);}static inline void gen_mov_pc_npc(DisasContext * dc){    if (dc->npc == JUMP_PC) {        gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);        gen_op_mov_pc_npc();        dc->pc = DYNAMIC_PC;    } else if (dc->npc == DYNAMIC_PC) {        gen_op_mov_pc_npc();        dc->pc = DYNAMIC_PC;    } else {        dc->pc = dc->npc;    }}static GenOpFunc * const gen_cond[2][16] = {    {	gen_op_eval_ba,	gen_op_eval_be,	gen_op_eval_ble,	gen_op_eval_bl,	gen_op_eval_bleu,	gen_op_eval_bcs,	gen_op_eval_bneg,	gen_op_eval_bvs,	gen_op_eval_bn,	gen_op_eval_bne,	gen_op_eval_bg,	gen_op_eval_bge,	gen_op_eval_bgu,	gen_op_eval_bcc,	gen_op_eval_bpos,	gen_op_eval_bvc,    },    {#ifdef TARGET_SPARC64	gen_op_eval_ba,	gen_op_eval_xbe,	gen_op_eval_xble,	gen_op_eval_xbl,	gen_op_eval_xbleu,	gen_op_eval_xbcs,	gen_op_eval_xbneg,	gen_op_eval_xbvs,	gen_op_eval_bn,	gen_op_eval_xbne,	gen_op_eval_xbg,	gen_op_eval_xbge,	gen_op_eval_xbgu,	gen_op_eval_xbcc,	gen_op_eval_xbpos,	gen_op_eval_xbvc,#endif    },};static GenOpFunc * const gen_fcond[4][16] = {    {	gen_op_eval_ba,	gen_op_eval_fbne,	gen_op_eval_fblg,	gen_op_eval_fbul,	gen_op_eval_fbl,	gen_op_eval_fbug,	gen_op_eval_fbg,	gen_op_eval_fbu,	gen_op_eval_bn,	gen_op_eval_fbe,	gen_op_eval_fbue,	gen_op_eval_fbge,	gen_op_eval_fbuge,	gen_op_eval_fble,	gen_op_eval_fbule,	gen_op_eval_fbo,    },#ifdef TARGET_SPARC64    {	gen_op_eval_ba,	gen_op_eval_fbne_fcc1,	gen_op_eval_fblg_fcc1,	gen_op_eval_fbul_fcc1,	gen_op_eval_fbl_fcc1,	gen_op_eval_fbug_fcc1,	gen_op_eval_fbg_fcc1,	gen_op_eval_fbu_fcc1,	gen_op_eval_bn,	gen_op_eval_fbe_fcc1,	gen_op_eval_fbue_fcc1,	gen_op_eval_fbge_fcc1,	gen_op_eval_fbuge_fcc1,	gen_op_eval_fble_fcc1,	gen_op_eval_fbule_fcc1,	gen_op_eval_fbo_fcc1,    },    {	gen_op_eval_ba,	gen_op_eval_fbne_fcc2,	gen_op_eval_fblg_fcc2,	gen_op_eval_fbul_fcc2,	gen_op_eval_fbl_fcc2,	gen_op_eval_fbug_fcc2,	gen_op_eval_fbg_fcc2,	gen_op_eval_fbu_fcc2,	gen_op_eval_bn,	gen_op_eval_fbe_fcc2,	gen_op_eval_fbue_fcc2,	gen_op_eval_fbge_fcc2,	gen_op_eval_fbuge_fcc2,	gen_op_eval_fble_fcc2,	gen_op_eval_fbule_fcc2,	gen_op_eval_fbo_fcc2,    },    {	gen_op_eval_ba,	gen_op_eval_fbne_fcc3,	gen_op_eval_fblg_fcc3,	gen_op_eval_fbul_fcc3,	gen_op_eval_fbl_fcc3,	gen_op_eval_fbug_fcc3,	gen_op_eval_fbg_fcc3,	gen_op_eval_fbu_fcc3,	gen_op_eval_bn,	gen_op_eval_fbe_fcc3,	gen_op_eval_fbue_fcc3,	gen_op_eval_fbge_fcc3,	gen_op_eval_fbuge_fcc3,	gen_op_eval_fble_fcc3,	gen_op_eval_fbule_fcc3,	gen_op_eval_fbo_fcc3,    },#else    {}, {}, {},#endif};#ifdef TARGET_SPARC64static void gen_cond_reg(int cond){	switch (cond) {	case 0x1:	    gen_op_eval_brz();	    break;	case 0x2:	    gen_op_eval_brlez();	    break;	case 0x3:	    gen_op_eval_brlz();	    break;	case 0x5:	    gen_op_eval_brnz();	    break;	case 0x6:	    gen_op_eval_brgz();	    break;        default:	case 0x7:	    gen_op_eval_brgez();	    break;	}}#endif/* XXX: potentially incorrect if dynamic npc */static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc){    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));    target_ulong target = dc->pc + offset;	    if (cond == 0x0) {	/* unconditional not taken */	if (a) {	    dc->pc = dc->npc + 4; 	    dc->npc = dc->pc + 4;	} else {	    dc->pc = dc->npc;	    dc->npc = dc->pc + 4;	}    } else if (cond == 0x8) {	/* unconditional taken */	if (a) {	    dc->pc = target;	    dc->npc = dc->pc + 4;	} else {	    dc->pc = dc->npc;	    dc->npc = target;	}    } else {        flush_T2(dc);        gen_cond[cc][cond]();	if (a) {	    gen_branch_a(dc, (long)dc->tb, target, dc->npc);            dc->is_br = 1;	} else {            dc->pc = dc->npc;            dc->jump_pc[0] = target;            dc->jump_pc[1] = dc->npc + 4;            dc->npc = JUMP_PC;	}    }}/* XXX: potentially incorrect if dynamic npc */static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc){    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));    target_ulong target = dc->pc + offset;    if (cond == 0x0) {	/* unconditional not taken */	if (a) {	    dc->pc = dc->npc + 4;	    dc->npc = dc->pc + 4;	} else {	    dc->pc = dc->npc;	    dc->npc = dc->pc + 4;	}    } else if (cond == 0x8) {	/* unconditional taken */	if (a) {	    dc->pc = target;	    dc->npc = dc->pc + 4;	} else {	    dc->pc = dc->npc;	    dc->npc = target;	}    } else {        flush_T2(dc);        gen_fcond[cc][cond]();	if (a) {	    gen_branch_a(dc, (long)dc->tb, target, dc->npc);            dc->is_br = 1;	} else {            dc->pc = dc->npc;            dc->jump_pc[0] = target;            dc->jump_pc[1] = dc->npc + 4;            dc->npc = JUMP_PC;	}    }}#ifdef TARGET_SPARC64/* XXX: potentially incorrect if dynamic npc */static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn){    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));    target_ulong target = dc->pc + offset;    flush_T2(dc);    gen_cond_reg(cond);    if (a) {	gen_branch_a(dc, (long)dc->tb, target, dc->npc);	dc->is_br = 1;    } else {	dc->pc = dc->npc;	dc->jump_pc[0] = target;	dc->jump_pc[1] = dc->npc + 4;	dc->npc = JUMP_PC;    }}static GenOpFunc * const gen_fcmps[4] = {    gen_op_fcmps,    gen_op_fcmps_fcc1,    gen_op_fcmps_fcc2,    gen_op_fcmps_fcc3,};static GenOpFunc * const gen_fcmpd[4] = {    gen_op_fcmpd,    gen_op_fcmpd_fcc1,    gen_op_fcmpd_fcc2,    gen_op_fcmpd_fcc3,};#endif/* before an instruction, dc->pc must be static */static void disas_sparc_insn(DisasContext * dc){    unsigned int insn, opc, rs1, rs2, rd;    insn = ldl_code(dc->pc);    opc = GET_FIELD(insn, 0, 1);    rd = GET_FIELD(insn, 2, 6);    switch (opc) {    case 0:			/* branches/sethi */	{	    unsigned int xop = GET_FIELD(insn, 7, 9);	    int32_t target;	    switch (xop) {#ifdef TARGET_SPARC64	    case 0x1:		/* V9 BPcc */		{		    int cc;		    target = GET_FIELD_SP(insn, 0, 18);		    target <<= 2;		    target = sign_extend(target, 18);		    cc = GET_FIELD_SP(insn, 20, 21);		    if (cc == 0)			do_branch(dc, target, insn, 0);		    else if (cc == 2)			do_branch(dc, target, insn, 1);		    else			goto illegal_insn;		    goto jmp_insn;		}	    case 0x3:		/* V9 BPr */		{		    target = GET_FIELD_SP(insn, 0, 13) | 			(GET_FIELD_SP(insn, 20, 21) >> 7);		    target <<= 2;		    target = sign_extend(target, 16);		    rs1 = GET_FIELD(insn, 13, 17);		    gen_movl_reg_T0(rs1);		    do_branch_reg(dc, target, insn);		    goto jmp_insn;		}	    case 0x5:		/* V9 FBPcc */		{		    int cc = GET_FIELD_SP(insn, 20, 21);#if !defined(CONFIG_USER_ONLY)		    gen_op_trap_ifnofpu();#endif		    target = GET_FIELD_SP(insn, 0, 18);		    target <<= 2;		    target = sign_extend(target, 19);		    do_fbranch(dc, target, insn, cc);		    goto jmp_insn;		}

⌨️ 快捷键说明

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