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

📄 translate.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  SH4 translation *  *  Copyright (c) 2005 Samuel Tardieu * * 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 <assert.h>#define DEBUG_DISAS#define SH4_DEBUG_DISAS//#define SH4_SINGLE_STEP#include "cpu.h"#include "exec-all.h"#include "disas.h"enum {#define DEF(s, n, copy_size) INDEX_op_ ## s,#include "opc.h"#undef DEF    NB_OPS,};#ifdef USE_DIRECT_JUMP#define TBPARAM(x)#else#define TBPARAM(x) ((long)(x))#endifstatic uint16_t *gen_opc_ptr;static uint32_t *gen_opparam_ptr;#include "gen-op.h"typedef struct DisasContext {    struct TranslationBlock *tb;    target_ulong pc;    uint32_t sr;    uint16_t opcode;    uint32_t flags;    int memidx;    uint32_t delayed_pc;    int singlestep_enabled;} DisasContext;#ifdef CONFIG_USER_ONLY#define GEN_OP_LD(width) \  void gen_op_ld##width##_T0_T0 (DisasContext *ctx) { \    gen_op_ld##width##_T0_T0_raw(); \  }#define GEN_OP_ST(width) \  void gen_op_st##width##_T0_T1 (DisasContext *ctx) { \    gen_op_st##width##_T0_T1_raw(); \  }#else#define GEN_OP_LD(width) \  void gen_op_ld##width##_T0_T0 (DisasContext *ctx) { \    if (ctx->memidx) gen_op_ld##width##_T0_T0_kernel(); \    else gen_op_ld##width##_T0_T0_user();\  }#define GEN_OP_ST(width) \  void gen_op_st##width##_T0_T1 (DisasContext *ctx) { \    if (ctx->memidx) gen_op_st##width##_T0_T1_kernel(); \    else gen_op_st##width##_T0_T1_user();\  }#endifGEN_OP_LD(ub)    GEN_OP_LD(b)    GEN_OP_ST(b)    GEN_OP_LD(uw)    GEN_OP_LD(w)    GEN_OP_ST(w)    GEN_OP_LD(l)    GEN_OP_ST(l)void cpu_dump_state(CPUState * env, FILE * f,		    int (*cpu_fprintf) (FILE * f, const char *fmt, ...),		    int flags){    int i;    cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x\n",		env->pc, env->sr, env->pr);    for (i = 0; i < 24; i += 4) {	cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",		    i, env->gregs[i], i + 1, env->gregs[i + 1],		    i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);    }    if (env->flags & DELAY_SLOT) {	cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",		    env->delayed_pc);    } else if (env->flags & DELAY_SLOT_CONDITIONAL) {	cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",		    env->delayed_pc);    }}void cpu_sh4_reset(CPUSH4State * env){    env->sr = 0x700000F0;	/* MD, RB, BL, I3-I0 */    env->vbr = 0;    env->pc = 0xA0000000;    env->fpscr = 0x00040001;    env->mmucr = 0;}CPUSH4State *cpu_sh4_init(void){    CPUSH4State *env;    env = qemu_mallocz(sizeof(CPUSH4State));    if (!env)	return NULL;    cpu_exec_init(env);    cpu_sh4_reset(env);    tlb_flush(env, 1);    return env;}#ifdef CONFIG_USER_ONLYtarget_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr){    return addr;}#elsetarget_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr){    target_ulong physical;    int prot;    get_physical_address(env, &physical, &prot, addr, PAGE_READ, 0);    return physical;}#endifstatic void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest){    TranslationBlock *tb;    tb = ctx->tb;    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&	!ctx->singlestep_enabled) {	/* Use a direct jump if in same page and singlestep not enabled */	if (n == 0)	    gen_op_goto_tb0(TBPARAM(tb));	else	    gen_op_goto_tb1(TBPARAM(tb));	gen_op_movl_imm_T0((long) tb + n);    } else {	gen_op_movl_imm_T0(0);    }    gen_op_movl_imm_PC(dest);    if (ctx->singlestep_enabled)	gen_op_debug();    gen_op_exit_tb();}/* Jump to pc after an exception */static void gen_jump_exception(DisasContext * ctx){    gen_op_movl_imm_T0(0);    if (ctx->singlestep_enabled)	gen_op_debug();    gen_op_exit_tb();}static void gen_jump(DisasContext * ctx){    if (ctx->delayed_pc == (uint32_t) - 1) {	/* Target is not statically known, it comes necessarily from a	   delayed jump as immediate jump are conditinal jumps */	gen_op_movl_delayed_pc_PC();	gen_op_movl_imm_T0(0);	if (ctx->singlestep_enabled)	    gen_op_debug();	gen_op_exit_tb();    } else {	gen_goto_tb(ctx, 0, ctx->delayed_pc);    }}/* Immediate conditional jump (bt or bf) */static void gen_conditional_jump(DisasContext * ctx,				 target_ulong ift, target_ulong ifnott){    int l1;    l1 = gen_new_label();    gen_op_jT(l1);    gen_goto_tb(ctx, 0, ifnott);    gen_set_label(l1);    gen_goto_tb(ctx, 1, ift);}/* Delayed conditional jump (bt or bf) */static void gen_delayed_conditional_jump(DisasContext * ctx){    int l1;    l1 = gen_new_label();    gen_op_jTT2(l1);    gen_goto_tb(ctx, 0, ctx->pc);    gen_set_label(l1);    gen_goto_tb(ctx, 1, ctx->delayed_pc);}#define B3_0 (ctx->opcode & 0xf)#define B6_4 ((ctx->opcode >> 4) & 0x7)#define B7_4 ((ctx->opcode >> 4) & 0xf)#define B7_0 (ctx->opcode & 0xff)#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \  (ctx->opcode & 0xfff))#define B11_8 ((ctx->opcode >> 8) & 0xf)#define B15_12 ((ctx->opcode >> 12) & 0xf)#define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \		(x) + 16 : (x))#define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \		? (x) + 16 : (x))#define CHECK_NOT_DELAY_SLOT \  if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \  {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \   return;}void decode_opc(DisasContext * ctx){#if 0    fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);#endif    switch (ctx->opcode) {    case 0x0019:		/* div0u */	printf("div0u\n");	gen_op_div0u();	return;    case 0x000b:		/* rts */	CHECK_NOT_DELAY_SLOT gen_op_rts();	ctx->flags |= DELAY_SLOT;	ctx->delayed_pc = (uint32_t) - 1;	return;    case 0x0028:		/* clrmac */	gen_op_clrmac();	return;    case 0x0048:		/* clrs */	gen_op_clrs();	return;    case 0x0008:		/* clrt */	gen_op_clrt();	return;    case 0x0038:		/* ldtlb */	assert(0);		/* XXXXX */	return;    case 0x004b:		/* rte */	CHECK_NOT_DELAY_SLOT gen_op_rte();	ctx->flags |= DELAY_SLOT;	ctx->delayed_pc = (uint32_t) - 1;	return;    case 0x0058:		/* sets */	gen_op_sets();	return;    case 0x0018:		/* sett */	gen_op_sett();	return;    case 0xfbfb:		/* frchg */	assert(0);		/* XXXXX */	return;    case 0xf3fb:		/* fschg */	assert(0);		/* XXXXX */	return;    case 0x0009:		/* nop */	return;    case 0x001b:		/* sleep */	assert(0);		/* XXXXX */	return;    }    switch (ctx->opcode & 0xf000) {    case 0x1000:		/* mov.l Rm,@(disp,Rn) */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_addl_imm_T1(B3_0 * 4);	gen_op_stl_T0_T1(ctx);	return;    case 0x5000:		/* mov.l @(disp,Rm),Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_addl_imm_T0(B3_0 * 4);	gen_op_ldl_T0_T0(ctx);	gen_op_movl_T0_rN(REG(B11_8));	return;    case 0xe000:		/* mov.l #imm,Rn */	gen_op_movl_imm_rN(B7_0s, REG(B11_8));	return;    case 0x9000:		/* mov.w @(disp,PC),Rn */	gen_op_movl_imm_T0(ctx->pc + 4 + B7_0 * 2);	gen_op_ldw_T0_T0(ctx);	gen_op_movl_T0_rN(REG(B11_8));	return;    case 0xd000:		/* mov.l @(disp,PC),Rn */	gen_op_movl_imm_T0((ctx->pc + 4 + B7_0 * 4) & ~3);	gen_op_ldl_T0_T0(ctx);	gen_op_movl_T0_rN(REG(B11_8));	return;    case 0x7000:		/* add.l #imm,Rn */	gen_op_add_imm_rN(B7_0s, REG(B11_8));	return;    case 0xa000:		/* bra disp */	CHECK_NOT_DELAY_SLOT	    gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);	ctx->flags |= DELAY_SLOT;	return;    case 0xb000:		/* bsr disp */	CHECK_NOT_DELAY_SLOT	    gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =		       ctx->pc + 4 + B11_0s * 2);	ctx->flags |= DELAY_SLOT;	return;    }    switch (ctx->opcode & 0xf00f) {    case 0x6003:		/* mov Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_T0_rN(REG(B11_8));	return;    case 0x2000:		/* mov.b Rm,@Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_stb_T0_T1(ctx);	return;    case 0x2001:		/* mov.w Rm,@Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_stw_T0_T1(ctx);	return;    case 0x2002:		/* mov.l Rm,@Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_stl_T0_T1(ctx);	return;    case 0x6000:		/* mov.b @Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_ldb_T0_T0(ctx);	gen_op_movl_T0_rN(REG(B11_8));	return;    case 0x6001:		/* mov.w @Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_ldw_T0_T0(ctx);	gen_op_movl_T0_rN(REG(B11_8));	return;    case 0x6002:		/* mov.l @Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_ldl_T0_T0(ctx);	gen_op_movl_T0_rN(REG(B11_8));	return;    case 0x2004:		/* mov.b Rm,@-Rn */	gen_op_dec1_rN(REG(B11_8));	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_stb_T0_T1(ctx);	return;    case 0x2005:		/* mov.w Rm,@-Rn */	gen_op_dec2_rN(REG(B11_8));	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_stw_T0_T1(ctx);	return;    case 0x2006:		/* mov.l Rm,@-Rn */	gen_op_dec4_rN(REG(B11_8));	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_stl_T0_T1(ctx);	return;    case 0x6004:		/* mov.l @Rm+,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_ldb_T0_T0(ctx);	gen_op_movl_T0_rN(REG(B11_8));	gen_op_inc1_rN(REG(B7_4));	return;    case 0x6005:		/* mov.w @Rm+,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_ldw_T0_T0(ctx);	gen_op_movl_T0_rN(REG(B11_8));	gen_op_inc2_rN(REG(B7_4));	return;    case 0x6006:		/* mov.l @Rm+,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_ldl_T0_T0(ctx);	gen_op_movl_T0_rN(REG(B11_8));	gen_op_inc4_rN(REG(B7_4));	return;    case 0x0004:		/* mov.b Rm,@(R0,Rn) */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_add_rN_T1(REG(0));	gen_op_stb_T0_T1(ctx);	return;    case 0x0005:		/* mov.w Rm,@(R0,Rn) */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_add_rN_T1(REG(0));	gen_op_stw_T0_T1(ctx);	return;    case 0x0006:		/* mov.l Rm,@(R0,Rn) */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_add_rN_T1(REG(0));	gen_op_stl_T0_T1(ctx);	return;    case 0x000c:		/* mov.b @(R0,Rm),Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_add_rN_T0(REG(0));	gen_op_ldb_T0_T0(ctx);	gen_op_movl_T0_rN(REG(B11_8));	return;    case 0x000d:		/* mov.w @(R0,Rm),Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_add_rN_T0(REG(0));	gen_op_ldw_T0_T0(ctx);	gen_op_movl_T0_rN(REG(B11_8));	return;    case 0x000e:		/* mov.l @(R0,Rm),Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_add_rN_T0(REG(0));	gen_op_ldl_T0_T0(ctx);	gen_op_movl_T0_rN(REG(B11_8));	return;    case 0x6008:		/* swap.b Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_swapb_T0();	gen_op_movl_T0_rN(REG(B11_8));	return;    case 0x6009:		/* swap.w Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_swapw_T0();	gen_op_movl_T0_rN(REG(B11_8));	return;    case 0x200d:		/* xtrct Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_xtrct_T0_T1();	gen_op_movl_T1_rN(REG(B11_8));	return;    case 0x300c:		/* add Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_add_T0_rN(REG(B11_8));	return;    case 0x300e:		/* addc Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_addc_T0_T1();	gen_op_movl_T1_rN(REG(B11_8));	return;    case 0x300f:		/* addv Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_addv_T0_T1();	gen_op_movl_T1_rN(REG(B11_8));	return;    case 0x2009:		/* and Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_and_T0_rN(REG(B11_8));	return;    case 0x3000:		/* cmp/eq Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_cmp_eq_T0_T1();	return;    case 0x3003:		/* cmp/ge Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_cmp_ge_T0_T1();	return;    case 0x3007:		/* cmp/gt Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_cmp_gt_T0_T1();	return;    case 0x3006:		/* cmp/hi Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_cmp_hi_T0_T1();	return;    case 0x3002:		/* cmp/hs Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_cmp_hs_T0_T1();	return;    case 0x200c:		/* cmp/str Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_cmp_str_T0_T1();	return;    case 0x2007:		/* div0s Rm,Rn */	printf("div0s\n");	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_div0s_T0_T1();	gen_op_movl_T1_rN(REG(B11_8));	return;    case 0x3004:		/* div1 Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_div1_T0_T1();	gen_op_movl_T1_rN(REG(B11_8));	return;    case 0x300d:		/* dmuls.l Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_dmulsl_T0_T1();	return;    case 0x3005:		/* dmulu.l Rm,Rn */	gen_op_movl_rN_T0(REG(B7_4));	gen_op_movl_rN_T1(REG(B11_8));	gen_op_dmulul_T0_T1();

⌨️ 快捷键说明

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