Commit 9c2a9ea1b1fe221566ca6c3f873da1454cadd263

Authored by pbrook
1 parent 397e923f

SH bugfixes.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1991 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-exec.c
... ... @@ -47,7 +47,7 @@ void cpu_loop_exit(void)
47 47 longjmp(env->jmp_env, 1);
48 48 }
49 49 #endif
50   -#ifndef TARGET_SPARC
  50 +#if !(defined(TARGET_SPARC) || defined(TARGET_SH4))
51 51 #define reg_T2
52 52 #endif
53 53  
... ...
gdbstub.c
... ... @@ -504,7 +504,12 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
504 504 int i;
505 505  
506 506 #define SAVE(x) *ptr++=tswapl(x)
507   - for (i = 0; i < 16; i++) SAVE(env->gregs[i]);
  507 + if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
  508 + for (i = 0; i < 8; i++) SAVE(env->gregs[i + 16]);
  509 + } else {
  510 + for (i = 0; i < 8; i++) SAVE(env->gregs[i]);
  511 + }
  512 + for (i = 8; i < 16; i++) SAVE(env->gregs[i]);
508 513 SAVE (env->pc);
509 514 SAVE (env->pr);
510 515 SAVE (env->gbr);
... ... @@ -527,7 +532,12 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
527 532 int i;
528 533  
529 534 #define LOAD(x) (x)=*ptr++;
530   - for (i = 0; i < 16; i++) LOAD(env->gregs[i]);
  535 + if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
  536 + for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]);
  537 + } else {
  538 + for (i = 0; i < 8; i++) LOAD(env->gregs[i]);
  539 + }
  540 + for (i = 8; i < 16; i++) LOAD(env->gregs[i]);
531 541 LOAD (env->pc);
532 542 LOAD (env->pr);
533 543 LOAD (env->gbr);
... ...
linux-user/main.c
... ... @@ -1370,14 +1370,14 @@ void cpu_loop (CPUState *env)
1370 1370 switch (trapnr) {
1371 1371 case 0x160:
1372 1372 ret = do_syscall(env,
1373   - env->gregs[0x13],
1374   - env->gregs[0x14],
1375   - env->gregs[0x15],
1376   - env->gregs[0x16],
1377   - env->gregs[0x17],
1378   - env->gregs[0x10],
  1373 + env->gregs[3],
  1374 + env->gregs[4],
  1375 + env->gregs[5],
  1376 + env->gregs[6],
  1377 + env->gregs[7],
  1378 + env->gregs[0],
1379 1379 0);
1380   - env->gregs[0x10] = ret;
  1380 + env->gregs[0] = ret;
1381 1381 env->pc += 2;
1382 1382 break;
1383 1383 case EXCP_DEBUG:
... ...
target-sh4/cpu.h
... ... @@ -45,7 +45,9 @@
45 45 #define FPSCR_PR (1 << 19)
46 46 #define FPSCR_DN (1 << 18)
47 47  
48   -#define DELAY_SLOT (1 << 0)
  48 +#define DELAY_SLOT (1 << 0) /* Must be the same as SR_T. */
  49 +/* This flag is set if the next insn is a delay slot for a conditional jump.
  50 + The dynamic value of the DELAY_SLOT determines whether the jup is taken. */
49 51 #define DELAY_SLOT_CONDITIONAL (1 << 1)
50 52 /* Those are used in contexts only */
51 53 #define BRANCH (1 << 2)
... ...
target-sh4/exec.h
... ... @@ -26,7 +26,7 @@
26 26 register struct CPUSH4State *env asm(AREG0);
27 27 register uint32_t T0 asm(AREG1);
28 28 register uint32_t T1 asm(AREG2);
29   -register uint32_t T2 asm(AREG3);
  29 +//register uint32_t T2 asm(AREG3);
30 30  
31 31 #define FT0 (env->ft0)
32 32 #define FT1 (env->ft1)
... ...
target-sh4/op.c
... ... @@ -109,17 +109,15 @@ void OPPROTO op_not_T0(void)
109 109  
110 110 void OPPROTO op_bf_s(void)
111 111 {
112   - T2 = ~env->sr;
113 112 env->delayed_pc = PARAM1;
114   - set_flag(DELAY_SLOT_CONDITIONAL);
  113 + set_flag(DELAY_SLOT_CONDITIONAL | ((~env->sr) & SR_T));
115 114 RETURN();
116 115 }
117 116  
118 117 void OPPROTO op_bt_s(void)
119 118 {
120   - T2 = env->sr;
121 119 env->delayed_pc = PARAM1;
122   - set_flag(DELAY_SLOT_CONDITIONAL);
  120 + set_flag(DELAY_SLOT_CONDITIONAL | (env->sr & SR_T));
123 121 RETURN();
124 122 }
125 123  
... ... @@ -888,9 +886,12 @@ void OPPROTO op_jT(void)
888 886 RETURN();
889 887 }
890 888  
891   -void OPPROTO op_jTT2(void)
  889 +void OPPROTO op_jdelayed(void)
892 890 {
893   - if (T2 & SR_T)
  891 + uint32_t flags;
  892 + flags = env->flags;
  893 + env->flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
  894 + if (flags & DELAY_SLOT)
894 895 GOTO_LABEL_PARAM(1);
895 896 RETURN();
896 897 }
... ...
target-sh4/translate.c
... ... @@ -124,7 +124,11 @@ void cpu_dump_state(CPUState * env, FILE * f,
124 124  
125 125 void cpu_sh4_reset(CPUSH4State * env)
126 126 {
  127 +#if defined(CONFIG_USER_ONLY)
  128 + env->sr = 0x00000000;
  129 +#else
127 130 env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
  131 +#endif
128 132 env->vbr = 0;
129 133 env->pc = 0xA0000000;
130 134 env->fpscr = 0x00040001;
... ... @@ -209,10 +213,10 @@ static void gen_delayed_conditional_jump(DisasContext * ctx)
209 213 int l1;
210 214  
211 215 l1 = gen_new_label();
212   - gen_op_jTT2(l1);
213   - gen_goto_tb(ctx, 0, ctx->pc);
  216 + gen_op_jdelayed(l1);
  217 + gen_goto_tb(ctx, 1, ctx->pc);
214 218 gen_set_label(l1);
215   - gen_goto_tb(ctx, 1, ctx->delayed_pc);
  219 + gen_jump(ctx);
216 220 }
217 221  
218 222 #define B3_0 (ctx->opcode & 0xf)
... ... @@ -1160,25 +1164,15 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1160 1164 #endif
1161 1165 }
1162 1166  
1163   - switch (old_flags & (DELAY_SLOT_CONDITIONAL | DELAY_SLOT)) {
1164   - case DELAY_SLOT_CONDITIONAL:
1165   - gen_op_clr_delay_slot_conditional();
  1167 + if (old_flags & DELAY_SLOT_CONDITIONAL) {
1166 1168 gen_delayed_conditional_jump(&ctx);
1167   - break;
1168   - case DELAY_SLOT:
  1169 + } else if (old_flags & DELAY_SLOT) {
1169 1170 gen_op_clr_delay_slot();
1170 1171 gen_jump(&ctx);
1171   - break;
1172   - case 0:
1173   - if (ctx.flags & BRANCH_EXCEPTION) {
1174   - gen_jump_exception(&ctx);
1175   - } else if ((ctx.flags & (BRANCH | BRANCH_CONDITIONAL)) == 0) {
1176   - gen_goto_tb(&ctx, 0, ctx.pc);
1177   - }
1178   - break;
1179   - default:
1180   - /* Both cannot be set at the same time */
1181   - assert(0);
  1172 + } else if (ctx.flags & BRANCH_EXCEPTION) {
  1173 + gen_jump_exception(&ctx);
  1174 + } else if ((ctx.flags & (BRANCH | BRANCH_CONDITIONAL)) == 0) {
  1175 + gen_goto_tb(&ctx, 0, ctx.pc);
1182 1176 }
1183 1177  
1184 1178 if (env->singlestep_enabled) {
... ...