Loading target-sh4/cpu.h +6 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ #include "cpu-defs.h" #include "softfloat.h" #define TARGET_PAGE_BITS 12 /* 4k XXXXX */ #define SR_MD (1 << 30) Loading Loading @@ -90,6 +92,10 @@ typedef struct CPUSH4State { uint32_t fpscr; /* floating point status/control register */ uint32_t fpul; /* floating point communication register */ /* temporary float registers */ float32 ft0, ft1; float64 dt0, dt1; /* Those belong to the specific unit (SH7750) but are handled here */ uint32_t mmucr; /* MMU control register */ uint32_t pteh; /* page table entry high register */ Loading target-sh4/exec.h +5 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,11 @@ register uint32_t T0 asm(AREG1); register uint32_t T1 asm(AREG2); register uint32_t T2 asm(AREG3); #define FT0 (env->ft0) #define FT1 (env->ft1) #define DT0 (env->dt0) #define DT1 (env->dt1) #include "cpu.h" #include "exec-all.h" Loading target-sh4/op.c +85 −1 Original line number Diff line number Diff line Loading @@ -228,6 +228,18 @@ void OPPROTO op_sett(void) RETURN(); } void OPPROTO op_frchg(void) { env->fpscr ^= FPSCR_FR; RETURN(); } void OPPROTO op_fschg(void) { env->fpscr ^= FPSCR_SZ; RETURN(); } void OPPROTO op_rte(void) { env->sr = env->ssr; Loading Loading @@ -465,6 +477,18 @@ void OPPROTO op_ldcl_rMplus_rN_bank(void) RETURN(); } void OPPROTO op_ldc_T0_sr(void) { env->sr = T0 & 0x700083f3; RETURN(); } void OPPROTO op_stc_sr_T0(void) { T0 = env->sr; RETURN(); } #define LDSTOPS(target,load,store) \ void OPPROTO op_##load##_T0_##target (void) \ { env ->target = T0; RETURN(); \ Loading @@ -473,7 +497,6 @@ void OPPROTO op_##store##_##target##_T0 (void) \ { T0 = env->target; RETURN(); \ } \ LDSTOPS(sr, ldc, stc) LDSTOPS(gbr, ldc, stc) LDSTOPS(vbr, ldc, stc) LDSTOPS(ssr, ldc, stc) Loading @@ -483,6 +506,19 @@ LDSTOPS(sr, ldc, stc) LDSTOPS(mach, lds, sts) LDSTOPS(macl, lds, sts) LDSTOPS(pr, lds, sts) LDSTOPS(fpul, lds, sts) void OPPROTO op_lds_T0_fpscr(void) { env->fpscr = T0 & 0x003fffff; RETURN(); } void OPPROTO op_sts_fpscr_T0(void) { T0 = env->fpscr & 0x003fffff; RETURN(); } void OPPROTO op_movt_rN(void) { Loading Loading @@ -659,6 +695,30 @@ void OPPROTO op_movl_imm_rN(void) RETURN(); } void OPPROTO op_fmov_frN_FT0(void) { FT0 = *(float32 *)&env->fregs[PARAM1]; RETURN(); } void OPPROTO op_fmov_drN_DT0(void) { DT0 = *(float64 *)&env->fregs[PARAM1]; RETURN(); } void OPPROTO op_fmov_FT0_frN(void) { *(float32 *)&env->fregs[PARAM1] = FT0; RETURN(); } void OPPROTO op_fmov_DT0_drN(void) { *(float64 *)&env->fregs[PARAM1] = DT0; RETURN(); } void OPPROTO op_dec1_rN(void) { env->gregs[PARAM1] -= 1; Loading @@ -677,6 +737,12 @@ void OPPROTO op_dec4_rN(void) RETURN(); } void OPPROTO op_dec8_rN(void) { env->gregs[PARAM1] -= 4; RETURN(); } void OPPROTO op_inc1_rN(void) { env->gregs[PARAM1] += 1; Loading @@ -695,6 +761,12 @@ void OPPROTO op_inc4_rN(void) RETURN(); } void OPPROTO op_inc8_rN(void) { env->gregs[PARAM1] += 4; RETURN(); } void OPPROTO op_add_T0_rN(void) { env->gregs[PARAM1] += T0; Loading Loading @@ -779,6 +851,18 @@ void OPPROTO op_movl_T0_T1(void) RETURN(); } void OPPROTO op_movl_fpul_FT0(void) { FT0 = *(float32 *)&env->fpul; RETURN(); } void OPPROTO op_movl_FT0_fpul(void) { *(float32 *)&env->fpul = FT0; RETURN(); } void OPPROTO op_goto_tb0(void) { GOTO_TB(op_goto_tb0, PARAM1, 0); Loading target-sh4/op_mem.c +20 −0 Original line number Diff line number Diff line Loading @@ -56,3 +56,23 @@ void glue(op_stl_T0_T1, MEMSUFFIX) (void) { glue(stl, MEMSUFFIX) (T1, T0); RETURN(); } void glue(op_ldfl_T0_FT0, MEMSUFFIX) (void) { FT0 = glue(ldfl, MEMSUFFIX) (T0); RETURN(); } void glue(op_stfl_FT0_T1, MEMSUFFIX) (void) { glue(stfl, MEMSUFFIX) (T1, FT0); RETURN(); } void glue(op_ldfq_T0_DT0, MEMSUFFIX) (void) { DT0 = glue(ldfq, MEMSUFFIX) (T0); RETURN(); } void glue(op_stfq_DT0_T1, MEMSUFFIX) (void) { glue(stfq, MEMSUFFIX) (T1, DT0); RETURN(); } target-sh4/translate.c +187 −37 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ typedef struct DisasContext { struct TranslationBlock *tb; target_ulong pc; uint32_t sr; uint32_t fpscr; uint16_t opcode; uint32_t flags; int memidx; Loading @@ -63,46 +64,50 @@ typedef struct DisasContext { #ifdef CONFIG_USER_ONLY #define GEN_OP_LD(width) \ void gen_op_ld##width##_T0_T0 (DisasContext *ctx) { \ gen_op_ld##width##_T0_T0_raw(); \ #define GEN_OP_LD(width, reg) \ void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \ gen_op_ld##width##_T0_##reg##_raw(); \ } #define GEN_OP_ST(width) \ void gen_op_st##width##_T0_T1 (DisasContext *ctx) { \ gen_op_st##width##_T0_T1_raw(); \ #define GEN_OP_ST(width, reg) \ void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \ gen_op_st##width##_##reg##_T1_raw(); \ } #else #define GEN_OP_LD(width) \ void gen_op_ld##width##_T0_T0 (DisasContext *ctx) { \ if (ctx->memidx) gen_op_ld##width##_T0_T0_kernel(); \ else gen_op_ld##width##_T0_T0_user();\ #define GEN_OP_LD(width, reg) \ void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \ if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \ else gen_op_ld##width##_T0_##reg##_user();\ } #define GEN_OP_ST(width) \ void gen_op_st##width##_T0_T1 (DisasContext *ctx) { \ if (ctx->memidx) gen_op_st##width##_T0_T1_kernel(); \ else gen_op_st##width##_T0_T1_user();\ #define GEN_OP_ST(width, reg) \ void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \ if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \ else gen_op_st##width##_##reg##_T1_user();\ } #endif GEN_OP_LD(ub) GEN_OP_LD(b) GEN_OP_ST(b) GEN_OP_LD(uw) GEN_OP_LD(w) GEN_OP_ST(w) GEN_OP_LD(l) GEN_OP_ST(l) GEN_OP_LD(ub, T0) GEN_OP_LD(b, T0) GEN_OP_ST(b, T0) GEN_OP_LD(uw, T0) GEN_OP_LD(w, T0) GEN_OP_ST(w, T0) GEN_OP_LD(l, T0) GEN_OP_ST(l, T0) GEN_OP_LD(fl, FT0) GEN_OP_ST(fl, FT0) GEN_OP_LD(fq, DT0) GEN_OP_ST(fq, DT0) void cpu_dump_state(CPUState * env, FILE * f, int (*cpu_fprintf) (FILE * f, const char *fmt, ...), int flags) { int i; cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x\n", env->pc, env->sr, env->pr); cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n", env->pc, env->sr, env->pr, env->fpscr); for (i = 0; i < 24; i += 4) { cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n", i, env->gregs[i], i + 1, env->gregs[i + 1], Loading Loading @@ -242,6 +247,10 @@ static void gen_delayed_conditional_jump(DisasContext * ctx) #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \ ? (x) + 16 : (x)) #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x)) #define XHACK(x) (((x) & 1 ) << 4 | ((x) & 0xe ) << 1) #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x)) #define CHECK_NOT_DELAY_SLOT \ if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \ {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \ Loading Loading @@ -286,10 +295,12 @@ void decode_opc(DisasContext * ctx) gen_op_sett(); return; case 0xfbfb: /* frchg */ assert(0); /* XXXXX */ gen_op_frchg(); ctx->flags |= MODE_CHANGE; return; case 0xf3fb: /* fschg */ assert(0); /* XXXXX */ gen_op_fschg(); ctx->flags |= MODE_CHANGE; return; case 0x0009: /* nop */ return; Loading Loading @@ -393,7 +404,7 @@ void decode_opc(DisasContext * ctx) gen_op_movl_rN_T1(REG(B11_8)); gen_op_stl_T0_T1(ctx); return; case 0x6004: /* mov.l @Rm+,Rn */ case 0x6004: /* mov.b @Rm+,Rn */ gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldb_T0_T0(ctx); gen_op_movl_T0_rN(REG(B11_8)); Loading Loading @@ -643,6 +654,134 @@ 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 */ if (ctx->fpscr & FPSCR_PR) { gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_fmov_DT0_drN(XREG(B11_8)); } 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)); } else { gen_op_fmov_frN_FT0(FREG(B7_4)); gen_op_fmov_FT0_frN(FREG(B11_8)); } return; case 0xf00a: /* fmov {F,D,X}Rm,@Rn */ if (ctx->fpscr & FPSCR_PR) { gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stfq_DT0_T1(ctx); } else if (ctx->fpscr & FPSCR_SZ) { if (ctx->opcode & 0x0010) break; /* illegal instruction */ gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stfq_DT0_T1(ctx); } else { gen_op_fmov_frN_FT0(FREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stfl_FT0_T1(ctx); } return; case 0xf008: /* fmov @Rm,{F,D,X}Rn */ if (ctx->fpscr & FPSCR_PR) { gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldfq_T0_DT0(ctx); gen_op_fmov_DT0_drN(XREG(B11_8)); } else if (ctx->fpscr & FPSCR_SZ) { if (ctx->opcode & 0x0100) 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)); } else { gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldfl_T0_FT0(ctx); gen_op_fmov_FT0_frN(XREG(B11_8)); } return; case 0xf009: /* fmov @Rm+,{F,D,X}Rn */ if (ctx->fpscr & FPSCR_PR) { gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldfq_T0_DT0(ctx); gen_op_fmov_DT0_drN(XREG(B11_8)); gen_op_inc8_rN(REG(B7_4)); } else if (ctx->fpscr & FPSCR_SZ) { if (ctx->opcode & 0x0100) 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_inc8_rN(REG(B7_4)); } 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_inc4_rN(REG(B7_4)); } return; case 0xf00b: /* fmov {F,D,X}Rm,@-Rn */ if (ctx->fpscr & FPSCR_PR) { gen_op_dec8_rN(REG(B11_8)); gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stfq_DT0_T1(ctx); } else if (ctx->fpscr & FPSCR_SZ) { if (ctx->opcode & 0x0100) break; /* illegal instruction */ gen_op_dec8_rN(REG(B11_8)); gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stfq_DT0_T1(ctx); } else { gen_op_dec4_rN(REG(B11_8)); gen_op_fmov_frN_FT0(FREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stfl_FT0_T1(ctx); } return; case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm */ if (ctx->fpscr & FPSCR_PR) { 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)); } else if (ctx->fpscr & FPSCR_SZ) { if (ctx->opcode & 0x0100) break; /* illegal instruction */ 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)); } else { 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)); } return; case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) */ if (ctx->fpscr & FPSCR_PR) { gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_add_rN_T1(REG(0)); gen_op_stfq_DT0_T1(ctx); } else if (ctx->fpscr & FPSCR_SZ) { if (ctx->opcode & 0x0010) break; /* illegal instruction */ gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_add_rN_T1(REG(0)); gen_op_stfq_DT0_T1(ctx); } else { gen_op_fmov_frN_FT0(FREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_add_rN_T1(REG(0)); gen_op_stfl_FT0_T1(ctx); } return; } switch (ctx->opcode & 0xff00) { Loading Loading @@ -869,8 +1008,7 @@ void decode_opc(DisasContext * ctx) gen_op_stl_T0_T1 (ctx); \ return; LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->flags |= MODE_CHANGE; ) MODE_CHANGE;) LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,) LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,) LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,) Loading @@ -879,6 +1017,9 @@ void decode_opc(DisasContext * ctx) LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,) LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,) LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,) LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x0052, sts,) LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x0062, sts, ctx->flags |= MODE_CHANGE;) case 0x00c3: /* movca.l R0,@Rm */ gen_op_movl_rN_T0(REG(0)); gen_op_movl_rN_T1(REG(B11_8)); Loading Loading @@ -944,6 +1085,14 @@ void decode_opc(DisasContext * ctx) case 0x401b: /* tas.b @Rn */ gen_op_tasb_rN(REG(B11_8)); return; case 0xf00d: /* fsts FPUL,FRn */ gen_op_movl_fpul_FT0(); gen_op_fmov_FT0_frN(FREG(B11_8)); return; case 0xf01d: /* flds FRm.FPUL */ gen_op_fmov_frN_FT0(FREG(B11_8)); gen_op_movl_FT0_fpul(); return; } fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n", Loading @@ -969,6 +1118,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, ctx.flags = env->flags; old_flags = 0; ctx.sr = env->sr; ctx.fpscr = env->fpscr; ctx.memidx = (env->sr & SR_MD) ? 1 : 0; ctx.delayed_pc = env->delayed_pc; ctx.tb = tb; Loading Loading
target-sh4/cpu.h +6 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ #include "cpu-defs.h" #include "softfloat.h" #define TARGET_PAGE_BITS 12 /* 4k XXXXX */ #define SR_MD (1 << 30) Loading Loading @@ -90,6 +92,10 @@ typedef struct CPUSH4State { uint32_t fpscr; /* floating point status/control register */ uint32_t fpul; /* floating point communication register */ /* temporary float registers */ float32 ft0, ft1; float64 dt0, dt1; /* Those belong to the specific unit (SH7750) but are handled here */ uint32_t mmucr; /* MMU control register */ uint32_t pteh; /* page table entry high register */ Loading
target-sh4/exec.h +5 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,11 @@ register uint32_t T0 asm(AREG1); register uint32_t T1 asm(AREG2); register uint32_t T2 asm(AREG3); #define FT0 (env->ft0) #define FT1 (env->ft1) #define DT0 (env->dt0) #define DT1 (env->dt1) #include "cpu.h" #include "exec-all.h" Loading
target-sh4/op.c +85 −1 Original line number Diff line number Diff line Loading @@ -228,6 +228,18 @@ void OPPROTO op_sett(void) RETURN(); } void OPPROTO op_frchg(void) { env->fpscr ^= FPSCR_FR; RETURN(); } void OPPROTO op_fschg(void) { env->fpscr ^= FPSCR_SZ; RETURN(); } void OPPROTO op_rte(void) { env->sr = env->ssr; Loading Loading @@ -465,6 +477,18 @@ void OPPROTO op_ldcl_rMplus_rN_bank(void) RETURN(); } void OPPROTO op_ldc_T0_sr(void) { env->sr = T0 & 0x700083f3; RETURN(); } void OPPROTO op_stc_sr_T0(void) { T0 = env->sr; RETURN(); } #define LDSTOPS(target,load,store) \ void OPPROTO op_##load##_T0_##target (void) \ { env ->target = T0; RETURN(); \ Loading @@ -473,7 +497,6 @@ void OPPROTO op_##store##_##target##_T0 (void) \ { T0 = env->target; RETURN(); \ } \ LDSTOPS(sr, ldc, stc) LDSTOPS(gbr, ldc, stc) LDSTOPS(vbr, ldc, stc) LDSTOPS(ssr, ldc, stc) Loading @@ -483,6 +506,19 @@ LDSTOPS(sr, ldc, stc) LDSTOPS(mach, lds, sts) LDSTOPS(macl, lds, sts) LDSTOPS(pr, lds, sts) LDSTOPS(fpul, lds, sts) void OPPROTO op_lds_T0_fpscr(void) { env->fpscr = T0 & 0x003fffff; RETURN(); } void OPPROTO op_sts_fpscr_T0(void) { T0 = env->fpscr & 0x003fffff; RETURN(); } void OPPROTO op_movt_rN(void) { Loading Loading @@ -659,6 +695,30 @@ void OPPROTO op_movl_imm_rN(void) RETURN(); } void OPPROTO op_fmov_frN_FT0(void) { FT0 = *(float32 *)&env->fregs[PARAM1]; RETURN(); } void OPPROTO op_fmov_drN_DT0(void) { DT0 = *(float64 *)&env->fregs[PARAM1]; RETURN(); } void OPPROTO op_fmov_FT0_frN(void) { *(float32 *)&env->fregs[PARAM1] = FT0; RETURN(); } void OPPROTO op_fmov_DT0_drN(void) { *(float64 *)&env->fregs[PARAM1] = DT0; RETURN(); } void OPPROTO op_dec1_rN(void) { env->gregs[PARAM1] -= 1; Loading @@ -677,6 +737,12 @@ void OPPROTO op_dec4_rN(void) RETURN(); } void OPPROTO op_dec8_rN(void) { env->gregs[PARAM1] -= 4; RETURN(); } void OPPROTO op_inc1_rN(void) { env->gregs[PARAM1] += 1; Loading @@ -695,6 +761,12 @@ void OPPROTO op_inc4_rN(void) RETURN(); } void OPPROTO op_inc8_rN(void) { env->gregs[PARAM1] += 4; RETURN(); } void OPPROTO op_add_T0_rN(void) { env->gregs[PARAM1] += T0; Loading Loading @@ -779,6 +851,18 @@ void OPPROTO op_movl_T0_T1(void) RETURN(); } void OPPROTO op_movl_fpul_FT0(void) { FT0 = *(float32 *)&env->fpul; RETURN(); } void OPPROTO op_movl_FT0_fpul(void) { *(float32 *)&env->fpul = FT0; RETURN(); } void OPPROTO op_goto_tb0(void) { GOTO_TB(op_goto_tb0, PARAM1, 0); Loading
target-sh4/op_mem.c +20 −0 Original line number Diff line number Diff line Loading @@ -56,3 +56,23 @@ void glue(op_stl_T0_T1, MEMSUFFIX) (void) { glue(stl, MEMSUFFIX) (T1, T0); RETURN(); } void glue(op_ldfl_T0_FT0, MEMSUFFIX) (void) { FT0 = glue(ldfl, MEMSUFFIX) (T0); RETURN(); } void glue(op_stfl_FT0_T1, MEMSUFFIX) (void) { glue(stfl, MEMSUFFIX) (T1, FT0); RETURN(); } void glue(op_ldfq_T0_DT0, MEMSUFFIX) (void) { DT0 = glue(ldfq, MEMSUFFIX) (T0); RETURN(); } void glue(op_stfq_DT0_T1, MEMSUFFIX) (void) { glue(stfq, MEMSUFFIX) (T1, DT0); RETURN(); }
target-sh4/translate.c +187 −37 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ typedef struct DisasContext { struct TranslationBlock *tb; target_ulong pc; uint32_t sr; uint32_t fpscr; uint16_t opcode; uint32_t flags; int memidx; Loading @@ -63,46 +64,50 @@ typedef struct DisasContext { #ifdef CONFIG_USER_ONLY #define GEN_OP_LD(width) \ void gen_op_ld##width##_T0_T0 (DisasContext *ctx) { \ gen_op_ld##width##_T0_T0_raw(); \ #define GEN_OP_LD(width, reg) \ void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \ gen_op_ld##width##_T0_##reg##_raw(); \ } #define GEN_OP_ST(width) \ void gen_op_st##width##_T0_T1 (DisasContext *ctx) { \ gen_op_st##width##_T0_T1_raw(); \ #define GEN_OP_ST(width, reg) \ void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \ gen_op_st##width##_##reg##_T1_raw(); \ } #else #define GEN_OP_LD(width) \ void gen_op_ld##width##_T0_T0 (DisasContext *ctx) { \ if (ctx->memidx) gen_op_ld##width##_T0_T0_kernel(); \ else gen_op_ld##width##_T0_T0_user();\ #define GEN_OP_LD(width, reg) \ void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \ if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \ else gen_op_ld##width##_T0_##reg##_user();\ } #define GEN_OP_ST(width) \ void gen_op_st##width##_T0_T1 (DisasContext *ctx) { \ if (ctx->memidx) gen_op_st##width##_T0_T1_kernel(); \ else gen_op_st##width##_T0_T1_user();\ #define GEN_OP_ST(width, reg) \ void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \ if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \ else gen_op_st##width##_##reg##_T1_user();\ } #endif GEN_OP_LD(ub) GEN_OP_LD(b) GEN_OP_ST(b) GEN_OP_LD(uw) GEN_OP_LD(w) GEN_OP_ST(w) GEN_OP_LD(l) GEN_OP_ST(l) GEN_OP_LD(ub, T0) GEN_OP_LD(b, T0) GEN_OP_ST(b, T0) GEN_OP_LD(uw, T0) GEN_OP_LD(w, T0) GEN_OP_ST(w, T0) GEN_OP_LD(l, T0) GEN_OP_ST(l, T0) GEN_OP_LD(fl, FT0) GEN_OP_ST(fl, FT0) GEN_OP_LD(fq, DT0) GEN_OP_ST(fq, DT0) void cpu_dump_state(CPUState * env, FILE * f, int (*cpu_fprintf) (FILE * f, const char *fmt, ...), int flags) { int i; cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x\n", env->pc, env->sr, env->pr); cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n", env->pc, env->sr, env->pr, env->fpscr); for (i = 0; i < 24; i += 4) { cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n", i, env->gregs[i], i + 1, env->gregs[i + 1], Loading Loading @@ -242,6 +247,10 @@ static void gen_delayed_conditional_jump(DisasContext * ctx) #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \ ? (x) + 16 : (x)) #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x)) #define XHACK(x) (((x) & 1 ) << 4 | ((x) & 0xe ) << 1) #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x)) #define CHECK_NOT_DELAY_SLOT \ if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \ {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \ Loading Loading @@ -286,10 +295,12 @@ void decode_opc(DisasContext * ctx) gen_op_sett(); return; case 0xfbfb: /* frchg */ assert(0); /* XXXXX */ gen_op_frchg(); ctx->flags |= MODE_CHANGE; return; case 0xf3fb: /* fschg */ assert(0); /* XXXXX */ gen_op_fschg(); ctx->flags |= MODE_CHANGE; return; case 0x0009: /* nop */ return; Loading Loading @@ -393,7 +404,7 @@ void decode_opc(DisasContext * ctx) gen_op_movl_rN_T1(REG(B11_8)); gen_op_stl_T0_T1(ctx); return; case 0x6004: /* mov.l @Rm+,Rn */ case 0x6004: /* mov.b @Rm+,Rn */ gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldb_T0_T0(ctx); gen_op_movl_T0_rN(REG(B11_8)); Loading Loading @@ -643,6 +654,134 @@ 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 */ if (ctx->fpscr & FPSCR_PR) { gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_fmov_DT0_drN(XREG(B11_8)); } 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)); } else { gen_op_fmov_frN_FT0(FREG(B7_4)); gen_op_fmov_FT0_frN(FREG(B11_8)); } return; case 0xf00a: /* fmov {F,D,X}Rm,@Rn */ if (ctx->fpscr & FPSCR_PR) { gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stfq_DT0_T1(ctx); } else if (ctx->fpscr & FPSCR_SZ) { if (ctx->opcode & 0x0010) break; /* illegal instruction */ gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stfq_DT0_T1(ctx); } else { gen_op_fmov_frN_FT0(FREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stfl_FT0_T1(ctx); } return; case 0xf008: /* fmov @Rm,{F,D,X}Rn */ if (ctx->fpscr & FPSCR_PR) { gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldfq_T0_DT0(ctx); gen_op_fmov_DT0_drN(XREG(B11_8)); } else if (ctx->fpscr & FPSCR_SZ) { if (ctx->opcode & 0x0100) 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)); } else { gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldfl_T0_FT0(ctx); gen_op_fmov_FT0_frN(XREG(B11_8)); } return; case 0xf009: /* fmov @Rm+,{F,D,X}Rn */ if (ctx->fpscr & FPSCR_PR) { gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldfq_T0_DT0(ctx); gen_op_fmov_DT0_drN(XREG(B11_8)); gen_op_inc8_rN(REG(B7_4)); } else if (ctx->fpscr & FPSCR_SZ) { if (ctx->opcode & 0x0100) 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_inc8_rN(REG(B7_4)); } 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_inc4_rN(REG(B7_4)); } return; case 0xf00b: /* fmov {F,D,X}Rm,@-Rn */ if (ctx->fpscr & FPSCR_PR) { gen_op_dec8_rN(REG(B11_8)); gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stfq_DT0_T1(ctx); } else if (ctx->fpscr & FPSCR_SZ) { if (ctx->opcode & 0x0100) break; /* illegal instruction */ gen_op_dec8_rN(REG(B11_8)); gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stfq_DT0_T1(ctx); } else { gen_op_dec4_rN(REG(B11_8)); gen_op_fmov_frN_FT0(FREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stfl_FT0_T1(ctx); } return; case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm */ if (ctx->fpscr & FPSCR_PR) { 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)); } else if (ctx->fpscr & FPSCR_SZ) { if (ctx->opcode & 0x0100) break; /* illegal instruction */ 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)); } else { 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)); } return; case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) */ if (ctx->fpscr & FPSCR_PR) { gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_add_rN_T1(REG(0)); gen_op_stfq_DT0_T1(ctx); } else if (ctx->fpscr & FPSCR_SZ) { if (ctx->opcode & 0x0010) break; /* illegal instruction */ gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_add_rN_T1(REG(0)); gen_op_stfq_DT0_T1(ctx); } else { gen_op_fmov_frN_FT0(FREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_add_rN_T1(REG(0)); gen_op_stfl_FT0_T1(ctx); } return; } switch (ctx->opcode & 0xff00) { Loading Loading @@ -869,8 +1008,7 @@ void decode_opc(DisasContext * ctx) gen_op_stl_T0_T1 (ctx); \ return; LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->flags |= MODE_CHANGE; ) MODE_CHANGE;) LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,) LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,) LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,) Loading @@ -879,6 +1017,9 @@ void decode_opc(DisasContext * ctx) LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,) LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,) LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,) LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x0052, sts,) LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x0062, sts, ctx->flags |= MODE_CHANGE;) case 0x00c3: /* movca.l R0,@Rm */ gen_op_movl_rN_T0(REG(0)); gen_op_movl_rN_T1(REG(B11_8)); Loading Loading @@ -944,6 +1085,14 @@ void decode_opc(DisasContext * ctx) case 0x401b: /* tas.b @Rn */ gen_op_tasb_rN(REG(B11_8)); return; case 0xf00d: /* fsts FPUL,FRn */ gen_op_movl_fpul_FT0(); gen_op_fmov_FT0_frN(FREG(B11_8)); return; case 0xf01d: /* flds FRm.FPUL */ gen_op_fmov_frN_FT0(FREG(B11_8)); gen_op_movl_FT0_fpul(); return; } fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n", Loading @@ -969,6 +1118,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, ctx.flags = env->flags; old_flags = 0; ctx.sr = env->sr; ctx.fpscr = env->fpscr; ctx.memidx = (env->sr & SR_MD) ? 1 : 0; ctx.delayed_pc = env->delayed_pc; ctx.tb = tb; Loading