Use TCG for MIPS GPR moves.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4356 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									b7ef7bf225
								
							
						
					
					
						commit
						958fb4a92c
					
				@ -158,6 +158,7 @@ struct CPUMIPSState {
 | 
			
		||||
    CPUMIPSTLBContext *tlb;
 | 
			
		||||
    CPUMIPSFPUContext *fpu;
 | 
			
		||||
    uint32_t current_tc;
 | 
			
		||||
    target_ulong *current_tc_gprs;
 | 
			
		||||
 | 
			
		||||
    uint32_t SEGBITS;
 | 
			
		||||
    target_ulong SEGMask;
 | 
			
		||||
 | 
			
		||||
@ -14,8 +14,8 @@ register struct CPUMIPSState *env asm(AREG0);
 | 
			
		||||
#define T0 (env->t0)
 | 
			
		||||
#define T1 (env->t1)
 | 
			
		||||
#else
 | 
			
		||||
register target_ulong T0 asm(AREG2);
 | 
			
		||||
register target_ulong T1 asm(AREG3);
 | 
			
		||||
register target_ulong T0 asm(AREG1);
 | 
			
		||||
register target_ulong T1 asm(AREG2);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined (USE_HOST_FLOAT_REGS)
 | 
			
		||||
 | 
			
		||||
@ -422,41 +422,71 @@ enum {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* global register indices */
 | 
			
		||||
static TCGv cpu_env, current_tc_regs, cpu_T[2];
 | 
			
		||||
static TCGv cpu_env, current_tc_gprs, cpu_T[2];
 | 
			
		||||
 | 
			
		||||
/* General purpose registers moves */
 | 
			
		||||
const unsigned char *regnames[] =
 | 
			
		||||
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
 | 
			
		||||
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
 | 
			
		||||
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
 | 
			
		||||
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
 | 
			
		||||
 | 
			
		||||
/* Warning: no function for r0 register (hard wired to zero) */
 | 
			
		||||
#define GEN32(func, NAME)                        \
 | 
			
		||||
static GenOpFunc *NAME ## _table [32] = {        \
 | 
			
		||||
NULL,       NAME ## 1, NAME ## 2, NAME ## 3,     \
 | 
			
		||||
NAME ## 4,  NAME ## 5, NAME ## 6, NAME ## 7,     \
 | 
			
		||||
NAME ## 8,  NAME ## 9, NAME ## 10, NAME ## 11,   \
 | 
			
		||||
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
 | 
			
		||||
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
 | 
			
		||||
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
 | 
			
		||||
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
 | 
			
		||||
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
 | 
			
		||||
};                                               \
 | 
			
		||||
static always_inline void func(int n)            \
 | 
			
		||||
{                                                \
 | 
			
		||||
    NAME ## _table[n]();                         \
 | 
			
		||||
static inline void gen_op_load_gpr_TN(int t_index, int reg)
 | 
			
		||||
{
 | 
			
		||||
    tcg_gen_ld_tl(cpu_T[t_index], current_tc_gprs, sizeof(target_ulong) * reg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* General purpose registers moves */
 | 
			
		||||
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
 | 
			
		||||
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
 | 
			
		||||
static inline void gen_op_load_gpr_T0(int reg)
 | 
			
		||||
{
 | 
			
		||||
    gen_op_load_gpr_TN(0, reg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
 | 
			
		||||
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
 | 
			
		||||
static inline void gen_op_load_gpr_T1(int reg)
 | 
			
		||||
{
 | 
			
		||||
    gen_op_load_gpr_TN(1, reg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void gen_op_store_gpr_TN(int t_index, int reg)
 | 
			
		||||
{
 | 
			
		||||
    tcg_gen_st_tl(cpu_T[t_index], current_tc_gprs, sizeof(target_ulong) * reg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void gen_op_store_gpr_T0(int reg)
 | 
			
		||||
{
 | 
			
		||||
    gen_op_store_gpr_TN(0, reg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void gen_op_store_gpr_T1(int reg)
 | 
			
		||||
{
 | 
			
		||||
    gen_op_store_gpr_TN(1, reg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Moves to/from shadow registers */
 | 
			
		||||
GEN32(gen_op_load_srsgpr_T0, gen_op_load_srsgpr_T0_gpr);
 | 
			
		||||
GEN32(gen_op_store_T0_srsgpr, gen_op_store_T0_srsgpr_gpr);
 | 
			
		||||
static inline void gen_op_load_srsgpr_T0(int reg)
 | 
			
		||||
{
 | 
			
		||||
    int r_tmp = tcg_temp_new(TCG_TYPE_I32);
 | 
			
		||||
 | 
			
		||||
    tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
 | 
			
		||||
    tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
 | 
			
		||||
    tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
 | 
			
		||||
    tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
 | 
			
		||||
    tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
 | 
			
		||||
 | 
			
		||||
    tcg_gen_ld_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void gen_op_store_srsgpr_T0(int reg)
 | 
			
		||||
{
 | 
			
		||||
    int r_tmp = tcg_temp_new(TCG_TYPE_I32);
 | 
			
		||||
 | 
			
		||||
    tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
 | 
			
		||||
    tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
 | 
			
		||||
    tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
 | 
			
		||||
    tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
 | 
			
		||||
    tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
 | 
			
		||||
 | 
			
		||||
    tcg_gen_st_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *fregnames[] =
 | 
			
		||||
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
 | 
			
		||||
@ -634,7 +664,7 @@ do {                                                                          \
 | 
			
		||||
#define GEN_STORE_T0_REG(Rn)                                                  \
 | 
			
		||||
do {                                                                          \
 | 
			
		||||
    if (Rn != 0) {                                                            \
 | 
			
		||||
        glue(gen_op_store_T0,_gpr)(Rn);                                       \
 | 
			
		||||
        gen_op_store_gpr_T0(Rn);                                              \
 | 
			
		||||
        ctx->glue(last_T0,_store) = gen_opc_ptr;                              \
 | 
			
		||||
        ctx->glue(last_T0,_gpr) = Rn;                                         \
 | 
			
		||||
    }                                                                         \
 | 
			
		||||
@ -643,14 +673,13 @@ do {                                                                          \
 | 
			
		||||
#define GEN_STORE_T1_REG(Rn)                                                  \
 | 
			
		||||
do {                                                                          \
 | 
			
		||||
    if (Rn != 0)                                                              \
 | 
			
		||||
        glue(gen_op_store_T1,_gpr)(Rn);                                       \
 | 
			
		||||
        gen_op_store_gpr_T1(Rn);                                              \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
#define GEN_STORE_TN_SRSREG(Rn, Tn)                                           \
 | 
			
		||||
do {                                                                          \
 | 
			
		||||
    if (Rn != 0) {                                                            \
 | 
			
		||||
        glue(glue(gen_op_store_, Tn),_srsgpr)(Rn);                            \
 | 
			
		||||
    }                                                                         \
 | 
			
		||||
    if (Rn != 0)                                                              \
 | 
			
		||||
        glue(gen_op_store_srsgpr_, Tn)(Rn);                                   \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
 | 
			
		||||
@ -813,6 +842,7 @@ static always_inline void check_mips_64(DisasContext *ctx)
 | 
			
		||||
        generate_exception(ctx, EXCP_RI);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* load/store instructions. */
 | 
			
		||||
#if defined(CONFIG_USER_ONLY)
 | 
			
		||||
#define op_ldst(name)        gen_op_##name##_raw()
 | 
			
		||||
#define OP_LD_TABLE(width)
 | 
			
		||||
@ -1638,7 +1668,7 @@ static void gen_cl (DisasContext *ctx, uint32_t opc,
 | 
			
		||||
        generate_exception(ctx, EXCP_RI);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    gen_op_store_T0_gpr(rd);
 | 
			
		||||
    gen_op_store_gpr_T0(rd);
 | 
			
		||||
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1870,12 +1900,12 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
 | 
			
		||||
            return;
 | 
			
		||||
        case OPC_BLTZAL:  /* 0 < 0           */
 | 
			
		||||
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
 | 
			
		||||
            gen_op_store_T0_gpr(31);
 | 
			
		||||
            gen_op_store_gpr_T0(31);
 | 
			
		||||
            MIPS_DEBUG("bnever and link");
 | 
			
		||||
            return;
 | 
			
		||||
        case OPC_BLTZALL: /* 0 < 0 likely */
 | 
			
		||||
            GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
 | 
			
		||||
            gen_op_store_T0_gpr(31);
 | 
			
		||||
            gen_op_store_gpr_T0(31);
 | 
			
		||||
            /* Skip the instruction in the delay slot */
 | 
			
		||||
            MIPS_DEBUG("bnever, link and skip");
 | 
			
		||||
            ctx->pc += 4;
 | 
			
		||||
@ -2002,7 +2032,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
 | 
			
		||||
    ctx->btarget = btarget;
 | 
			
		||||
    if (blink > 0) {
 | 
			
		||||
        GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
 | 
			
		||||
        gen_op_store_T0_gpr(blink);
 | 
			
		||||
        gen_op_store_gpr_T0(blink);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4721,7 +4751,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
 | 
			
		||||
        gen_op_store_T0_gpr(rt);
 | 
			
		||||
        gen_op_store_gpr_T0(rt);
 | 
			
		||||
        opn = "mfc0";
 | 
			
		||||
        break;
 | 
			
		||||
    case OPC_MTC0:
 | 
			
		||||
@ -4738,7 +4768,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
 | 
			
		||||
        gen_op_store_T0_gpr(rt);
 | 
			
		||||
        gen_op_store_gpr_T0(rt);
 | 
			
		||||
        opn = "dmfc0";
 | 
			
		||||
        break;
 | 
			
		||||
    case OPC_DMTC0:
 | 
			
		||||
@ -4757,7 +4787,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
 | 
			
		||||
        }
 | 
			
		||||
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
 | 
			
		||||
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
 | 
			
		||||
        gen_op_store_T0_gpr(rd);
 | 
			
		||||
        gen_op_store_gpr_T0(rd);
 | 
			
		||||
        opn = "mftr";
 | 
			
		||||
        break;
 | 
			
		||||
    case OPC_MTTR:
 | 
			
		||||
@ -6806,8 +6836,13 @@ void fpu_dump_state(CPUState *env, FILE *f,
 | 
			
		||||
void dump_fpu (CPUState *env)
 | 
			
		||||
{
 | 
			
		||||
    if (loglevel) {
 | 
			
		||||
       fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
 | 
			
		||||
               env->PC[env->current_tc], env->HI[env->current_tc][0], env->LO[env->current_tc][0], env->hflags, env->btarget, env->bcond);
 | 
			
		||||
        fprintf(logfile,
 | 
			
		||||
                "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
 | 
			
		||||
                " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx
 | 
			
		||||
                " %04x\n",
 | 
			
		||||
                env->PC[env->current_tc], env->HI[env->current_tc][0],
 | 
			
		||||
                env->LO[env->current_tc][0], env->hflags, env->btarget,
 | 
			
		||||
                env->bcond);
 | 
			
		||||
       fpu_dump_state(env, logfile, fprintf, 0);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -6881,15 +6916,18 @@ static void mips_tcg_init(void)
 | 
			
		||||
	return;
 | 
			
		||||
 | 
			
		||||
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
 | 
			
		||||
    current_tc_regs = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG1, "current_tc_regs");
 | 
			
		||||
    current_tc_gprs = tcg_global_mem_new(TCG_TYPE_PTR,
 | 
			
		||||
                                         TCG_AREG0,
 | 
			
		||||
                                         offsetof(CPUState, current_tc_gprs),
 | 
			
		||||
                                         "current_tc_gprs");
 | 
			
		||||
#if TARGET_LONG_BITS > HOST_LONG_BITS
 | 
			
		||||
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
 | 
			
		||||
                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
 | 
			
		||||
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
 | 
			
		||||
                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
 | 
			
		||||
#else
 | 
			
		||||
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T0");
 | 
			
		||||
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T1");
 | 
			
		||||
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
 | 
			
		||||
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    inited = 1;
 | 
			
		||||
 | 
			
		||||
@ -543,6 +543,8 @@ static int cpu_mips_register (CPUMIPSState *env, const mips_def_t *def)
 | 
			
		||||
    env->CP0_Status_rw_bitmask = def->CP0_Status_rw_bitmask;
 | 
			
		||||
    env->CP0_TCStatus_rw_bitmask = def->CP0_TCStatus_rw_bitmask;
 | 
			
		||||
    env->CP0_SRSCtl = def->CP0_SRSCtl;
 | 
			
		||||
    env->current_tc = 0;
 | 
			
		||||
    env->current_tc_gprs = &env->gpr[env->current_tc][0];
 | 
			
		||||
    env->SEGBITS = def->SEGBITS;
 | 
			
		||||
    env->SEGMask = (target_ulong)((1ULL << def->SEGBITS) - 1);
 | 
			
		||||
#if defined(TARGET_MIPS64)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user