This enables the exceptions raised by the actual load to be reflected as a failure.
Reviewed-by: Philippe Mathieu-Daudé <phi...@linaro.org> Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- target/m68k/translate.c | 104 ++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 642e80857c..711f1477c8 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -902,53 +902,6 @@ static void gen_fp_move(TCGv_ptr dest, TCGv_ptr src) tcg_gen_st_i64(t64, dest, offsetof(FPReg, l.lower)); } -static void gen_load_fp(DisasContext *s, int opsize, TCGv addr, TCGv_ptr fp, - int index) -{ - TCGv tmp; - TCGv_i64 t64; - - t64 = tcg_temp_new_i64(); - tmp = tcg_temp_new(); - switch (opsize) { - case OS_BYTE: - case OS_WORD: - case OS_LONG: - tcg_gen_qemu_ld_tl(tmp, addr, index, opsize | MO_SIGN | MO_TE); - gen_helper_exts32(tcg_env, fp, tmp); - break; - case OS_SINGLE: - tcg_gen_qemu_ld_tl(tmp, addr, index, MO_TEUL); - gen_helper_extf32(tcg_env, fp, tmp); - break; - case OS_DOUBLE: - tcg_gen_qemu_ld_i64(t64, addr, index, MO_TEUQ); - gen_helper_extf64(tcg_env, fp, t64); - break; - case OS_EXTENDED: - if (m68k_feature(s->env, M68K_FEATURE_CF_FPU)) { - gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP); - break; - } - tcg_gen_qemu_ld_i32(tmp, addr, index, MO_TEUL); - tcg_gen_shri_i32(tmp, tmp, 16); - tcg_gen_st16_i32(tmp, fp, offsetof(FPReg, l.upper)); - tcg_gen_addi_i32(tmp, addr, 4); - tcg_gen_qemu_ld_i64(t64, tmp, index, MO_TEUQ); - tcg_gen_st_i64(t64, fp, offsetof(FPReg, l.lower)); - break; - case OS_PACKED: - /* - * unimplemented data type on 68040/ColdFire - * FIXME if needed for another FPU - */ - gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP); - break; - default: - g_assert_not_reached(); - } -} - static void gen_store_fp(DisasContext *s, int opsize, TCGv addr, TCGv_ptr fp, int index) { @@ -996,8 +949,8 @@ static void gen_store_fp(DisasContext *s, int opsize, TCGv addr, TCGv_ptr fp, } } -static bool gen_load_mode_fp(DisasContext *s, uint16_t insn, int opsize, - TCGv_ptr fp, int index) +static bool gen_load_fp(DisasContext *s, uint16_t insn, int opsize, + TCGv_ptr fp, int index) { int mode = extract32(insn, 3, 3); int reg0 = REG(insn, 0); @@ -1084,10 +1037,55 @@ static bool gen_load_mode_fp(DisasContext *s, uint16_t insn, int opsize, gen_addr_fault(s); return false; } - gen_load_fp(s, opsize, addr, fp, index); - return true; + break; + + default: + g_assert_not_reached(); } - g_assert_not_reached(); + + switch (opsize) { + case OS_BYTE: + case OS_WORD: + case OS_LONG: + tmp = tcg_temp_new(); + tcg_gen_qemu_ld_tl(tmp, addr, index, opsize | MO_SIGN | MO_TE); + gen_helper_exts32(tcg_env, fp, tmp); + break; + case OS_SINGLE: + tmp = tcg_temp_new(); + tcg_gen_qemu_ld_tl(tmp, addr, index, MO_TEUL); + gen_helper_extf32(tcg_env, fp, tmp); + break; + case OS_DOUBLE: + t64 = tcg_temp_new_i64(); + tcg_gen_qemu_ld_i64(t64, addr, index, MO_TEUQ); + gen_helper_extf64(tcg_env, fp, t64); + break; + case OS_EXTENDED: + if (m68k_feature(s->env, M68K_FEATURE_CF_FPU)) { + gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP); + return false; + } + tmp = tcg_temp_new(); + t64 = tcg_temp_new_i64(); + tcg_gen_qemu_ld_i32(tmp, addr, index, MO_TEUL); + tcg_gen_addi_i32(addr, addr, 4); + tcg_gen_qemu_ld_i64(t64, addr, index, MO_TEUQ); + tcg_gen_shri_i32(tmp, tmp, 16); + tcg_gen_st16_i32(tmp, fp, offsetof(FPReg, l.upper)); + tcg_gen_st_i64(t64, fp, offsetof(FPReg, l.lower)); + break; + case OS_PACKED: + /* + * unimplemented data type on 68040/ColdFire + * FIXME if needed for another FPU + */ + gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP); + return false; + default: + g_assert_not_reached(); + } + return true; } static bool gen_store_mode_fp(DisasContext *s, uint16_t insn, int opsize, @@ -4911,7 +4909,7 @@ DISAS_INSN(fpu) /* Source effective address. */ opsize = ext_opsize(ext, 10); cpu_src = gen_fp_result_ptr(); - if (!gen_load_mode_fp(s, insn, opsize, cpu_src, IS_USER(s))) { + if (!gen_load_fp(s, insn, opsize, cpu_src, IS_USER(s))) { return; } } else { -- 2.43.0