Hi everyone, Here comes the second batch of patches for the user space emulator. Below is a one line summary of each patch, please have a look in the patch header for details:
- Fix XHACK() macro and use FREG if possible - Emulate more fpu opcodes - Document FPSCR usage - Use DREG() over XREG() if possible - Remove unnecessary pointer magic in shift operations - Add fpu register support to the gdb code If you have any questions or comments, please don't hesitate to contact me! Thanks! / magnus
sh4: Fix XHACK() macro and use FREG if possible The XHACK() macro seems to incorrectly shift left once, so fix that. XREG() is used in some places where FREG() is more suitable. Signed-off-by: Magnus Damm <[EMAIL PROTECTED]> --- 0001/target-sh4/translate.c +++ work/target-sh4/translate.c 2007-05-07 17:11:49.000000000 +0900 @@ -236,7 +236,7 @@ static void gen_delayed_conditional_jump ? (x) + 16 : (x)) #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x)) -#define XHACK(x) (((x) & 1 ) << 4 | ((x) & 0xe ) << 1) +#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe)) #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x)) #define CHECK_NOT_DELAY_SLOT \ @@ -685,7 +685,7 @@ void decode_opc(DisasContext * ctx) } else { gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldfl_T0_FT0(ctx); - gen_op_fmov_FT0_frN(XREG(B11_8)); + gen_op_fmov_FT0_frN(FREG(B11_8)); } return; case 0xf009: /* fmov @Rm+,{F,D,X}Rn */ @@ -704,7 +704,7 @@ void decode_opc(DisasContext * ctx) } else { gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldfl_T0_FT0(ctx); - gen_op_fmov_FT0_frN(XREG(B11_8)); + gen_op_fmov_FT0_frN(FREG(B11_8)); gen_op_inc4_rN(REG(B7_4)); } return; @@ -745,7 +745,7 @@ void decode_opc(DisasContext * ctx) gen_op_movl_rN_T0(REG(B7_4)); gen_op_add_rN_T0(REG(0)); gen_op_ldfl_T0_FT0(ctx); - gen_op_fmov_FT0_frN(XREG(B11_8)); + gen_op_fmov_FT0_frN(FREG(B11_8)); } return; case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) */
sh4: Emulate more fpu opcodes This patch adds support for more fpu opcodes. Emulation is not complete yet - FPU flags and exceptions are not fully supported. The FPSCR register does not yet contain correct flag information. But it is a good start. =) Signed-off-by: Magnus Damm <[EMAIL PROTECTED]> --- 0001/target-sh4/cpu.h +++ work/target-sh4/cpu.h 2007-05-07 17:40:32.000000000 +0900 @@ -99,6 +99,7 @@ typedef struct CPUSH4State { /* temporary float registers */ float32 ft0, ft1; float64 dt0, dt1; + float_status fp_status; /* Those belong to the specific unit (SH7750) but are handled here */ uint32_t mmucr; /* MMU control register */ --- 0001/target-sh4/op.c +++ work/target-sh4/op.c 2007-05-07 17:40:32.000000000 +0900 @@ -509,6 +509,9 @@ void OPPROTO op_##store##_##target##_T0 void OPPROTO op_lds_T0_fpscr(void) { env->fpscr = T0 & 0x003fffff; + env->fp_status.float_rounding_mode = T0 & 0x01 ? + float_round_to_zero : float_round_nearest_even; + RETURN(); } @@ -705,6 +708,18 @@ void OPPROTO op_fmov_drN_DT0(void) RETURN(); } +void OPPROTO op_fmov_frN_FT1(void) +{ + FT1 = *(float32 *)&env->fregs[PARAM1]; + RETURN(); +} + +void OPPROTO op_fmov_drN_DT1(void) +{ + DT1 = *(float64 *)&env->fregs[PARAM1]; + RETURN(); +} + void OPPROTO op_fmov_FT0_frN(void) { *(float32 *)&env->fregs[PARAM1] = FT0; @@ -717,6 +732,84 @@ void OPPROTO op_fmov_DT0_drN(void) RETURN(); } +void OPPROTO op_fadd_FT(void) +{ + FT0 = float32_add(FT0, FT1, &env->fp_status); + RETURN(); +} + +void OPPROTO op_fadd_DT(void) +{ + DT0 = float64_add(DT0, DT1, &env->fp_status); + RETURN(); +} + +void OPPROTO op_fsub_FT(void) +{ + FT0 = float32_sub(FT0, FT1, &env->fp_status); + RETURN(); +} + +void OPPROTO op_fsub_DT(void) +{ + DT0 = float64_sub(DT0, DT1, &env->fp_status); + RETURN(); +} + +void OPPROTO op_fmul_FT(void) +{ + FT0 = float32_mul(FT0, FT1, &env->fp_status); + RETURN(); +} + +void OPPROTO op_fmul_DT(void) +{ + DT0 = float64_mul(DT0, DT1, &env->fp_status); + RETURN(); +} + +void OPPROTO op_fdiv_FT(void) +{ + FT0 = float32_div(FT0, FT1, &env->fp_status); + RETURN(); +} + +void OPPROTO op_fdiv_DT(void) +{ + DT0 = float64_div(DT0, DT1, &env->fp_status); + RETURN(); +} + +void OPPROTO op_float_FT(void) +{ + FT0 = int32_to_float32(env->fpul, &env->fp_status); + RETURN(); +} + +void OPPROTO op_float_DT(void) +{ + DT0 = int32_to_float64(env->fpul, &env->fp_status); + RETURN(); +} + +void OPPROTO op_ftrc_FT(void) +{ + env->fpul = float32_to_int32(FT0, &env->fp_status); + RETURN(); +} + +void OPPROTO op_ftrc_DT(void) +{ + env->fpul = float64_to_int32(DT0, &env->fp_status); + RETURN(); +} + +void OPPROTO op_movl_T0_FT0(void) +{ + FT0 = T0; + RETURN(); +} + void OPPROTO op_dec1_rN(void) { env->gregs[PARAM1] -= 1; --- 0002/target-sh4/translate.c +++ work/target-sh4/translate.c 2007-05-09 16:47:55.000000000 +0900 @@ -131,7 +131,13 @@ void cpu_sh4_reset(CPUSH4State * env) #endif env->vbr = 0; env->pc = 0xA0000000; - env->fpscr = 0x00040001; +#if defined(CONFIG_USER_ONLY) + env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */ + env->fp_status.float_rounding_mode = float_round_nearest_even; /* ?! */ +#else + env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */ + env->fp_status.float_rounding_mode = float_round_to_zero; +#endif env->mmucr = 0; } @@ -238,6 +244,7 @@ static void gen_delayed_conditional_jump #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x)) #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe)) #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x)) +#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */ #define CHECK_NOT_DELAY_SLOT \ if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \ @@ -768,6 +775,49 @@ void decode_opc(DisasContext * ctx) gen_op_stfl_FT0_T1(ctx); } return; + case 0xf000: /* fadd Rm,Rn */ + case 0xf001: /* fsub Rm,Rn */ + case 0xf002: /* fmul Rm,Rn */ + case 0xf003: /* fdiv Rm,Rn */ + case 0xf004: /* fcmp/eq Rm,Rn */ + case 0xf005: /* fcmp/gt Rm,Rn */ + if (ctx->fpscr & FPSCR_PR) { + if (ctx->opcode & 0x0110) + break; /* illegal instruction */ + gen_op_fmov_drN_DT1(DREG(B7_4)); + gen_op_fmov_drN_DT0(DREG(B11_8)); + } + else { + gen_op_fmov_frN_FT1(FREG(B7_4)); + gen_op_fmov_frN_FT0(FREG(B11_8)); + } + + switch (ctx->opcode & 0xf00f) { + case 0xf000: /* fadd Rm,Rn */ + ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT(); + break; + case 0xf001: /* fsub Rm,Rn */ + ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT(); + break; + case 0xf002: /* fmul Rm,Rn */ + ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT(); + break; + case 0xf003: /* fdiv Rm,Rn */ + ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT(); + break; + case 0xf004: /* fcmp/eq Rm,Rn */ + return; + case 0xf005: /* fcmp/gt Rm,Rn */ + return; + } + + if (ctx->fpscr & FPSCR_PR) { + gen_op_fmov_DT0_drN(DREG(B11_8)); + } + else { + gen_op_fmov_FT0_frN(FREG(B11_8)); + } + return; } switch (ctx->opcode & 0xff00) { @@ -1079,6 +1129,46 @@ void decode_opc(DisasContext * ctx) gen_op_fmov_frN_FT0(FREG(B11_8)); gen_op_movl_FT0_fpul(); return; + case 0xf02d: /* float FPUL,FRn/DRn */ + if (ctx->fpscr & FPSCR_PR) { + if (ctx->opcode & 0x0100) + break; /* illegal instruction */ + gen_op_float_DT(); + gen_op_fmov_DT0_drN(DREG(B11_8)); + } + else { + gen_op_float_FT(); + gen_op_fmov_FT0_frN(FREG(B11_8)); + } + return; + case 0xf03d: /* ftrc FRm/DRm,FPUL */ + if (ctx->fpscr & FPSCR_PR) { + if (ctx->opcode & 0x0100) + break; /* illegal instruction */ + gen_op_fmov_drN_DT0(DREG(B11_8)); + gen_op_ftrc_DT(); + } + else { + gen_op_fmov_frN_FT0(FREG(B11_8)); + gen_op_ftrc_FT(); + } + return; + case 0xf08d: /* fldi0 FRn */ + if (!(ctx->fpscr & FPSCR_PR)) { + gen_op_movl_imm_T0(0); + gen_op_movl_T0_FT0(); + gen_op_fmov_FT0_frN(FREG(B11_8)); + return; + } + break; + case 0xf09d: /* fldi1 FRn */ + if (!(ctx->fpscr & FPSCR_PR)) { + gen_op_movl_imm_T0(0x3f800000); + gen_op_movl_T0_FT0(); + gen_op_fmov_FT0_frN(FREG(B11_8)); + return; + } + break; } fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
sh4: Document FPSCR usage This patch extends per opcode comments to include FPSCR usage. These comments are useful when implementing proper fpu exception handling in the future. This patch contains no logic changes. Signed-off-by: Magnus Damm <[EMAIL PROTECTED]> --- 0003/target-sh4/translate.c +++ work/target-sh4/translate.c 2007-05-07 17:29:32.000000000 +0900 @@ -642,7 +642,7 @@ void decode_opc(DisasContext * ctx) gen_op_movl_rN_T0(REG(B7_4)); gen_op_xor_T0_rN(REG(B11_8)); return; - case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn */ + case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */ if (ctx->fpscr & FPSCR_PR) { gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_fmov_DT0_drN(XREG(B11_8)); @@ -656,7 +656,7 @@ void decode_opc(DisasContext * ctx) gen_op_fmov_FT0_frN(FREG(B11_8)); } return; - case 0xf00a: /* fmov {F,D,X}Rm,@Rn */ + case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */ if (ctx->fpscr & FPSCR_PR) { gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); @@ -673,7 +673,7 @@ void decode_opc(DisasContext * ctx) gen_op_stfl_FT0_T1(ctx); } return; - case 0xf008: /* fmov @Rm,{F,D,X}Rn */ + case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */ if (ctx->fpscr & FPSCR_PR) { gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldfq_T0_DT0(ctx); @@ -690,7 +690,7 @@ void decode_opc(DisasContext * ctx) gen_op_fmov_FT0_frN(FREG(B11_8)); } return; - case 0xf009: /* fmov @Rm+,{F,D,X}Rn */ + case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */ if (ctx->fpscr & FPSCR_PR) { gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldfq_T0_DT0(ctx); @@ -710,7 +710,7 @@ void decode_opc(DisasContext * ctx) gen_op_inc4_rN(REG(B7_4)); } return; - case 0xf00b: /* fmov {F,D,X}Rm,@-Rn */ + case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */ if (ctx->fpscr & FPSCR_PR) { gen_op_dec8_rN(REG(B11_8)); gen_op_fmov_drN_DT0(XREG(B7_4)); @@ -730,7 +730,7 @@ void decode_opc(DisasContext * ctx) gen_op_stfl_FT0_T1(ctx); } return; - case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm */ + case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */ if (ctx->fpscr & FPSCR_PR) { gen_op_movl_rN_T0(REG(B7_4)); gen_op_add_rN_T0(REG(0)); @@ -750,7 +750,7 @@ void decode_opc(DisasContext * ctx) gen_op_fmov_FT0_frN(FREG(B11_8)); } return; - case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) */ + case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */ if (ctx->fpscr & FPSCR_PR) { gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); @@ -770,12 +770,12 @@ void decode_opc(DisasContext * ctx) gen_op_stfl_FT0_T1(ctx); } return; - case 0xf000: /* fadd Rm,Rn */ - case 0xf001: /* fsub Rm,Rn */ - case 0xf002: /* fmul Rm,Rn */ - case 0xf003: /* fdiv Rm,Rn */ - case 0xf004: /* fcmp/eq Rm,Rn */ - case 0xf005: /* fcmp/gt Rm,Rn */ + case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */ + case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */ + case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */ + case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */ + case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */ + case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */ if (ctx->fpscr & FPSCR_PR) { if (ctx->opcode & 0x0110) break; /* illegal instruction */ @@ -1116,15 +1116,15 @@ void decode_opc(DisasContext * ctx) case 0x401b: /* tas.b @Rn */ gen_op_tasb_rN(REG(B11_8)); return; - case 0xf00d: /* fsts FPUL,FRn */ + case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */ gen_op_movl_fpul_FT0(); gen_op_fmov_FT0_frN(FREG(B11_8)); return; - case 0xf01d: /* flds FRm.FPUL */ + case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */ gen_op_fmov_frN_FT0(FREG(B11_8)); gen_op_movl_FT0_fpul(); return; - case 0xf02d: /* float FPUL,FRn/DRn */ + case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */ if (ctx->fpscr & FPSCR_PR) { if (ctx->opcode & 0x0100) break; /* illegal instruction */ @@ -1136,7 +1136,7 @@ void decode_opc(DisasContext * ctx) gen_op_fmov_FT0_frN(FREG(B11_8)); } return; - case 0xf03d: /* ftrc FRm/DRm,FPUL */ + case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */ if (ctx->fpscr & FPSCR_PR) { if (ctx->opcode & 0x0100) break; /* illegal instruction */ @@ -1148,7 +1148,7 @@ void decode_opc(DisasContext * ctx) gen_op_ftrc_FT(); } return; - case 0xf08d: /* fldi0 FRn */ + case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */ if (!(ctx->fpscr & FPSCR_PR)) { gen_op_movl_imm_T0(0); gen_op_movl_T0_FT0(); @@ -1156,7 +1156,7 @@ void decode_opc(DisasContext * ctx) return; } break; - case 0xf09d: /* fldi1 FRn */ + case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */ if (!(ctx->fpscr & FPSCR_PR)) { gen_op_movl_imm_T0(0x3f800000); gen_op_movl_T0_FT0();
sh4: Use DREG() over XREG() if possible Replace XREG() with DREG() if the lowest register bits are known to be zero. Signed-off-by: Magnus Damm <[EMAIL PROTECTED]> --- 0006/target-sh4/translate.c +++ work/target-sh4/translate.c 2007-05-08 13:19:40.000000000 +0900 @@ -649,8 +649,8 @@ void decode_opc(DisasContext * ctx) } else if (ctx->fpscr & FPSCR_SZ) { if (ctx->opcode & 0x0110) break; /* illegal instruction */ - gen_op_fmov_drN_DT0(XREG(B7_4)); - gen_op_fmov_DT0_drN(XREG(B11_8)); + gen_op_fmov_drN_DT0(DREG(B7_4)); + gen_op_fmov_DT0_drN(DREG(B11_8)); } else { gen_op_fmov_frN_FT0(FREG(B7_4)); gen_op_fmov_FT0_frN(FREG(B11_8)); @@ -664,7 +664,7 @@ void decode_opc(DisasContext * ctx) } else if (ctx->fpscr & FPSCR_SZ) { if (ctx->opcode & 0x0010) break; /* illegal instruction */ - gen_op_fmov_drN_DT0(XREG(B7_4)); + gen_op_fmov_drN_DT0(DREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stfq_DT0_T1(ctx); } else { @@ -683,7 +683,7 @@ void decode_opc(DisasContext * ctx) break; /* illegal instruction */ gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldfq_T0_DT0(ctx); - gen_op_fmov_DT0_drN(XREG(B11_8)); + gen_op_fmov_DT0_drN(DREG(B11_8)); } else { gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldfl_T0_FT0(ctx); @@ -701,7 +701,7 @@ void decode_opc(DisasContext * ctx) break; /* illegal instruction */ gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldfq_T0_DT0(ctx); - gen_op_fmov_DT0_drN(XREG(B11_8)); + gen_op_fmov_DT0_drN(DREG(B11_8)); gen_op_inc8_rN(REG(B7_4)); } else { gen_op_movl_rN_T0(REG(B7_4)); @@ -720,7 +720,7 @@ void decode_opc(DisasContext * ctx) if (ctx->opcode & 0x0100) break; /* illegal instruction */ gen_op_dec8_rN(REG(B11_8)); - gen_op_fmov_drN_DT0(XREG(B7_4)); + gen_op_fmov_drN_DT0(DREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stfq_DT0_T1(ctx); } else { @@ -742,7 +742,7 @@ void decode_opc(DisasContext * ctx) gen_op_movl_rN_T0(REG(B7_4)); gen_op_add_rN_T0(REG(0)); gen_op_ldfq_T0_DT0(ctx); - gen_op_fmov_DT0_drN(XREG(B11_8)); + gen_op_fmov_DT0_drN(DREG(B11_8)); } else { gen_op_movl_rN_T0(REG(B7_4)); gen_op_add_rN_T0(REG(0)); @@ -759,7 +759,7 @@ void decode_opc(DisasContext * ctx) } else if (ctx->fpscr & FPSCR_SZ) { if (ctx->opcode & 0x0010) break; /* illegal instruction */ - gen_op_fmov_drN_DT0(XREG(B7_4)); + gen_op_fmov_drN_DT0(DREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_add_rN_T1(REG(0)); gen_op_stfq_DT0_T1(ctx);
sh4: Remove unnecessary pointer magic in shift operations 32-bit data types are already present, so casting should be unnecessary. Signed-off-by: Magnus Damm <[EMAIL PROTECTED]> --- 0003/target-sh4/op.c +++ work/target-sh4/op.c 2007-05-08 15:41:23.000000000 +0900 @@ -564,14 +564,14 @@ void OPPROTO op_shal_Rn(void) void OPPROTO op_shar_Rn(void) { cond_t(env->gregs[PARAM1] & 1); - *(int32_t *) & env->gregs[PARAM1] >>= 1; + env->gregs[PARAM1] >>= 1; RETURN(); } void OPPROTO op_shlr_Rn(void) { cond_t(env->gregs[PARAM1] & 1); - *(uint32_t *) & env->gregs[PARAM1] >>= 1; + env->gregs[PARAM1] >>= 1; RETURN(); } @@ -595,19 +595,19 @@ void OPPROTO op_shll16_Rn(void) void OPPROTO op_shlr2_Rn(void) { - *(uint32_t *) & env->gregs[PARAM1] >>= 2; + env->gregs[PARAM1] >>= 2; RETURN(); } void OPPROTO op_shlr8_Rn(void) { - *(uint32_t *) & env->gregs[PARAM1] >>= 8; + env->gregs[PARAM1] >>= 8; RETURN(); } void OPPROTO op_shlr16_Rn(void) { - *(uint32_t *) & env->gregs[PARAM1] >>= 16; + env->gregs[PARAM1] >>= 16; RETURN(); }
sh4: Add fpu register support to the gdb code This patch adds fpu registers to the register saving and restoring code. Signed-off-by: Magnus Damm <[EMAIL PROTECTED]> --- 0001/gdbstub.c +++ work/gdbstub.c 2007-05-09 16:43:01.000000000 +0900 @@ -657,6 +657,9 @@ static void cpu_gdb_write_registers(CPUS } } #elif defined (TARGET_SH4) + +/* Hint: Use "set architecture sh4" in GDB to see fpu registers */ + static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) { uint32_t *ptr = (uint32_t *)mem_buf; @@ -676,12 +679,14 @@ static int cpu_gdb_read_registers(CPUSta SAVE (env->mach); SAVE (env->macl); SAVE (env->sr); - SAVE (0); /* TICKS */ - SAVE (0); /* STALLS */ - SAVE (0); /* CYCLES */ - SAVE (0); /* INSTS */ - SAVE (0); /* PLR */ - + SAVE (env->fpul); + SAVE (env->fpscr); + for (i = 0; i < 16; i++) + SAVE(env->fregs[i + ((env->fpscr & FPSCR_FR) ? 16 : 0)]); + SAVE (env->ssr); + SAVE (env->spc); + for (i = 0; i < 8; i++) SAVE(env->gregs[i]); + for (i = 0; i < 8; i++) SAVE(env->gregs[i + 16]); return ((uint8_t *)ptr - mem_buf); } @@ -704,6 +709,14 @@ static void cpu_gdb_write_registers(CPUS LOAD (env->mach); LOAD (env->macl); LOAD (env->sr); + LOAD (env->fpul); + LOAD (env->fpscr); + for (i = 0; i < 16; i++) + LOAD(env->fregs[i + ((env->fpscr & FPSCR_FR) ? 16 : 0)]); + LOAD (env->ssr); + LOAD (env->spc); + for (i = 0; i < 8; i++) LOAD(env->gregs[i]); + for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]); } #else static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)