target-sh4: map FP registers as TCG variables

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5758 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
aurel32 2008-11-19 18:00:47 +00:00
parent 9850d1e82c
commit 66ba317c90

View File

@ -72,6 +72,7 @@ static TCGv cpu_gregs[24];
static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr;
static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_flags;
static TCGv cpu_fregs[32];
/* internal register indexes */
static TCGv cpu_flags, cpu_delayed_pc;
@ -89,6 +90,16 @@ static void sh4_translate_init(void)
"R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
"R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
};
static const char * const fregnames[32] = {
"FPR0_BANK0", "FPR1_BANK0", "FPR2_BANK0", "FPR3_BANK0",
"FPR4_BANK0", "FPR5_BANK0", "FPR6_BANK0", "FPR7_BANK0",
"FPR8_BANK0", "FPR9_BANK0", "FPR10_BANK0", "FPR11_BANK0",
"FPR12_BANK0", "FPR13_BANK0", "FPR14_BANK0", "FPR15_BANK0",
"FPR0_BANK1", "FPR1_BANK1", "FPR2_BANK1", "FPR3_BANK1",
"FPR4_BANK1", "FPR5_BANK1", "FPR6_BANK1", "FPR7_BANK1",
"FPR8_BANK1", "FPR9_BANK1", "FPR10_BANK1", "FPR11_BANK1",
"FPR12_BANK1", "FPR13_BANK1", "FPR14_BANK1", "FPR15_BANK1",
};
if (done_init)
return;
@ -97,8 +108,8 @@ static void sh4_translate_init(void)
for (i = 0; i < 24; i++)
cpu_gregs[i] = tcg_global_mem_new_i32(TCG_AREG0,
offsetof(CPUState, gregs[i]),
gregnames[i]);
offsetof(CPUState, gregs[i]),
gregnames[i]);
cpu_pc = tcg_global_mem_new_i32(TCG_AREG0,
offsetof(CPUState, pc), "PC");
@ -133,6 +144,11 @@ static void sh4_translate_init(void)
offsetof(CPUState, delayed_pc),
"_delayed_pc_");
for (i = 0; i < 32; i++)
cpu_fregs[i] = tcg_global_mem_new_i32(TCG_AREG0,
offsetof(CPUState, fregs[i]),
fregnames[i]);
/* register helpers */
#define GEN_HELPER 2
#include "helper.h"
@ -393,38 +409,19 @@ static inline void gen_copy_bit_i32(TCGv t0, int p0, TCGv t1, int p1)
tcg_temp_free(tmp);
}
static inline void gen_load_fpr32(TCGv_i32 t, int reg)
{
tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, fregs[reg]));
}
static inline void gen_load_fpr64(TCGv_i64 t, int reg)
{
TCGv_i32 tmp1 = tcg_temp_new_i32();
TCGv_i32 tmp2 = tcg_temp_new_i32();
tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg]));
tcg_gen_ld_i32(tmp2, cpu_env, offsetof(CPUState, fregs[reg + 1]));
tcg_gen_concat_i32_i64(t, tmp2, tmp1);
tcg_temp_free_i32(tmp1);
tcg_temp_free_i32(tmp2);
}
static inline void gen_store_fpr32(TCGv_i32 t, int reg)
{
tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, fregs[reg]));
tcg_gen_concat_i32_i64(t, cpu_fregs[reg + 1], cpu_fregs[reg]);
}
static inline void gen_store_fpr64 (TCGv_i64 t, int reg)
{
TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_trunc_i64_i32(tmp, t);
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, fregs[reg + 1]));
tcg_gen_mov_i32(cpu_fregs[reg + 1], tmp);
tcg_gen_shri_i64(t, t, 32);
tcg_gen_trunc_i64_i32(tmp, t);
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, fregs[reg]));
tcg_gen_mov_i32(cpu_fregs[reg], tmp);
tcg_temp_free_i32(tmp);
}
@ -989,10 +986,7 @@ static void _decode_opc(DisasContext * ctx)
gen_store_fpr64(fp, XREG(B11_8));
tcg_temp_free_i64(fp);
} else {
TCGv_i32 fp = tcg_temp_new_i32();
gen_load_fpr32(fp, FREG(B7_4));
gen_store_fpr32(fp, FREG(B11_8));
tcg_temp_free_i32(fp);
tcg_gen_mov_i32(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
}
return;
case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
@ -1002,10 +996,7 @@ static void _decode_opc(DisasContext * ctx)
tcg_gen_qemu_st64(fp, REG(B11_8), ctx->memidx);
tcg_temp_free_i64(fp);
} else {
TCGv_i32 fp = tcg_temp_new_i32();
gen_load_fpr32(fp, FREG(B7_4));
tcg_gen_qemu_st32(fp, REG(B11_8), ctx->memidx);
tcg_temp_free_i32(fp);
tcg_gen_qemu_st32(cpu_fregs[FREG(B7_4)], REG(B11_8), ctx->memidx);
}
return;
case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
@ -1015,10 +1006,7 @@ static void _decode_opc(DisasContext * ctx)
gen_store_fpr64(fp, XREG(B11_8));
tcg_temp_free_i64(fp);
} else {
TCGv_i32 fp = tcg_temp_new_i32();
tcg_gen_qemu_ld32u(fp, REG(B7_4), ctx->memidx);
gen_store_fpr32(fp, FREG(B11_8));
tcg_temp_free_i32(fp);
tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], REG(B7_4), ctx->memidx);
}
return;
case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
@ -1029,10 +1017,7 @@ static void _decode_opc(DisasContext * ctx)
tcg_temp_free_i64(fp);
tcg_gen_addi_i32(REG(B7_4),REG(B7_4), 8);
} else {
TCGv_i32 fp = tcg_temp_new_i32();
tcg_gen_qemu_ld32u(fp, REG(B7_4), ctx->memidx);
gen_store_fpr32(fp, FREG(B11_8));
tcg_temp_free_i32(fp);
tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], REG(B7_4), ctx->memidx);
tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
}
return;
@ -1050,13 +1035,9 @@ static void _decode_opc(DisasContext * ctx)
tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 8);
} else {
TCGv addr;
TCGv_i32 fp;
addr = tcg_temp_new_i32();
tcg_gen_subi_i32(addr, REG(B11_8), 4);
fp = tcg_temp_new_i32();
gen_load_fpr32(fp, FREG(B7_4));
tcg_gen_qemu_st32(fp, addr, ctx->memidx);
tcg_temp_free_i32(fp);
tcg_gen_qemu_st32(cpu_fregs[FREG(B7_4)], addr, ctx->memidx);
tcg_temp_free(addr);
tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
}
@ -1071,10 +1052,7 @@ static void _decode_opc(DisasContext * ctx)
gen_store_fpr64(fp, XREG(B11_8));
tcg_temp_free_i64(fp);
} else {
TCGv_i32 fp = tcg_temp_new_i32();
tcg_gen_qemu_ld32u(fp, addr, ctx->memidx);
gen_store_fpr32(fp, FREG(B11_8));
tcg_temp_free_i32(fp);
tcg_gen_qemu_ld32u(cpu_fregs[FREG(B11_8)], addr, ctx->memidx);
}
tcg_temp_free(addr);
}
@ -1089,10 +1067,7 @@ static void _decode_opc(DisasContext * ctx)
tcg_gen_qemu_st64(fp, addr, ctx->memidx);
tcg_temp_free_i64(fp);
} else {
TCGv_i32 fp = tcg_temp_new_i32();
gen_load_fpr32(fp, FREG(B7_4));
tcg_gen_qemu_st32(fp, addr, ctx->memidx);
tcg_temp_free_i32(fp);
tcg_gen_qemu_st32(cpu_fregs[FREG(B7_4)], addr, ctx->memidx);
}
tcg_temp_free(addr);
}
@ -1137,36 +1112,26 @@ static void _decode_opc(DisasContext * ctx)
tcg_temp_free_i64(fp0);
tcg_temp_free_i64(fp1);
} else {
TCGv_i32 fp0, fp1;
fp0 = tcg_temp_new_i32();
fp1 = tcg_temp_new_i32();
gen_load_fpr32(fp0, FREG(B11_8));
gen_load_fpr32(fp1, FREG(B7_4));
switch (ctx->opcode & 0xf00f) {
case 0xf000: /* fadd Rm,Rn */
gen_helper_fadd_FT(fp0, fp0, fp1);
gen_helper_fadd_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
break;
case 0xf001: /* fsub Rm,Rn */
gen_helper_fsub_FT(fp0, fp0, fp1);
gen_helper_fsub_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
break;
case 0xf002: /* fmul Rm,Rn */
gen_helper_fmul_FT(fp0, fp0, fp1);
gen_helper_fmul_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
break;
case 0xf003: /* fdiv Rm,Rn */
gen_helper_fdiv_FT(fp0, fp0, fp1);
gen_helper_fdiv_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
break;
case 0xf004: /* fcmp/eq Rm,Rn */
gen_helper_fcmp_eq_FT(fp0, fp1);
gen_helper_fcmp_eq_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
return;
case 0xf005: /* fcmp/gt Rm,Rn */
gen_helper_fcmp_gt_FT(fp0, fp1);
gen_helper_fcmp_gt_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
return;
}
gen_store_fpr32(fp0, FREG(B11_8));
tcg_temp_free_i32(fp0);
tcg_temp_free_i32(fp1);
}
}
return;
@ -1633,18 +1598,12 @@ static void _decode_opc(DisasContext * ctx)
return;
case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
{
TCGv fp = tcg_temp_new();
tcg_gen_mov_i32(fp, cpu_fpul);
gen_store_fpr32(fp, FREG(B11_8));
tcg_temp_free(fp);
tcg_gen_mov_i32(cpu_fregs[FREG(B11_8)], cpu_fpul);
}
return;
case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
{
TCGv fp = tcg_temp_new();
gen_load_fpr32(fp, FREG(B11_8));
tcg_gen_mov_i32(cpu_fpul, fp);
tcg_temp_free(fp);
tcg_gen_mov_i32(cpu_fpul, cpu_fregs[FREG(B11_8)]);
}
return;
case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
@ -1658,10 +1617,7 @@ static void _decode_opc(DisasContext * ctx)
tcg_temp_free_i64(fp);
}
else {
TCGv_i32 fp = tcg_temp_new_i32();
gen_helper_float_FT(fp, cpu_fpul);
gen_store_fpr32(fp, FREG(B11_8));
tcg_temp_free_i32(fp);
gen_helper_float_FT(cpu_fregs[FREG(B11_8)], cpu_fpul);
}
return;
case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
@ -1675,19 +1631,12 @@ static void _decode_opc(DisasContext * ctx)
tcg_temp_free_i64(fp);
}
else {
TCGv_i32 fp = tcg_temp_new_i32();
gen_load_fpr32(fp, FREG(B11_8));
gen_helper_ftrc_FT(cpu_fpul, fp);
tcg_temp_free_i32(fp);
gen_helper_ftrc_FT(cpu_fpul, cpu_fregs[FREG(B11_8)]);
}
return;
case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
{
TCGv_i32 fp = tcg_temp_new_i32();
gen_load_fpr32(fp, FREG(B11_8));
gen_helper_fneg_T(fp, fp);
gen_store_fpr32(fp, FREG(B11_8));
tcg_temp_free_i32(fp);
gen_helper_fneg_T(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)]);
}
return;
case 0xf05d: /* fabs FRn/DRn */
@ -1700,11 +1649,7 @@ static void _decode_opc(DisasContext * ctx)
gen_store_fpr64(fp, DREG(B11_8));
tcg_temp_free_i64(fp);
} else {
TCGv_i32 fp = tcg_temp_new_i32();
gen_load_fpr32(fp, FREG(B11_8));
gen_helper_fabs_FT(fp, fp);
gen_store_fpr32(fp, FREG(B11_8));
tcg_temp_free_i32(fp);
gen_helper_fabs_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)]);
}
return;
case 0xf06d: /* fsqrt FRn */
@ -1717,28 +1662,20 @@ static void _decode_opc(DisasContext * ctx)
gen_store_fpr64(fp, DREG(B11_8));
tcg_temp_free_i64(fp);
} else {
TCGv_i32 fp = tcg_temp_new_i32();
gen_load_fpr32(fp, FREG(B11_8));
gen_helper_fsqrt_FT(fp, fp);
gen_store_fpr32(fp, FREG(B11_8));
tcg_temp_free_i32(fp);
gen_helper_fsqrt_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)]);
}
return;
case 0xf07d: /* fsrra FRn */
break;
case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
if (!(ctx->fpscr & FPSCR_PR)) {
TCGv_i32 val = tcg_const_i32(0);
gen_load_fpr32(val, FREG(B11_8));
tcg_temp_free_i32(val);
tcg_gen_movi_i32(cpu_fregs[FREG(B11_8)], 0);
return;
}
break;
case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
if (!(ctx->fpscr & FPSCR_PR)) {
TCGv_i32 val = tcg_const_i32(0x3f800000);
gen_load_fpr32(val, FREG(B11_8));
tcg_temp_free_i32(val);
tcg_gen_movi_i32(cpu_fregs[FREG(B11_8)], 0x3f800000);
return;
}
break;