This enables the exceptions raised by the actual load
to be reflected as a failure.
Signed-off-by: Richard Henderson <richard.henderson@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 df886ed062..e966d2c929 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -901,53 +901,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)
{
@@ -995,8 +948,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);
@@ -1083,10 +1036,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