* [Qemu-devel] [PATCH] MIPS FPU dynamic activation, part 1
@ 2007-02-25 20:30 Hervé Poussineau
2007-02-27 18:31 ` Stefan Weil
0 siblings, 1 reply; 2+ messages in thread
From: Hervé Poussineau @ 2007-02-25 20:30 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 387 bytes --]
Hi,
This patch remove (most of) the use of the #define MIPS_USES_FPU, and
replaces it with a check of the FP bit in the config1 register.
The only place where MIPS_USES_FPU is still used is when resetting a CPU, to
set (or not) the FP bit.
In a latter patch, this bit may be dynamically enabled according to some
condition, as a command line switch or the CPU model.
Hervé
[-- Attachment #2: fpu.diff --]
[-- Type: application/octet-stream, Size: 17511 bytes --]
Index: exec-all.h
===================================================================
RCS file: /cvsroot/qemu/qemu/exec-all.h,v
retrieving revision 1.49
diff -u -r1.49 exec-all.h
--- exec-all.h 12 Nov 2006 20:40:55 -0000 1.49
+++ exec-all.h 25 Feb 2007 20:08:31 -0000
@@ -581,13 +581,12 @@
}
pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK;
if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
- cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x%08lx\n", addr);
+ cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr);
}
return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base;
}
#endif
-
#ifdef USE_KQEMU
#define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG))
Index: gdbstub.c
===================================================================
RCS file: /cvsroot/qemu/qemu/gdbstub.c,v
retrieving revision 1.48
diff -u -r1.48 gdbstub.c
--- gdbstub.c 22 Feb 2007 01:48:01 -0000 1.48
+++ gdbstub.c 25 Feb 2007 20:08:31 -0000
@@ -568,19 +568,20 @@
*(uint32_t *)ptr = tswapl(env->PC);
ptr += 4;
-#ifdef MIPS_USES_FPU
- for (i = 0; i < 32; i++)
+ if (env->CP0_Config1 & (1 << CP0C1_FP))
{
- *(uint32_t *)ptr = tswapl(FPR_W (env, i));
- ptr += 4;
- }
+ for (i = 0; i < 32; i++)
+ {
+ *(uint32_t *)ptr = tswapl(FPR_W (env, i));
+ ptr += 4;
+ }
- *(uint32_t *)ptr = tswapl(env->fcr31);
- ptr += 4;
+ *(uint32_t *)ptr = tswapl(env->fcr31);
+ ptr += 4;
- *(uint32_t *)ptr = tswapl(env->fcr0);
- ptr += 4;
-#endif
+ *(uint32_t *)ptr = tswapl(env->fcr0);
+ ptr += 4;
+ }
/* 32 FP registers, fsr, fir, fp. Not yet implemented. */
/* what's 'fp' mean here? */
@@ -629,27 +630,28 @@
env->PC = tswapl(*(uint32_t *)ptr);
ptr += 4;
-#ifdef MIPS_USES_FPU
- for (i = 0; i < 32; i++)
+ if (env->CP0_Config1 & (1 << CP0C1_FP))
{
- FPR_W (env, i) = tswapl(*(uint32_t *)ptr);
- ptr += 4;
- }
+ for (i = 0; i < 32; i++)
+ {
+ FPR_W (env, i) = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
+ }
- env->fcr31 = tswapl(*(uint32_t *)ptr) & 0x0183FFFF;
- ptr += 4;
+ env->fcr31 = tswapl(*(uint32_t *)ptr) & 0x0183FFFF;
+ ptr += 4;
- env->fcr0 = tswapl(*(uint32_t *)ptr);
- ptr += 4;
+ env->fcr0 = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
- /* set rounding mode */
- RESTORE_ROUNDING_MODE;
+ /* set rounding mode */
+ RESTORE_ROUNDING_MODE;
#ifndef CONFIG_SOFTFLOAT
- /* no floating point exception for native float */
- SET_FP_ENABLE(env->fcr31, 0);
-#endif
+ /* no floating point exception for native float */
+ SET_FP_ENABLE(env->fcr31, 0);
#endif
+ }
}
#elif defined (TARGET_SH4)
static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
Index: linux-user/main.c
===================================================================
RCS file: /cvsroot/qemu/qemu/linux-user/main.c,v
retrieving revision 1.98
diff -u -r1.98 main.c
--- linux-user/main.c 5 Feb 2007 20:21:32 -0000 1.98
+++ linux-user/main.c 25 Feb 2007 20:08:37 -0000
@@ -1838,9 +1838,9 @@
env->gpr[i] = regs->regs[i];
}
env->PC = regs->cp0_epc;
-#ifdef MIPS_USES_FPU
- env->CP0_Status |= (1 << CP0St_CU1);
-#endif
+ if (env->CP0_Config1 & (1 << CP0C1_FP)) {
+ env->CP0_Status |= (1 << CP0St_CU1);
+ }
}
#elif defined(TARGET_SH4)
{
Index: target-mips/cpu.h
===================================================================
RCS file: /cvsroot/qemu/qemu/target-mips/cpu.h,v
retrieving revision 1.21
diff -u -r1.21 cpu.h
--- target-mips/cpu.h 20 Feb 2007 23:37:21 -0000 1.21
+++ target-mips/cpu.h 25 Feb 2007 20:08:38 -0000
@@ -63,7 +63,6 @@
#endif
target_ulong HI, LO;
uint32_t DCR; /* ? */
-#if defined(MIPS_USES_FPU)
/* Floating point registers */
fpr_t fpr[16];
#define FPR(cpu, n) ((fpr_t*)&(cpu)->fpr[(n) / 2])
@@ -97,8 +96,7 @@
#define FP_DIV0 8
#define FP_INVALID 16
#define FP_UNIMPLEMENTED 32
-
-#endif
+
#if defined(MIPS_USES_R4K_TLB)
tlb_t tlb[MIPS_TLB_MAX];
uint32_t tlb_in_use;
Index: target-mips/exec.h
===================================================================
RCS file: /cvsroot/qemu/qemu/target-mips/exec.h,v
retrieving revision 1.17
diff -u -r1.17 exec.h
--- target-mips/exec.h 2 Feb 2007 01:03:34 -0000 1.17
+++ target-mips/exec.h 25 Feb 2007 20:08:38 -0000
@@ -115,12 +115,10 @@
void do_tlbwr (void);
void do_tlbp (void);
void do_tlbr (void);
-#ifdef MIPS_USES_FPU
void dump_fpu(CPUState *env);
void fpu_dump_state(CPUState *env, FILE *f,
int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
int flags);
-#endif
void dump_sc (void);
void do_lwl_raw (uint32_t);
void do_lwr_raw (uint32_t);
Index: target-mips/mips-defs.h
===================================================================
RCS file: /cvsroot/qemu/qemu/target-mips/mips-defs.h,v
retrieving revision 1.6
diff -u -r1.6 mips-defs.h
--- target-mips/mips-defs.h 21 Dec 2006 01:19:56 -0000 1.6
+++ target-mips/mips-defs.h 25 Feb 2007 20:08:38 -0000
@@ -45,19 +45,14 @@
2-way Icache, 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache,
no coprocessor2 attached, no MDMX support attached,
no performance counters, watch registers present,
- no code compression, EJTAG present, FPU enable bit depending on
- MIPS_USES_FPU */
-#define MIPS_CONFIG1_1 \
+ no code compression, EJTAG present, no FPU */
+#define MIPS_CONFIG1 \
((1 << CP0C1_M) | ((MIPS_TLB_NB - 1) << CP0C1_MMU) | \
(0x0 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x1 << CP0C1_IA) | \
(0x0 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x1 << CP0C1_DA) | \
(0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \
- (1 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP))
-#ifdef MIPS_USES_FPU
-#define MIPS_CONFIG1 (MIPS_CONFIG1_1 | (1 << CP0C1_FP))
-#else
-#define MIPS_CONFIG1 (MIPS_CONFIG1_1 | (0 << CP0C1_FP))
-#endif
+ (1 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP) | \
+ (0 << CP0C1_FP))
/* Have config3, no tertiary/secondary caches implemented */
#define MIPS_CONFIG2 \
((1 << CP0C2_M))
Index: target-mips/op.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-mips/op.c,v
retrieving revision 1.23
diff -u -r1.23 op.c
--- target-mips/op.c 18 Feb 2007 00:19:08 -0000 1.23
+++ target-mips/op.c 25 Feb 2007 20:08:39 -0000
@@ -144,8 +144,6 @@
#include "op_template.c"
#undef TN
-#ifdef MIPS_USES_FPU
-
#define SFREG 0
#define DFREG 0
#include "fop_template.c"
@@ -279,8 +277,6 @@
#include "fop_template.c"
#undef FTN
-#endif
-
void op_dup_T0 (void)
{
T2 = T0;
@@ -924,7 +920,6 @@
RETURN();
}
-#ifdef MIPS_USES_FPU
void op_movf (void)
{
if (!(env->fcr31 & PARAM1))
@@ -938,7 +933,6 @@
env->gpr[PARAM2] = env->gpr[PARAM3];
RETURN();
}
-#endif
/* Tests */
#define OP_COND(name, cond) \
@@ -1645,8 +1639,6 @@
RETURN();
}
-#ifdef MIPS_USES_FPU
-
#if 0
# define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
#else
@@ -2001,7 +1993,6 @@
DEBUG_FPU_STATE();
RETURN();
}
-#endif /* MIPS_USES_FPU */
#if defined(MIPS_USES_R4K_TLB)
void op_tlbwi (void)
Index: target-mips/op_helper.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-mips/op_helper.c,v
retrieving revision 1.30
diff -u -r1.30 op_helper.c
--- target-mips/op_helper.c 20 Feb 2007 23:37:21 -0000 1.30
+++ target-mips/op_helper.c 25 Feb 2007 20:08:39 -0000
@@ -331,7 +331,6 @@
fprintf(logfile, "Raise pending IRQs\n");
}
-#ifdef MIPS_USES_FPU
#include "softfloat.h"
void fpu_handle_exception(void)
@@ -370,7 +369,6 @@
SET_FP_CAUSE(env->fcr31, 0);
#endif
}
-#endif /* MIPS_USES_FPU */
/* TLB management */
#if defined(MIPS_USES_R4K_TLB)
Index: target-mips/op_mem.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-mips/op_mem.c,v
retrieving revision 1.5
diff -u -r1.5 op_mem.c
--- target-mips/op_mem.c 21 Dec 2006 01:19:56 -0000 1.5
+++ target-mips/op_mem.c 25 Feb 2007 20:08:39 -0000
@@ -192,7 +192,6 @@
}
#endif /* MIPS_HAS_MIPS64 */
-#ifdef MIPS_USES_FPU
void glue(op_lwc1, MEMSUFFIX) (void)
{
WT0 = glue(ldl, MEMSUFFIX)(T0);
@@ -213,4 +212,3 @@
glue(stq, MEMSUFFIX)(T0, DT0);
RETURN();
}
-#endif
Index: target-mips/translate.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-mips/translate.c,v
retrieving revision 1.33
diff -u -r1.33 translate.c
--- target-mips/translate.c 20 Feb 2007 23:37:21 -0000 1.33
+++ target-mips/translate.c 25 Feb 2007 20:08:41 -0000
@@ -391,8 +391,6 @@
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 @@
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_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 @@
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 @@
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 @@
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)
@@ -4544,8 +4532,6 @@
gen_op_movt(ccbit, rd, rs);
}
-#endif /* MIPS_USES_FPU */
-
/* ISA extensions (ASEs) */
/* MIPS16 extension to MIPS32 */
/* SmartMIPS extension to MIPS32 */
@@ -4568,7 +4554,7 @@
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;
@@ -4644,13 +4630,15 @@
/* 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 */
@@ -4881,47 +4869,47 @@
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. */
@@ -4934,18 +4922,20 @@
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 */
@@ -5092,7 +5082,7 @@
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)
@@ -5161,8 +5151,6 @@
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)
@@ -5197,8 +5185,6 @@
}
}
-#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. */
@@ -5261,10 +5247,8 @@
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
@@ -5308,6 +5292,10 @@
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);
@@ -5322,9 +5310,7 @@
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;
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [Qemu-devel] [PATCH] MIPS FPU dynamic activation, part 1
2007-02-25 20:30 [Qemu-devel] [PATCH] MIPS FPU dynamic activation, part 1 Hervé Poussineau
@ 2007-02-27 18:31 ` Stefan Weil
0 siblings, 0 replies; 2+ messages in thread
From: Stefan Weil @ 2007-02-27 18:31 UTC (permalink / raw)
To: qemu-devel
It would be great to see Hervé's patch in CVS HEAD.
There are already emulated MIPS machines with and without
FPU today, so removing the need for different binaries
is a good idea.
Stefan
Hervé Poussineau schrieb:
> Hi,
>
> This patch remove (most of) the use of the #define MIPS_USES_FPU, and
> replaces it with a check of the FP bit in the config1 register.
> The only place where MIPS_USES_FPU is still used is when resetting a
> CPU, to
> set (or not) the FP bit.
>
> In a latter patch, this bit may be dynamically enabled according to some
> condition, as a command line switch or the CPU model.
>
> Hervé
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Qemu-devel mailing list
> Qemu-devel@nongnu.org
> http://lists.nongnu.org/mailman/listinfo/qemu-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-02-27 18:31 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-02-25 20:30 [Qemu-devel] [PATCH] MIPS FPU dynamic activation, part 1 Hervé Poussineau
2007-02-27 18:31 ` Stefan Weil
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).