summaryrefslogtreecommitdiff
path: root/target-mips/translate.c
diff options
context:
space:
mode:
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-02-28 22:37:42 +0000
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-02-28 22:37:42 +0000
commit36d239587370c6ccfc53d7f6acc624ce5d61fe84 (patch)
tree43d11aaf52a198b5544bbb7e878c6cb633dec299 /target-mips/translate.c
parent54d43f70e3b003b5f24ef30ea361e034c2813d9f (diff)
downloadqemu-36d239587370c6ccfc53d7f6acc624ce5d61fe84.tar.gz
qemu-36d239587370c6ccfc53d7f6acc624ce5d61fe84.tar.bz2
qemu-36d239587370c6ccfc53d7f6acc624ce5d61fe84.zip
MIPS FPU dynamic activation, part 1, by Herve Poussineau.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2463 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r--target-mips/translate.c134
1 files changed, 60 insertions, 74 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 7576fa3b38..5a77e906f1 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -391,8 +391,6 @@ GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
-#ifdef MIPS_USES_FPU
-
static const char *fregnames[] =
{ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
@@ -476,8 +474,6 @@ static inline void gen_cmp_ ## fmt(int n) \
FOP_CONDS(d)
FOP_CONDS(s)
-#endif /* MIPS_USES_FPU */
-
typedef struct DisasContext {
struct TranslationBlock *tb;
target_ulong pc, saved_pc;
@@ -640,12 +636,10 @@ OP_LD_TABLE(bu);
OP_ST_TABLE(b);
OP_LD_TABLE(l);
OP_ST_TABLE(c);
-#ifdef MIPS_USES_FPU
OP_LD_TABLE(wc1);
OP_ST_TABLE(wc1);
OP_LD_TABLE(dc1);
OP_ST_TABLE(dc1);
-#endif
/* Load and store */
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
@@ -794,8 +788,6 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
}
-#ifdef MIPS_USES_FPU
-
/* Load and store */
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
int base, int16_t offset)
@@ -843,8 +835,6 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
}
-#endif /* MIPS_USES_FPU */
-
/* Arithmetic with immediate operand */
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
int rs, int16_t imm)
@@ -4111,8 +4101,6 @@ static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
}
-#ifdef MIPS_USES_FPU
-
/* CP1 Branches (before delay slot) */
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
int32_t offset)
@@ -4531,8 +4519,6 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
gen_op_movt(ccbit, rd, rs);
}
-#endif /* MIPS_USES_FPU */
-
/* ISA extensions (ASEs) */
/* MIPS16 extension to MIPS32 */
/* SmartMIPS extension to MIPS32 */
@@ -4555,7 +4541,7 @@ static void gen_blikely(DisasContext *ctx)
gen_set_label(l1);
}
-static void decode_opc (DisasContext *ctx)
+static void decode_opc (CPUState *env, DisasContext *ctx)
{
int32_t offset;
int rs, rt, rd, sa;
@@ -4631,13 +4617,15 @@ static void decode_opc (DisasContext *ctx)
/* Treat as a noop. */
break;
-#ifdef MIPS_USES_FPU
case OPC_MOVCI:
- gen_op_cp1_enabled();
- gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
- (ctx->opcode >> 16) & 1);
+ if (env->CP0_Config1 & (1 << CP0C1_FP)) {
+ gen_op_cp1_enabled();
+ gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
+ (ctx->opcode >> 16) & 1);
+ } else {
+ generate_exception(ctx, EXCP_RI);
+ }
break;
-#endif
#ifdef MIPS_HAS_MIPS64
/* MIPS64 specific opcodes */
@@ -4868,47 +4856,47 @@ static void decode_opc (DisasContext *ctx)
case OPC_LDC1:
case OPC_SWC1:
case OPC_SDC1:
-#if defined(MIPS_USES_FPU)
- save_cpu_state(ctx, 1);
- gen_op_cp1_enabled();
- gen_flt_ldst(ctx, op, rt, rs, imm);
-#else
- generate_exception_err(ctx, EXCP_CpU, 1);
-#endif
+ if (env->CP0_Config1 & (1 << CP0C1_FP)) {
+ save_cpu_state(ctx, 1);
+ gen_op_cp1_enabled();
+ gen_flt_ldst(ctx, op, rt, rs, imm);
+ } else {
+ generate_exception_err(ctx, EXCP_CpU, 1);
+ }
break;
case OPC_CP1:
-#if defined(MIPS_USES_FPU)
- save_cpu_state(ctx, 1);
- gen_op_cp1_enabled();
- op1 = MASK_CP1(ctx->opcode);
- switch (op1) {
- case OPC_MFC1:
- case OPC_CFC1:
- case OPC_MTC1:
- case OPC_CTC1:
+ if (env->CP0_Config1 & (1 << CP0C1_FP)) {
+ save_cpu_state(ctx, 1);
+ gen_op_cp1_enabled();
+ op1 = MASK_CP1(ctx->opcode);
+ switch (op1) {
+ case OPC_MFC1:
+ case OPC_CFC1:
+ case OPC_MTC1:
+ case OPC_CTC1:
#ifdef MIPS_HAS_MIPS64
- case OPC_DMFC1:
- case OPC_DMTC1:
+ case OPC_DMFC1:
+ case OPC_DMTC1:
#endif
- gen_cp1(ctx, op1, rt, rd);
- break;
- case OPC_BC1:
- gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2);
- return;
- case OPC_S_FMT:
- case OPC_D_FMT:
- case OPC_W_FMT:
- case OPC_L_FMT:
- gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa);
- break;
- default:
- generate_exception_err(ctx, EXCP_RI, 1);
- break;
+ gen_cp1(ctx, op1, rt, rd);
+ break;
+ case OPC_BC1:
+ gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2);
+ return;
+ case OPC_S_FMT:
+ case OPC_D_FMT:
+ case OPC_W_FMT:
+ case OPC_L_FMT:
+ gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa);
+ break;
+ default:
+ generate_exception_err(ctx, EXCP_RI, 1);
+ break;
+ }
+ } else {
+ generate_exception_err(ctx, EXCP_CpU, 1);
}
-#else
- generate_exception_err(ctx, EXCP_CpU, 1);
-#endif
break;
/* COP2. */
@@ -4921,18 +4909,20 @@ static void decode_opc (DisasContext *ctx)
generate_exception_err(ctx, EXCP_CpU, 2);
break;
-#ifdef MIPS_USES_FPU
case OPC_CP3:
- gen_op_cp1_enabled();
- op1 = MASK_CP3(ctx->opcode);
- switch (op1) {
- /* Not implemented */
- default:
- generate_exception_err(ctx, EXCP_RI, 1);
- break;
+ if (env->CP0_Config1 & (1 << CP0C1_FP)) {
+ gen_op_cp1_enabled();
+ op1 = MASK_CP3(ctx->opcode);
+ switch (op1) {
+ /* Not implemented */
+ default:
+ generate_exception_err(ctx, EXCP_RI, 1);
+ break;
+ }
+ } else {
+ generate_exception(ctx, EXCP_RI);
}
break;
-#endif
#ifdef MIPS_HAS_MIPS64
/* MIPS64 opcodes */
@@ -5079,7 +5069,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
gen_opc_instr_start[lj] = 1;
}
ctx.opcode = ldl_code(ctx.pc);
- decode_opc(&ctx);
+ decode_opc(env, &ctx);
ctx.pc += 4;
if (env->singlestep_enabled)
@@ -5148,8 +5138,6 @@ int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
return gen_intermediate_code_internal(env, tb, 1);
}
-#ifdef MIPS_USES_FPU
-
void fpu_dump_state(CPUState *env, FILE *f,
int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
int flags)
@@ -5184,8 +5172,6 @@ void dump_fpu (CPUState *env)
}
}
-#endif /* MIPS_USES_FPU */
-
#if defined(MIPS_HAS_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
/* Debug help: The architecture requires 32bit code to maintain proper
sign-extened values on 64bit machines. */
@@ -5248,10 +5234,8 @@ void cpu_dump_state (CPUState *env, FILE *f,
c0_status, env->CP0_Cause, env->CP0_EPC);
cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
-#ifdef MIPS_USES_FPU
if (c0_status & (1 << CP0St_CU1))
fpu_dump_state(env, f, cpu_fprintf, flags);
-#endif
#if defined(MIPS_HAS_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
#endif
@@ -5295,6 +5279,10 @@ void cpu_reset (CPUMIPSState *env)
env->CP0_EBase = 0x80000000;
env->CP0_Config0 = MIPS_CONFIG0;
env->CP0_Config1 = MIPS_CONFIG1;
+#ifdef MIPS_USES_FPU
+ /* basic FPU register support */
+ env->CP0_Config1 |= (1 << CP0C1_FP);
+#endif
env->CP0_Config2 = MIPS_CONFIG2;
env->CP0_Config3 = MIPS_CONFIG3;
env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
@@ -5309,9 +5297,7 @@ void cpu_reset (CPUMIPSState *env)
env->hflags |= MIPS_HFLAG_UM;
env->user_mode_only = 1;
#endif
-#ifdef MIPS_USES_FPU
- env->fcr0 = MIPS_FCR0;
-#endif
+ env->fcr0 = MIPS_FCR0;
/* XXX some guesswork here, values are CPU specific */
env->SYNCI_Step = 16;
env->CCRes = 2;