Loading target-sh4/exec.h +0 −4 Original line number Diff line number Diff line Loading @@ -71,10 +71,6 @@ int find_itlb_entry(CPUState * env, target_ulong address, int use_asid, int update); int find_utlb_entry(CPUState * env, target_ulong address, int use_asid); void helper_div1_T0_T1(void); void helper_rotcl(uint32_t * addr); void helper_rotcr(uint32_t * addr); void do_interrupt(CPUState * env); void cpu_loop_exit(void); Loading target-sh4/helper.h +1 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ DEF_HELPER(uint32_t, helper_addc, (uint32_t, uint32_t)) DEF_HELPER(uint32_t, helper_subv, (uint32_t, uint32_t)) DEF_HELPER(uint32_t, helper_subc, (uint32_t, uint32_t)) DEF_HELPER(uint32_t, helper_negc, (uint32_t)) DEF_HELPER(uint32_t, helper_div1, (uint32_t, uint32_t)) DEF_HELPER(void, helper_macl, (uint32_t, uint32_t)) DEF_HELPER(void, helper_macw, (uint32_t, uint32_t)) Loading target-sh4/op.c +0 −78 Original line number Diff line number Diff line Loading @@ -37,84 +37,6 @@ static inline void cond_t(int cond) clr_t(); } void OPPROTO op_cmp_str_T0_T1(void) { cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) || (T0 & 0x0000ff00) == (T1 & 0x0000ff00) || (T0 & 0x00ff0000) == (T1 & 0x00ff0000) || (T0 & 0xff000000) == (T1 & 0xff000000)); RETURN(); } void OPPROTO op_div0s_T0_T1(void) { if (T1 & 0x80000000) env->sr |= SR_Q; else env->sr &= ~SR_Q; if (T0 & 0x80000000) env->sr |= SR_M; else env->sr &= ~SR_M; cond_t((T1 ^ T0) & 0x80000000); RETURN(); } void OPPROTO op_div1_T0_T1(void) { helper_div1_T0_T1(); RETURN(); } void OPPROTO op_shad_T0_T1(void) { if ((T0 & 0x80000000) == 0) T1 <<= (T0 & 0x1f); else if ((T0 & 0x1f) == 0) T1 = (T1 & 0x80000000)? 0xffffffff : 0; else T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1); RETURN(); } void OPPROTO op_shld_T0_T1(void) { if ((T0 & 0x80000000) == 0) T1 <<= (T0 & 0x1f); else if ((T0 & 0x1f) == 0) T1 = 0; else T1 = ((uint32_t) T1) >> ((~T0 & 0x1f) + 1); RETURN(); } void OPPROTO op_rotcl_Rn(void) { helper_rotcl(&env->gregs[PARAM1]); RETURN(); } void OPPROTO op_rotcr_Rn(void) { helper_rotcr(&env->gregs[PARAM1]); RETURN(); } void OPPROTO op_rotl_Rn(void) { cond_t(env->gregs[PARAM1] & 0x80000000); env->gregs[PARAM1] = (env->gregs[PARAM1] << 1) | (env->sr & SR_T); RETURN(); } void OPPROTO op_rotr_Rn(void) { cond_t(env->gregs[PARAM1] & 1); env->gregs[PARAM1] = (env->gregs[PARAM1] >> 1) | ((env->sr & SR_T) ? 0x80000000 : 0); RETURN(); } void OPPROTO op_fmov_frN_FT0(void) { FT0 = env->fregs[PARAM1]; Loading target-sh4/op_helper.c +20 −43 Original line number Diff line number Diff line Loading @@ -163,27 +163,27 @@ uint32_t helper_addv(uint32_t arg0, uint32_t arg1) #define SETM env->sr |= SR_M #define CLRM env->sr &= ~SR_M void helper_div1_T0_T1(void) uint32_t helper_div1(uint32_t arg0, uint32_t arg1) { uint32_t tmp0, tmp2; uint8_t old_q, tmp1 = 0xff; //printf("div1 T0=0x%08x T1=0x%08x M=%d Q=%d T=%d\n", T0, T1, M, Q, T); //printf("div1 arg0=0x%08x arg1=0x%08x M=%d Q=%d T=%d\n", arg0, arg1, M, Q, T); old_q = Q; if ((0x80000000 & T1) != 0) if ((0x80000000 & arg1) != 0) SETQ; else CLRQ; tmp2 = T0; T1 <<= 1; T1 |= T; tmp2 = arg0; arg1 <<= 1; arg1 |= T; switch (old_q) { case 0: switch (M) { case 0: tmp0 = T1; T1 -= tmp2; tmp1 = T1 > tmp0; tmp0 = arg1; arg1 -= tmp2; tmp1 = arg1 > tmp0; switch (Q) { case 0: if (tmp1) Loading @@ -200,9 +200,9 @@ void helper_div1_T0_T1(void) } break; case 1: tmp0 = T1; T1 += tmp2; tmp1 = T1 < tmp0; tmp0 = arg1; arg1 += tmp2; tmp1 = arg1 < tmp0; switch (Q) { case 0: if (tmp1 == 0) Loading @@ -223,9 +223,9 @@ void helper_div1_T0_T1(void) case 1: switch (M) { case 0: tmp0 = T1; T1 += tmp2; tmp1 = T1 < tmp0; tmp0 = arg1; arg1 += tmp2; tmp1 = arg1 < tmp0; switch (Q) { case 0: if (tmp1) Loading @@ -242,9 +242,9 @@ void helper_div1_T0_T1(void) } break; case 1: tmp0 = T1; T1 -= tmp2; tmp1 = T1 > tmp0; tmp0 = arg1; arg1 -= tmp2; tmp1 = arg1 > tmp0; switch (Q) { case 0: if (tmp1 == 0) Loading @@ -267,7 +267,8 @@ void helper_div1_T0_T1(void) SETT; else CLRT; //printf("Output: T1=0x%08x M=%d Q=%d T=%d\n", T1, M, Q, T); //printf("Output: arg1=0x%08x M=%d Q=%d T=%d\n", arg1, M, Q, T); return arg1; } void helper_macl(uint32_t arg0, uint32_t arg1) Loading Loading @@ -365,30 +366,6 @@ uint32_t helper_subv(uint32_t arg0, uint32_t arg1) return arg1; } void helper_rotcl(uint32_t * addr) { uint32_t new; new = (*addr << 1) | (env->sr & SR_T); if (*addr & 0x80000000) env->sr |= SR_T; else env->sr &= ~SR_T; *addr = new; } void helper_rotcr(uint32_t * addr) { uint32_t new; new = (*addr >> 1) | ((env->sr & SR_T) ? 0x80000000 : 0); if (*addr & 1) env->sr |= SR_T; else env->sr &= ~SR_T; *addr = new; } void helper_ld_fpscr(uint32_t val) { env->fpscr = val & 0x003fffff; Loading target-sh4/translate.c +109 −28 Original line number Diff line number Diff line Loading @@ -337,6 +337,24 @@ static inline void gen_store_flags(uint32_t flags) tcg_gen_ori_i32(cpu_flags, cpu_flags, flags); } static inline void gen_copy_bit_i32(TCGv t0, int p0, TCGv t1, int p1) { TCGv tmp = tcg_temp_new(TCG_TYPE_I32); p0 &= 0x1f; p1 &= 0x1f; tcg_gen_andi_i32(tmp, t1, (1 << p1)); tcg_gen_andi_i32(t0, t0, ~(1 << p0)); if (p0 < p1) tcg_gen_shri_i32(tmp, tmp, p1 - p0); else if (p0 > p1) tcg_gen_shli_i32(tmp, tmp, p0 - p1); tcg_gen_or_i32(t0, t0, tmp); tcg_temp_free(tmp); } #define B3_0 (ctx->opcode & 0xf) #define B6_4 ((ctx->opcode >> 4) & 0x7) #define B7_4 ((ctx->opcode >> 4) & 0xf) Loading Loading @@ -643,20 +661,33 @@ void _decode_opc(DisasContext * ctx) gen_cmp(TCG_COND_GEU, cpu_T[0], cpu_T[1]); return; case 0x200c: /* cmp/str Rm,Rn */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); gen_op_cmp_str_T0_T1(); { int label1 = gen_new_label(); int label2 = gen_new_label(); tcg_gen_xor_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]); tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff000000); tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1); tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x00ff0000); tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1); tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x0000ff00); tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1); tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x000000ff); tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1); tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T); tcg_gen_br(label2); gen_set_label(label1); tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T); gen_set_label(label2); } return; case 0x2007: /* div0s Rm,Rn */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); gen_op_div0s_T0_T1(); gen_copy_bit_i32(cpu_sr, 8, cpu_gregs[REG(B11_8)], 31); /* SR_Q */ gen_copy_bit_i32(cpu_sr, 9, cpu_gregs[REG(B7_4)], 31); /* SR_M */ tcg_gen_xor_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]); gen_copy_bit_i32(cpu_sr, 0, cpu_T[0], 31); /* SR_T */ return; case 0x3004: /* div1 Rm,Rn */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); gen_op_div1_T0_T1(); tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]); tcg_gen_helper_1_2(helper_div1, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]); return; case 0x300d: /* dmuls.l Rm,Rn */ { Loading Loading @@ -758,16 +789,59 @@ void _decode_opc(DisasContext * ctx) tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]); return; case 0x400c: /* shad Rm,Rn */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); gen_op_shad_T0_T1(); tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]); { int label1 = gen_new_label(); int label2 = gen_new_label(); int label3 = gen_new_label(); int label4 = gen_new_label(); tcg_gen_brcondi_i32(TCG_COND_LT, cpu_gregs[REG(B7_4)], 0, label1); /* Rm positive, shift to the left */ tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0x1f); tcg_gen_shl_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]); tcg_gen_br(label4); /* Rm negative, shift to the right */ gen_set_label(label1); tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0x1f); tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label2); tcg_gen_not_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x1f); tcg_gen_addi_i32(cpu_T[0], cpu_T[0], 1); tcg_gen_sar_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]); tcg_gen_br(label4); /* Rm = -32 */ gen_set_label(label2); tcg_gen_brcondi_i32(TCG_COND_LT, cpu_gregs[REG(B11_8)], 0, label3); tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], 0); tcg_gen_br(label4); gen_set_label(label3); tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], 0xffffffff); gen_set_label(label4); } return; case 0x400d: /* shld Rm,Rn */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); gen_op_shld_T0_T1(); tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]); { int label1 = gen_new_label(); int label2 = gen_new_label(); int label3 = gen_new_label(); tcg_gen_brcondi_i32(TCG_COND_LT, cpu_gregs[REG(B7_4)], 0, label1); /* Rm positive, shift to the left */ tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0x1f); tcg_gen_shl_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]); tcg_gen_br(label3); /* Rm negative, shift to the right */ gen_set_label(label1); tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0x1f); tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label2); tcg_gen_not_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x1f); tcg_gen_addi_i32(cpu_T[0], cpu_T[0], 1); tcg_gen_shr_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]); tcg_gen_br(label3); /* Rm = -32 */ gen_set_label(label2); tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], 0); gen_set_label(label3); } return; case 0x3008: /* sub Rm,Rn */ tcg_gen_sub_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]); Loading Loading @@ -1213,31 +1287,38 @@ void _decode_opc(DisasContext * ctx) case 0x0083: /* pref @Rn */ return; case 0x4024: /* rotcl Rn */ gen_op_rotcl_Rn(REG(B11_8)); tcg_gen_mov_i32(cpu_T[0], cpu_sr); gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 31); tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1); gen_copy_bit_i32(cpu_gregs[REG(B11_8)], 0, cpu_T[0], 0); return; case 0x4025: /* rotcr Rn */ gen_op_rotcr_Rn(REG(B11_8)); tcg_gen_mov_i32(cpu_T[0], cpu_sr); gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0); tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1); gen_copy_bit_i32(cpu_gregs[REG(B11_8)], 31, cpu_T[0], 0); return; case 0x4004: /* rotl Rn */ gen_op_rotl_Rn(REG(B11_8)); gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 31); tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1); gen_copy_bit_i32(cpu_gregs[REG(B11_8)], 0, cpu_sr, 0); return; case 0x4005: /* rotr Rn */ gen_op_rotr_Rn(REG(B11_8)); gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0); tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1); gen_copy_bit_i32(cpu_gregs[REG(B11_8)], 31, cpu_sr, 0); return; case 0x4000: /* shll Rn */ case 0x4020: /* shal Rn */ tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B11_8)], 0x80000000); gen_cmp_imm(TCG_COND_NE, cpu_T[0], 0); gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 31); tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1); return; case 0x4021: /* shar Rn */ tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B11_8)], 1); gen_cmp_imm(TCG_COND_NE, cpu_T[0], 0); gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0); tcg_gen_sari_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1); return; case 0x4001: /* shlr Rn */ tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B11_8)], 1); gen_cmp_imm(TCG_COND_NE, cpu_T[0], 0); gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0); tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1); return; case 0x4008: /* shll2 Rn */ Loading Loading
target-sh4/exec.h +0 −4 Original line number Diff line number Diff line Loading @@ -71,10 +71,6 @@ int find_itlb_entry(CPUState * env, target_ulong address, int use_asid, int update); int find_utlb_entry(CPUState * env, target_ulong address, int use_asid); void helper_div1_T0_T1(void); void helper_rotcl(uint32_t * addr); void helper_rotcr(uint32_t * addr); void do_interrupt(CPUState * env); void cpu_loop_exit(void); Loading
target-sh4/helper.h +1 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ DEF_HELPER(uint32_t, helper_addc, (uint32_t, uint32_t)) DEF_HELPER(uint32_t, helper_subv, (uint32_t, uint32_t)) DEF_HELPER(uint32_t, helper_subc, (uint32_t, uint32_t)) DEF_HELPER(uint32_t, helper_negc, (uint32_t)) DEF_HELPER(uint32_t, helper_div1, (uint32_t, uint32_t)) DEF_HELPER(void, helper_macl, (uint32_t, uint32_t)) DEF_HELPER(void, helper_macw, (uint32_t, uint32_t)) Loading
target-sh4/op.c +0 −78 Original line number Diff line number Diff line Loading @@ -37,84 +37,6 @@ static inline void cond_t(int cond) clr_t(); } void OPPROTO op_cmp_str_T0_T1(void) { cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) || (T0 & 0x0000ff00) == (T1 & 0x0000ff00) || (T0 & 0x00ff0000) == (T1 & 0x00ff0000) || (T0 & 0xff000000) == (T1 & 0xff000000)); RETURN(); } void OPPROTO op_div0s_T0_T1(void) { if (T1 & 0x80000000) env->sr |= SR_Q; else env->sr &= ~SR_Q; if (T0 & 0x80000000) env->sr |= SR_M; else env->sr &= ~SR_M; cond_t((T1 ^ T0) & 0x80000000); RETURN(); } void OPPROTO op_div1_T0_T1(void) { helper_div1_T0_T1(); RETURN(); } void OPPROTO op_shad_T0_T1(void) { if ((T0 & 0x80000000) == 0) T1 <<= (T0 & 0x1f); else if ((T0 & 0x1f) == 0) T1 = (T1 & 0x80000000)? 0xffffffff : 0; else T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1); RETURN(); } void OPPROTO op_shld_T0_T1(void) { if ((T0 & 0x80000000) == 0) T1 <<= (T0 & 0x1f); else if ((T0 & 0x1f) == 0) T1 = 0; else T1 = ((uint32_t) T1) >> ((~T0 & 0x1f) + 1); RETURN(); } void OPPROTO op_rotcl_Rn(void) { helper_rotcl(&env->gregs[PARAM1]); RETURN(); } void OPPROTO op_rotcr_Rn(void) { helper_rotcr(&env->gregs[PARAM1]); RETURN(); } void OPPROTO op_rotl_Rn(void) { cond_t(env->gregs[PARAM1] & 0x80000000); env->gregs[PARAM1] = (env->gregs[PARAM1] << 1) | (env->sr & SR_T); RETURN(); } void OPPROTO op_rotr_Rn(void) { cond_t(env->gregs[PARAM1] & 1); env->gregs[PARAM1] = (env->gregs[PARAM1] >> 1) | ((env->sr & SR_T) ? 0x80000000 : 0); RETURN(); } void OPPROTO op_fmov_frN_FT0(void) { FT0 = env->fregs[PARAM1]; Loading
target-sh4/op_helper.c +20 −43 Original line number Diff line number Diff line Loading @@ -163,27 +163,27 @@ uint32_t helper_addv(uint32_t arg0, uint32_t arg1) #define SETM env->sr |= SR_M #define CLRM env->sr &= ~SR_M void helper_div1_T0_T1(void) uint32_t helper_div1(uint32_t arg0, uint32_t arg1) { uint32_t tmp0, tmp2; uint8_t old_q, tmp1 = 0xff; //printf("div1 T0=0x%08x T1=0x%08x M=%d Q=%d T=%d\n", T0, T1, M, Q, T); //printf("div1 arg0=0x%08x arg1=0x%08x M=%d Q=%d T=%d\n", arg0, arg1, M, Q, T); old_q = Q; if ((0x80000000 & T1) != 0) if ((0x80000000 & arg1) != 0) SETQ; else CLRQ; tmp2 = T0; T1 <<= 1; T1 |= T; tmp2 = arg0; arg1 <<= 1; arg1 |= T; switch (old_q) { case 0: switch (M) { case 0: tmp0 = T1; T1 -= tmp2; tmp1 = T1 > tmp0; tmp0 = arg1; arg1 -= tmp2; tmp1 = arg1 > tmp0; switch (Q) { case 0: if (tmp1) Loading @@ -200,9 +200,9 @@ void helper_div1_T0_T1(void) } break; case 1: tmp0 = T1; T1 += tmp2; tmp1 = T1 < tmp0; tmp0 = arg1; arg1 += tmp2; tmp1 = arg1 < tmp0; switch (Q) { case 0: if (tmp1 == 0) Loading @@ -223,9 +223,9 @@ void helper_div1_T0_T1(void) case 1: switch (M) { case 0: tmp0 = T1; T1 += tmp2; tmp1 = T1 < tmp0; tmp0 = arg1; arg1 += tmp2; tmp1 = arg1 < tmp0; switch (Q) { case 0: if (tmp1) Loading @@ -242,9 +242,9 @@ void helper_div1_T0_T1(void) } break; case 1: tmp0 = T1; T1 -= tmp2; tmp1 = T1 > tmp0; tmp0 = arg1; arg1 -= tmp2; tmp1 = arg1 > tmp0; switch (Q) { case 0: if (tmp1 == 0) Loading @@ -267,7 +267,8 @@ void helper_div1_T0_T1(void) SETT; else CLRT; //printf("Output: T1=0x%08x M=%d Q=%d T=%d\n", T1, M, Q, T); //printf("Output: arg1=0x%08x M=%d Q=%d T=%d\n", arg1, M, Q, T); return arg1; } void helper_macl(uint32_t arg0, uint32_t arg1) Loading Loading @@ -365,30 +366,6 @@ uint32_t helper_subv(uint32_t arg0, uint32_t arg1) return arg1; } void helper_rotcl(uint32_t * addr) { uint32_t new; new = (*addr << 1) | (env->sr & SR_T); if (*addr & 0x80000000) env->sr |= SR_T; else env->sr &= ~SR_T; *addr = new; } void helper_rotcr(uint32_t * addr) { uint32_t new; new = (*addr >> 1) | ((env->sr & SR_T) ? 0x80000000 : 0); if (*addr & 1) env->sr |= SR_T; else env->sr &= ~SR_T; *addr = new; } void helper_ld_fpscr(uint32_t val) { env->fpscr = val & 0x003fffff; Loading
target-sh4/translate.c +109 −28 Original line number Diff line number Diff line Loading @@ -337,6 +337,24 @@ static inline void gen_store_flags(uint32_t flags) tcg_gen_ori_i32(cpu_flags, cpu_flags, flags); } static inline void gen_copy_bit_i32(TCGv t0, int p0, TCGv t1, int p1) { TCGv tmp = tcg_temp_new(TCG_TYPE_I32); p0 &= 0x1f; p1 &= 0x1f; tcg_gen_andi_i32(tmp, t1, (1 << p1)); tcg_gen_andi_i32(t0, t0, ~(1 << p0)); if (p0 < p1) tcg_gen_shri_i32(tmp, tmp, p1 - p0); else if (p0 > p1) tcg_gen_shli_i32(tmp, tmp, p0 - p1); tcg_gen_or_i32(t0, t0, tmp); tcg_temp_free(tmp); } #define B3_0 (ctx->opcode & 0xf) #define B6_4 ((ctx->opcode >> 4) & 0x7) #define B7_4 ((ctx->opcode >> 4) & 0xf) Loading Loading @@ -643,20 +661,33 @@ void _decode_opc(DisasContext * ctx) gen_cmp(TCG_COND_GEU, cpu_T[0], cpu_T[1]); return; case 0x200c: /* cmp/str Rm,Rn */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); gen_op_cmp_str_T0_T1(); { int label1 = gen_new_label(); int label2 = gen_new_label(); tcg_gen_xor_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]); tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff000000); tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1); tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x00ff0000); tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1); tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x0000ff00); tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1); tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x000000ff); tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1); tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T); tcg_gen_br(label2); gen_set_label(label1); tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T); gen_set_label(label2); } return; case 0x2007: /* div0s Rm,Rn */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); gen_op_div0s_T0_T1(); gen_copy_bit_i32(cpu_sr, 8, cpu_gregs[REG(B11_8)], 31); /* SR_Q */ gen_copy_bit_i32(cpu_sr, 9, cpu_gregs[REG(B7_4)], 31); /* SR_M */ tcg_gen_xor_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]); gen_copy_bit_i32(cpu_sr, 0, cpu_T[0], 31); /* SR_T */ return; case 0x3004: /* div1 Rm,Rn */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); gen_op_div1_T0_T1(); tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]); tcg_gen_helper_1_2(helper_div1, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]); return; case 0x300d: /* dmuls.l Rm,Rn */ { Loading Loading @@ -758,16 +789,59 @@ void _decode_opc(DisasContext * ctx) tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]); return; case 0x400c: /* shad Rm,Rn */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); gen_op_shad_T0_T1(); tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]); { int label1 = gen_new_label(); int label2 = gen_new_label(); int label3 = gen_new_label(); int label4 = gen_new_label(); tcg_gen_brcondi_i32(TCG_COND_LT, cpu_gregs[REG(B7_4)], 0, label1); /* Rm positive, shift to the left */ tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0x1f); tcg_gen_shl_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]); tcg_gen_br(label4); /* Rm negative, shift to the right */ gen_set_label(label1); tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0x1f); tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label2); tcg_gen_not_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x1f); tcg_gen_addi_i32(cpu_T[0], cpu_T[0], 1); tcg_gen_sar_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]); tcg_gen_br(label4); /* Rm = -32 */ gen_set_label(label2); tcg_gen_brcondi_i32(TCG_COND_LT, cpu_gregs[REG(B11_8)], 0, label3); tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], 0); tcg_gen_br(label4); gen_set_label(label3); tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], 0xffffffff); gen_set_label(label4); } return; case 0x400d: /* shld Rm,Rn */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); gen_op_shld_T0_T1(); tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]); { int label1 = gen_new_label(); int label2 = gen_new_label(); int label3 = gen_new_label(); tcg_gen_brcondi_i32(TCG_COND_LT, cpu_gregs[REG(B7_4)], 0, label1); /* Rm positive, shift to the left */ tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0x1f); tcg_gen_shl_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]); tcg_gen_br(label3); /* Rm negative, shift to the right */ gen_set_label(label1); tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0x1f); tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label2); tcg_gen_not_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x1f); tcg_gen_addi_i32(cpu_T[0], cpu_T[0], 1); tcg_gen_shr_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]); tcg_gen_br(label3); /* Rm = -32 */ gen_set_label(label2); tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], 0); gen_set_label(label3); } return; case 0x3008: /* sub Rm,Rn */ tcg_gen_sub_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]); Loading Loading @@ -1213,31 +1287,38 @@ void _decode_opc(DisasContext * ctx) case 0x0083: /* pref @Rn */ return; case 0x4024: /* rotcl Rn */ gen_op_rotcl_Rn(REG(B11_8)); tcg_gen_mov_i32(cpu_T[0], cpu_sr); gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 31); tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1); gen_copy_bit_i32(cpu_gregs[REG(B11_8)], 0, cpu_T[0], 0); return; case 0x4025: /* rotcr Rn */ gen_op_rotcr_Rn(REG(B11_8)); tcg_gen_mov_i32(cpu_T[0], cpu_sr); gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0); tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1); gen_copy_bit_i32(cpu_gregs[REG(B11_8)], 31, cpu_T[0], 0); return; case 0x4004: /* rotl Rn */ gen_op_rotl_Rn(REG(B11_8)); gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 31); tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1); gen_copy_bit_i32(cpu_gregs[REG(B11_8)], 0, cpu_sr, 0); return; case 0x4005: /* rotr Rn */ gen_op_rotr_Rn(REG(B11_8)); gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0); tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1); gen_copy_bit_i32(cpu_gregs[REG(B11_8)], 31, cpu_sr, 0); return; case 0x4000: /* shll Rn */ case 0x4020: /* shal Rn */ tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B11_8)], 0x80000000); gen_cmp_imm(TCG_COND_NE, cpu_T[0], 0); gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 31); tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1); return; case 0x4021: /* shar Rn */ tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B11_8)], 1); gen_cmp_imm(TCG_COND_NE, cpu_T[0], 0); gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0); tcg_gen_sari_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1); return; case 0x4001: /* shlr Rn */ tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B11_8)], 1); gen_cmp_imm(TCG_COND_NE, cpu_T[0], 0); gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0); tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1); return; case 0x4008: /* shll2 Rn */ Loading