From 9c2a9ea1b1fe221566ca6c3f873da1454cadd263 Mon Sep 17 00:00:00 2001 From: pbrook Date: Sun, 18 Jun 2006 19:12:54 +0000 Subject: [PATCH] SH bugfixes. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1991 c046a42c-6fe2-441c-8c8c-71466251a162 --- cpu-exec.c | 2 +- gdbstub.c | 14 ++++++++++++-- linux-user/main.c | 14 +++++++------- target-sh4/cpu.h | 4 +++- target-sh4/exec.h | 2 +- target-sh4/op.c | 13 +++++++------ target-sh4/translate.c | 32 +++++++++++++------------------- 7 files changed, 44 insertions(+), 37 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 9d5c35e782..926093afbb 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -47,7 +47,7 @@ void cpu_loop_exit(void) longjmp(env->jmp_env, 1); } #endif -#ifndef TARGET_SPARC +#if !(defined(TARGET_SPARC) || defined(TARGET_SH4)) #define reg_T2 #endif diff --git a/gdbstub.c b/gdbstub.c index 37241ce589..3dcaa4c9cd 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -504,7 +504,12 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) int i; #define SAVE(x) *ptr++=tswapl(x) - for (i = 0; i < 16; i++) SAVE(env->gregs[i]); + if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) { + for (i = 0; i < 8; i++) SAVE(env->gregs[i + 16]); + } else { + for (i = 0; i < 8; i++) SAVE(env->gregs[i]); + } + for (i = 8; i < 16; i++) SAVE(env->gregs[i]); SAVE (env->pc); SAVE (env->pr); SAVE (env->gbr); @@ -527,7 +532,12 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) int i; #define LOAD(x) (x)=*ptr++; - for (i = 0; i < 16; i++) LOAD(env->gregs[i]); + if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) { + for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]); + } else { + for (i = 0; i < 8; i++) LOAD(env->gregs[i]); + } + for (i = 8; i < 16; i++) LOAD(env->gregs[i]); LOAD (env->pc); LOAD (env->pr); LOAD (env->gbr); diff --git a/linux-user/main.c b/linux-user/main.c index 74642cc361..a73919ec3c 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -1370,14 +1370,14 @@ void cpu_loop (CPUState *env) switch (trapnr) { case 0x160: ret = do_syscall(env, - env->gregs[0x13], - env->gregs[0x14], - env->gregs[0x15], - env->gregs[0x16], - env->gregs[0x17], - env->gregs[0x10], + env->gregs[3], + env->gregs[4], + env->gregs[5], + env->gregs[6], + env->gregs[7], + env->gregs[0], 0); - env->gregs[0x10] = ret; + env->gregs[0] = ret; env->pc += 2; break; case EXCP_DEBUG: diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index c71af74373..ef818fdf25 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -45,7 +45,9 @@ #define FPSCR_PR (1 << 19) #define FPSCR_DN (1 << 18) -#define DELAY_SLOT (1 << 0) +#define DELAY_SLOT (1 << 0) /* Must be the same as SR_T. */ +/* This flag is set if the next insn is a delay slot for a conditional jump. + The dynamic value of the DELAY_SLOT determines whether the jup is taken. */ #define DELAY_SLOT_CONDITIONAL (1 << 1) /* Those are used in contexts only */ #define BRANCH (1 << 2) diff --git a/target-sh4/exec.h b/target-sh4/exec.h index b828206121..3563300307 100644 --- a/target-sh4/exec.h +++ b/target-sh4/exec.h @@ -26,7 +26,7 @@ register struct CPUSH4State *env asm(AREG0); register uint32_t T0 asm(AREG1); register uint32_t T1 asm(AREG2); -register uint32_t T2 asm(AREG3); +//register uint32_t T2 asm(AREG3); #define FT0 (env->ft0) #define FT1 (env->ft1) diff --git a/target-sh4/op.c b/target-sh4/op.c index 64f952fc54..d3b68bc665 100644 --- a/target-sh4/op.c +++ b/target-sh4/op.c @@ -109,17 +109,15 @@ void OPPROTO op_not_T0(void) void OPPROTO op_bf_s(void) { - T2 = ~env->sr; env->delayed_pc = PARAM1; - set_flag(DELAY_SLOT_CONDITIONAL); + set_flag(DELAY_SLOT_CONDITIONAL | ((~env->sr) & SR_T)); RETURN(); } void OPPROTO op_bt_s(void) { - T2 = env->sr; env->delayed_pc = PARAM1; - set_flag(DELAY_SLOT_CONDITIONAL); + set_flag(DELAY_SLOT_CONDITIONAL | (env->sr & SR_T)); RETURN(); } @@ -888,9 +886,12 @@ void OPPROTO op_jT(void) RETURN(); } -void OPPROTO op_jTT2(void) +void OPPROTO op_jdelayed(void) { - if (T2 & SR_T) + uint32_t flags; + flags = env->flags; + env->flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL); + if (flags & DELAY_SLOT) GOTO_LABEL_PARAM(1); RETURN(); } diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 0dca45ee9c..358f975e0c 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -124,7 +124,11 @@ void cpu_dump_state(CPUState * env, FILE * f, void cpu_sh4_reset(CPUSH4State * env) { +#if defined(CONFIG_USER_ONLY) + env->sr = 0x00000000; +#else env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */ +#endif env->vbr = 0; env->pc = 0xA0000000; env->fpscr = 0x00040001; @@ -209,10 +213,10 @@ static void gen_delayed_conditional_jump(DisasContext * ctx) int l1; l1 = gen_new_label(); - gen_op_jTT2(l1); - gen_goto_tb(ctx, 0, ctx->pc); + gen_op_jdelayed(l1); + gen_goto_tb(ctx, 1, ctx->pc); gen_set_label(l1); - gen_goto_tb(ctx, 1, ctx->delayed_pc); + gen_jump(ctx); } #define B3_0 (ctx->opcode & 0xf) @@ -1160,25 +1164,15 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, #endif } - switch (old_flags & (DELAY_SLOT_CONDITIONAL | DELAY_SLOT)) { - case DELAY_SLOT_CONDITIONAL: - gen_op_clr_delay_slot_conditional(); + if (old_flags & DELAY_SLOT_CONDITIONAL) { gen_delayed_conditional_jump(&ctx); - break; - case DELAY_SLOT: + } else if (old_flags & DELAY_SLOT) { gen_op_clr_delay_slot(); gen_jump(&ctx); - break; - case 0: - if (ctx.flags & BRANCH_EXCEPTION) { - gen_jump_exception(&ctx); - } else if ((ctx.flags & (BRANCH | BRANCH_CONDITIONAL)) == 0) { - gen_goto_tb(&ctx, 0, ctx.pc); - } - break; - default: - /* Both cannot be set at the same time */ - assert(0); + } else if (ctx.flags & BRANCH_EXCEPTION) { + gen_jump_exception(&ctx); + } else if ((ctx.flags & (BRANCH | BRANCH_CONDITIONAL)) == 0) { + gen_goto_tb(&ctx, 0, ctx.pc); } if (env->singlestep_enabled) {