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
This commit is contained in:
parent
54d43f70e3
commit
36d2395873
@ -581,13 +581,12 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
|
|||||||
}
|
}
|
||||||
pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK;
|
pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK;
|
||||||
if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
|
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;
|
return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_KQEMU
|
#ifdef USE_KQEMU
|
||||||
#define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG))
|
#define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG))
|
||||||
|
|
||||||
|
50
gdbstub.c
50
gdbstub.c
@ -568,20 +568,21 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
|
|||||||
*(uint32_t *)ptr = tswapl(env->PC);
|
*(uint32_t *)ptr = tswapl(env->PC);
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
|
|
||||||
#ifdef MIPS_USES_FPU
|
if (env->CP0_Config1 & (1 << CP0C1_FP))
|
||||||
for (i = 0; i < 32; i++)
|
|
||||||
{
|
{
|
||||||
*(uint32_t *)ptr = tswapl(FPR_W (env, i));
|
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->fcr0);
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(uint32_t *)ptr = tswapl(env->fcr31);
|
|
||||||
ptr += 4;
|
|
||||||
|
|
||||||
*(uint32_t *)ptr = tswapl(env->fcr0);
|
|
||||||
ptr += 4;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* 32 FP registers, fsr, fir, fp. Not yet implemented. */
|
/* 32 FP registers, fsr, fir, fp. Not yet implemented. */
|
||||||
/* what's 'fp' mean here? */
|
/* what's 'fp' mean here? */
|
||||||
|
|
||||||
@ -629,27 +630,28 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
|
|||||||
env->PC = tswapl(*(uint32_t *)ptr);
|
env->PC = tswapl(*(uint32_t *)ptr);
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
|
|
||||||
#ifdef MIPS_USES_FPU
|
if (env->CP0_Config1 & (1 << CP0C1_FP))
|
||||||
for (i = 0; i < 32; i++)
|
|
||||||
{
|
{
|
||||||
FPR_W (env, i) = tswapl(*(uint32_t *)ptr);
|
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;
|
ptr += 4;
|
||||||
}
|
|
||||||
|
|
||||||
env->fcr31 = tswapl(*(uint32_t *)ptr) & 0x0183FFFF;
|
env->fcr0 = tswapl(*(uint32_t *)ptr);
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
|
|
||||||
env->fcr0 = tswapl(*(uint32_t *)ptr);
|
/* set rounding mode */
|
||||||
ptr += 4;
|
RESTORE_ROUNDING_MODE;
|
||||||
|
|
||||||
/* set rounding mode */
|
|
||||||
RESTORE_ROUNDING_MODE;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SOFTFLOAT
|
#ifndef CONFIG_SOFTFLOAT
|
||||||
/* no floating point exception for native float */
|
/* no floating point exception for native float */
|
||||||
SET_FP_ENABLE(env->fcr31, 0);
|
SET_FP_ENABLE(env->fcr31, 0);
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#elif defined (TARGET_SH4)
|
#elif defined (TARGET_SH4)
|
||||||
static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
|
static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
|
||||||
|
@ -1838,9 +1838,9 @@ int main(int argc, char **argv)
|
|||||||
env->gpr[i] = regs->regs[i];
|
env->gpr[i] = regs->regs[i];
|
||||||
}
|
}
|
||||||
env->PC = regs->cp0_epc;
|
env->PC = regs->cp0_epc;
|
||||||
#ifdef MIPS_USES_FPU
|
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
|
||||||
env->CP0_Status |= (1 << CP0St_CU1);
|
env->CP0_Status |= (1 << CP0St_CU1);
|
||||||
#endif
|
}
|
||||||
}
|
}
|
||||||
#elif defined(TARGET_SH4)
|
#elif defined(TARGET_SH4)
|
||||||
{
|
{
|
||||||
|
@ -63,7 +63,6 @@ struct CPUMIPSState {
|
|||||||
#endif
|
#endif
|
||||||
target_ulong HI, LO;
|
target_ulong HI, LO;
|
||||||
uint32_t DCR; /* ? */
|
uint32_t DCR; /* ? */
|
||||||
#if defined(MIPS_USES_FPU)
|
|
||||||
/* Floating point registers */
|
/* Floating point registers */
|
||||||
fpr_t fpr[16];
|
fpr_t fpr[16];
|
||||||
#define FPR(cpu, n) ((fpr_t*)&(cpu)->fpr[(n) / 2])
|
#define FPR(cpu, n) ((fpr_t*)&(cpu)->fpr[(n) / 2])
|
||||||
@ -97,8 +96,7 @@ struct CPUMIPSState {
|
|||||||
#define FP_DIV0 8
|
#define FP_DIV0 8
|
||||||
#define FP_INVALID 16
|
#define FP_INVALID 16
|
||||||
#define FP_UNIMPLEMENTED 32
|
#define FP_UNIMPLEMENTED 32
|
||||||
|
|
||||||
#endif
|
|
||||||
#if defined(MIPS_USES_R4K_TLB)
|
#if defined(MIPS_USES_R4K_TLB)
|
||||||
tlb_t tlb[MIPS_TLB_MAX];
|
tlb_t tlb[MIPS_TLB_MAX];
|
||||||
uint32_t tlb_in_use;
|
uint32_t tlb_in_use;
|
||||||
|
@ -115,12 +115,10 @@ void do_tlbwi (void);
|
|||||||
void do_tlbwr (void);
|
void do_tlbwr (void);
|
||||||
void do_tlbp (void);
|
void do_tlbp (void);
|
||||||
void do_tlbr (void);
|
void do_tlbr (void);
|
||||||
#ifdef MIPS_USES_FPU
|
|
||||||
void dump_fpu(CPUState *env);
|
void dump_fpu(CPUState *env);
|
||||||
void fpu_dump_state(CPUState *env, FILE *f,
|
void fpu_dump_state(CPUState *env, FILE *f,
|
||||||
int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
|
int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
|
||||||
int flags);
|
int flags);
|
||||||
#endif
|
|
||||||
void dump_sc (void);
|
void dump_sc (void);
|
||||||
void do_lwl_raw (uint32_t);
|
void do_lwl_raw (uint32_t);
|
||||||
void do_lwr_raw (uint32_t);
|
void do_lwr_raw (uint32_t);
|
||||||
|
@ -45,19 +45,14 @@
|
|||||||
2-way Icache, 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache,
|
2-way Icache, 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache,
|
||||||
no coprocessor2 attached, no MDMX support attached,
|
no coprocessor2 attached, no MDMX support attached,
|
||||||
no performance counters, watch registers present,
|
no performance counters, watch registers present,
|
||||||
no code compression, EJTAG present, FPU enable bit depending on
|
no code compression, EJTAG present, no FPU */
|
||||||
MIPS_USES_FPU */
|
#define MIPS_CONFIG1 \
|
||||||
#define MIPS_CONFIG1_1 \
|
|
||||||
((1 << CP0C1_M) | ((MIPS_TLB_NB - 1) << CP0C1_MMU) | \
|
((1 << CP0C1_M) | ((MIPS_TLB_NB - 1) << CP0C1_MMU) | \
|
||||||
(0x0 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x1 << CP0C1_IA) | \
|
(0x0 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x1 << CP0C1_IA) | \
|
||||||
(0x0 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x1 << CP0C1_DA) | \
|
(0x0 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x1 << CP0C1_DA) | \
|
||||||
(0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \
|
(0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \
|
||||||
(1 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP))
|
(1 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP) | \
|
||||||
#ifdef MIPS_USES_FPU
|
(0 << CP0C1_FP))
|
||||||
#define MIPS_CONFIG1 (MIPS_CONFIG1_1 | (1 << CP0C1_FP))
|
|
||||||
#else
|
|
||||||
#define MIPS_CONFIG1 (MIPS_CONFIG1_1 | (0 << CP0C1_FP))
|
|
||||||
#endif
|
|
||||||
/* Have config3, no tertiary/secondary caches implemented */
|
/* Have config3, no tertiary/secondary caches implemented */
|
||||||
#define MIPS_CONFIG2 \
|
#define MIPS_CONFIG2 \
|
||||||
((1 << CP0C2_M))
|
((1 << CP0C2_M))
|
||||||
|
@ -144,8 +144,6 @@ CALL_FROM_TB2(func, arg0, arg1);
|
|||||||
#include "op_template.c"
|
#include "op_template.c"
|
||||||
#undef TN
|
#undef TN
|
||||||
|
|
||||||
#ifdef MIPS_USES_FPU
|
|
||||||
|
|
||||||
#define SFREG 0
|
#define SFREG 0
|
||||||
#define DFREG 0
|
#define DFREG 0
|
||||||
#include "fop_template.c"
|
#include "fop_template.c"
|
||||||
@ -279,8 +277,6 @@ CALL_FROM_TB2(func, arg0, arg1);
|
|||||||
#include "fop_template.c"
|
#include "fop_template.c"
|
||||||
#undef FTN
|
#undef FTN
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void op_dup_T0 (void)
|
void op_dup_T0 (void)
|
||||||
{
|
{
|
||||||
T2 = T0;
|
T2 = T0;
|
||||||
@ -924,7 +920,6 @@ void op_movz (void)
|
|||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MIPS_USES_FPU
|
|
||||||
void op_movf (void)
|
void op_movf (void)
|
||||||
{
|
{
|
||||||
if (!(env->fcr31 & PARAM1))
|
if (!(env->fcr31 & PARAM1))
|
||||||
@ -938,7 +933,6 @@ void op_movt (void)
|
|||||||
env->gpr[PARAM2] = env->gpr[PARAM3];
|
env->gpr[PARAM2] = env->gpr[PARAM3];
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Tests */
|
/* Tests */
|
||||||
#define OP_COND(name, cond) \
|
#define OP_COND(name, cond) \
|
||||||
@ -1645,8 +1639,6 @@ void op_dmtc0_errorepc (void)
|
|||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MIPS_USES_FPU
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
# define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
|
# define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env)
|
||||||
#else
|
#else
|
||||||
@ -2001,7 +1993,6 @@ void op_bc1t (void)
|
|||||||
DEBUG_FPU_STATE();
|
DEBUG_FPU_STATE();
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
#endif /* MIPS_USES_FPU */
|
|
||||||
|
|
||||||
#if defined(MIPS_USES_R4K_TLB)
|
#if defined(MIPS_USES_R4K_TLB)
|
||||||
void op_tlbwi (void)
|
void op_tlbwi (void)
|
||||||
|
@ -331,7 +331,6 @@ void do_mtc0_status_irqraise_debug(void)
|
|||||||
fprintf(logfile, "Raise pending IRQs\n");
|
fprintf(logfile, "Raise pending IRQs\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MIPS_USES_FPU
|
|
||||||
#include "softfloat.h"
|
#include "softfloat.h"
|
||||||
|
|
||||||
void fpu_handle_exception(void)
|
void fpu_handle_exception(void)
|
||||||
@ -370,7 +369,6 @@ void fpu_handle_exception(void)
|
|||||||
SET_FP_CAUSE(env->fcr31, 0);
|
SET_FP_CAUSE(env->fcr31, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* MIPS_USES_FPU */
|
|
||||||
|
|
||||||
/* TLB management */
|
/* TLB management */
|
||||||
#if defined(MIPS_USES_R4K_TLB)
|
#if defined(MIPS_USES_R4K_TLB)
|
||||||
|
@ -192,7 +192,6 @@ void glue(op_scd, MEMSUFFIX) (void)
|
|||||||
}
|
}
|
||||||
#endif /* MIPS_HAS_MIPS64 */
|
#endif /* MIPS_HAS_MIPS64 */
|
||||||
|
|
||||||
#ifdef MIPS_USES_FPU
|
|
||||||
void glue(op_lwc1, MEMSUFFIX) (void)
|
void glue(op_lwc1, MEMSUFFIX) (void)
|
||||||
{
|
{
|
||||||
WT0 = glue(ldl, MEMSUFFIX)(T0);
|
WT0 = glue(ldl, MEMSUFFIX)(T0);
|
||||||
@ -213,4 +212,3 @@ void glue(op_sdc1, MEMSUFFIX) (void)
|
|||||||
glue(stq, MEMSUFFIX)(T0, DT0);
|
glue(stq, MEMSUFFIX)(T0, DT0);
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
@ -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_T0_gpr, gen_op_store_T0_gpr_gpr);
|
||||||
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
|
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
|
||||||
|
|
||||||
#ifdef MIPS_USES_FPU
|
|
||||||
|
|
||||||
static const char *fregnames[] =
|
static const char *fregnames[] =
|
||||||
{ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
|
{ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
|
||||||
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
|
"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(d)
|
||||||
FOP_CONDS(s)
|
FOP_CONDS(s)
|
||||||
|
|
||||||
#endif /* MIPS_USES_FPU */
|
|
||||||
|
|
||||||
typedef struct DisasContext {
|
typedef struct DisasContext {
|
||||||
struct TranslationBlock *tb;
|
struct TranslationBlock *tb;
|
||||||
target_ulong pc, saved_pc;
|
target_ulong pc, saved_pc;
|
||||||
@ -640,12 +636,10 @@ OP_LD_TABLE(bu);
|
|||||||
OP_ST_TABLE(b);
|
OP_ST_TABLE(b);
|
||||||
OP_LD_TABLE(l);
|
OP_LD_TABLE(l);
|
||||||
OP_ST_TABLE(c);
|
OP_ST_TABLE(c);
|
||||||
#ifdef MIPS_USES_FPU
|
|
||||||
OP_LD_TABLE(wc1);
|
OP_LD_TABLE(wc1);
|
||||||
OP_ST_TABLE(wc1);
|
OP_ST_TABLE(wc1);
|
||||||
OP_LD_TABLE(dc1);
|
OP_LD_TABLE(dc1);
|
||||||
OP_ST_TABLE(dc1);
|
OP_ST_TABLE(dc1);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Load and store */
|
/* Load and store */
|
||||||
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
|
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]);
|
MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MIPS_USES_FPU
|
|
||||||
|
|
||||||
/* Load and store */
|
/* Load and store */
|
||||||
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
|
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
|
||||||
int base, int16_t offset)
|
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]);
|
MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MIPS_USES_FPU */
|
|
||||||
|
|
||||||
/* Arithmetic with immediate operand */
|
/* Arithmetic with immediate operand */
|
||||||
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
|
static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
|
||||||
int rs, int16_t imm)
|
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);
|
MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MIPS_USES_FPU
|
|
||||||
|
|
||||||
/* CP1 Branches (before delay slot) */
|
/* CP1 Branches (before delay slot) */
|
||||||
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
|
static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
|
||||||
int32_t offset)
|
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);
|
gen_op_movt(ccbit, rd, rs);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MIPS_USES_FPU */
|
|
||||||
|
|
||||||
/* ISA extensions (ASEs) */
|
/* ISA extensions (ASEs) */
|
||||||
/* MIPS16 extension to MIPS32 */
|
/* MIPS16 extension to MIPS32 */
|
||||||
/* SmartMIPS extension to MIPS32 */
|
/* SmartMIPS extension to MIPS32 */
|
||||||
@ -4555,7 +4541,7 @@ static void gen_blikely(DisasContext *ctx)
|
|||||||
gen_set_label(l1);
|
gen_set_label(l1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_opc (DisasContext *ctx)
|
static void decode_opc (CPUState *env, DisasContext *ctx)
|
||||||
{
|
{
|
||||||
int32_t offset;
|
int32_t offset;
|
||||||
int rs, rt, rd, sa;
|
int rs, rt, rd, sa;
|
||||||
@ -4631,13 +4617,15 @@ static void decode_opc (DisasContext *ctx)
|
|||||||
/* Treat as a noop. */
|
/* Treat as a noop. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef MIPS_USES_FPU
|
|
||||||
case OPC_MOVCI:
|
case OPC_MOVCI:
|
||||||
gen_op_cp1_enabled();
|
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
|
||||||
gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
|
gen_op_cp1_enabled();
|
||||||
(ctx->opcode >> 16) & 1);
|
gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
|
||||||
|
(ctx->opcode >> 16) & 1);
|
||||||
|
} else {
|
||||||
|
generate_exception(ctx, EXCP_RI);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MIPS_HAS_MIPS64
|
#ifdef MIPS_HAS_MIPS64
|
||||||
/* MIPS64 specific opcodes */
|
/* MIPS64 specific opcodes */
|
||||||
@ -4868,47 +4856,47 @@ static void decode_opc (DisasContext *ctx)
|
|||||||
case OPC_LDC1:
|
case OPC_LDC1:
|
||||||
case OPC_SWC1:
|
case OPC_SWC1:
|
||||||
case OPC_SDC1:
|
case OPC_SDC1:
|
||||||
#if defined(MIPS_USES_FPU)
|
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
|
||||||
save_cpu_state(ctx, 1);
|
save_cpu_state(ctx, 1);
|
||||||
gen_op_cp1_enabled();
|
gen_op_cp1_enabled();
|
||||||
gen_flt_ldst(ctx, op, rt, rs, imm);
|
gen_flt_ldst(ctx, op, rt, rs, imm);
|
||||||
#else
|
} else {
|
||||||
generate_exception_err(ctx, EXCP_CpU, 1);
|
generate_exception_err(ctx, EXCP_CpU, 1);
|
||||||
#endif
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPC_CP1:
|
case OPC_CP1:
|
||||||
#if defined(MIPS_USES_FPU)
|
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
|
||||||
save_cpu_state(ctx, 1);
|
save_cpu_state(ctx, 1);
|
||||||
gen_op_cp1_enabled();
|
gen_op_cp1_enabled();
|
||||||
op1 = MASK_CP1(ctx->opcode);
|
op1 = MASK_CP1(ctx->opcode);
|
||||||
switch (op1) {
|
switch (op1) {
|
||||||
case OPC_MFC1:
|
case OPC_MFC1:
|
||||||
case OPC_CFC1:
|
case OPC_CFC1:
|
||||||
case OPC_MTC1:
|
case OPC_MTC1:
|
||||||
case OPC_CTC1:
|
case OPC_CTC1:
|
||||||
#ifdef MIPS_HAS_MIPS64
|
#ifdef MIPS_HAS_MIPS64
|
||||||
case OPC_DMFC1:
|
case OPC_DMFC1:
|
||||||
case OPC_DMTC1:
|
case OPC_DMTC1:
|
||||||
#endif
|
#endif
|
||||||
gen_cp1(ctx, op1, rt, rd);
|
gen_cp1(ctx, op1, rt, rd);
|
||||||
break;
|
break;
|
||||||
case OPC_BC1:
|
case OPC_BC1:
|
||||||
gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2);
|
gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2);
|
||||||
return;
|
return;
|
||||||
case OPC_S_FMT:
|
case OPC_S_FMT:
|
||||||
case OPC_D_FMT:
|
case OPC_D_FMT:
|
||||||
case OPC_W_FMT:
|
case OPC_W_FMT:
|
||||||
case OPC_L_FMT:
|
case OPC_L_FMT:
|
||||||
gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa);
|
gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
generate_exception_err(ctx, EXCP_RI, 1);
|
generate_exception_err(ctx, EXCP_RI, 1);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
generate_exception_err(ctx, EXCP_CpU, 1);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
generate_exception_err(ctx, EXCP_CpU, 1);
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* COP2. */
|
/* COP2. */
|
||||||
@ -4921,18 +4909,20 @@ static void decode_opc (DisasContext *ctx)
|
|||||||
generate_exception_err(ctx, EXCP_CpU, 2);
|
generate_exception_err(ctx, EXCP_CpU, 2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef MIPS_USES_FPU
|
|
||||||
case OPC_CP3:
|
case OPC_CP3:
|
||||||
gen_op_cp1_enabled();
|
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
|
||||||
op1 = MASK_CP3(ctx->opcode);
|
gen_op_cp1_enabled();
|
||||||
switch (op1) {
|
op1 = MASK_CP3(ctx->opcode);
|
||||||
/* Not implemented */
|
switch (op1) {
|
||||||
default:
|
/* Not implemented */
|
||||||
generate_exception_err(ctx, EXCP_RI, 1);
|
default:
|
||||||
break;
|
generate_exception_err(ctx, EXCP_RI, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
generate_exception(ctx, EXCP_RI);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MIPS_HAS_MIPS64
|
#ifdef MIPS_HAS_MIPS64
|
||||||
/* MIPS64 opcodes */
|
/* MIPS64 opcodes */
|
||||||
@ -5079,7 +5069,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
|
|||||||
gen_opc_instr_start[lj] = 1;
|
gen_opc_instr_start[lj] = 1;
|
||||||
}
|
}
|
||||||
ctx.opcode = ldl_code(ctx.pc);
|
ctx.opcode = ldl_code(ctx.pc);
|
||||||
decode_opc(&ctx);
|
decode_opc(env, &ctx);
|
||||||
ctx.pc += 4;
|
ctx.pc += 4;
|
||||||
|
|
||||||
if (env->singlestep_enabled)
|
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);
|
return gen_intermediate_code_internal(env, tb, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MIPS_USES_FPU
|
|
||||||
|
|
||||||
void fpu_dump_state(CPUState *env, FILE *f,
|
void fpu_dump_state(CPUState *env, FILE *f,
|
||||||
int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
|
int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
|
||||||
int flags)
|
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)
|
#if defined(MIPS_HAS_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
|
||||||
/* Debug help: The architecture requires 32bit code to maintain proper
|
/* Debug help: The architecture requires 32bit code to maintain proper
|
||||||
sign-extened values on 64bit machines. */
|
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);
|
c0_status, env->CP0_Cause, env->CP0_EPC);
|
||||||
cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
|
cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
|
||||||
env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
|
env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
|
||||||
#ifdef MIPS_USES_FPU
|
|
||||||
if (c0_status & (1 << CP0St_CU1))
|
if (c0_status & (1 << CP0St_CU1))
|
||||||
fpu_dump_state(env, f, cpu_fprintf, flags);
|
fpu_dump_state(env, f, cpu_fprintf, flags);
|
||||||
#endif
|
|
||||||
#if defined(MIPS_HAS_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
|
#if defined(MIPS_HAS_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
|
||||||
cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
|
cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
|
||||||
#endif
|
#endif
|
||||||
@ -5295,6 +5279,10 @@ void cpu_reset (CPUMIPSState *env)
|
|||||||
env->CP0_EBase = 0x80000000;
|
env->CP0_EBase = 0x80000000;
|
||||||
env->CP0_Config0 = MIPS_CONFIG0;
|
env->CP0_Config0 = MIPS_CONFIG0;
|
||||||
env->CP0_Config1 = MIPS_CONFIG1;
|
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_Config2 = MIPS_CONFIG2;
|
||||||
env->CP0_Config3 = MIPS_CONFIG3;
|
env->CP0_Config3 = MIPS_CONFIG3;
|
||||||
env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
|
env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
|
||||||
@ -5309,9 +5297,7 @@ void cpu_reset (CPUMIPSState *env)
|
|||||||
env->hflags |= MIPS_HFLAG_UM;
|
env->hflags |= MIPS_HFLAG_UM;
|
||||||
env->user_mode_only = 1;
|
env->user_mode_only = 1;
|
||||||
#endif
|
#endif
|
||||||
#ifdef MIPS_USES_FPU
|
env->fcr0 = MIPS_FCR0;
|
||||||
env->fcr0 = MIPS_FCR0;
|
|
||||||
#endif
|
|
||||||
/* XXX some guesswork here, values are CPU specific */
|
/* XXX some guesswork here, values are CPU specific */
|
||||||
env->SYNCI_Step = 16;
|
env->SYNCI_Step = 16;
|
||||||
env->CCRes = 2;
|
env->CCRes = 2;
|
||||||
|
Loading…
Reference in New Issue
Block a user