[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 48/76] target/microblaze: Fix cpu unwind for fpu exceptions
From: |
Richard Henderson |
Subject: |
[PULL 48/76] target/microblaze: Fix cpu unwind for fpu exceptions |
Date: |
Mon, 31 Aug 2020 09:05:33 -0700 |
Restore the correct PC when an exception must be raised.
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/microblaze/op_helper.c | 37 +++++++++++++++++++----------------
1 file changed, 20 insertions(+), 17 deletions(-)
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index d99d98051a..2c59d4492d 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -104,13 +104,16 @@ uint32_t helper_divu(CPUMBState *env, uint32_t a,
uint32_t b)
}
/* raise FPU exception. */
-static void raise_fpu_exception(CPUMBState *env)
+static void raise_fpu_exception(CPUMBState *env, uintptr_t ra)
{
+ CPUState *cs = env_cpu(env);
+
env->esr = ESR_EC_FPU;
- helper_raise_exception(env, EXCP_HW_EXCP);
+ cs->exception_index = EXCP_HW_EXCP;
+ cpu_loop_exit_restore(cs, ra);
}
-static void update_fpu_flags(CPUMBState *env, int flags)
+static void update_fpu_flags(CPUMBState *env, int flags, uintptr_t ra)
{
int raise = 0;
@@ -133,7 +136,7 @@ static void update_fpu_flags(CPUMBState *env, int flags)
if (raise
&& (env->pvr.regs[2] & PVR2_FPU_EXC_MASK)
&& (env->msr & MSR_EE)) {
- raise_fpu_exception(env);
+ raise_fpu_exception(env, ra);
}
}
@@ -148,7 +151,7 @@ uint32_t helper_fadd(CPUMBState *env, uint32_t a, uint32_t
b)
fd.f = float32_add(fa.f, fb.f, &env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
- update_fpu_flags(env, flags);
+ update_fpu_flags(env, flags, GETPC());
return fd.l;
}
@@ -162,7 +165,7 @@ uint32_t helper_frsub(CPUMBState *env, uint32_t a, uint32_t
b)
fb.l = b;
fd.f = float32_sub(fb.f, fa.f, &env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
- update_fpu_flags(env, flags);
+ update_fpu_flags(env, flags, GETPC());
return fd.l;
}
@@ -176,7 +179,7 @@ uint32_t helper_fmul(CPUMBState *env, uint32_t a, uint32_t
b)
fb.l = b;
fd.f = float32_mul(fa.f, fb.f, &env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
- update_fpu_flags(env, flags);
+ update_fpu_flags(env, flags, GETPC());
return fd.l;
}
@@ -191,7 +194,7 @@ uint32_t helper_fdiv(CPUMBState *env, uint32_t a, uint32_t
b)
fb.l = b;
fd.f = float32_div(fb.f, fa.f, &env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
- update_fpu_flags(env, flags);
+ update_fpu_flags(env, flags, GETPC());
return fd.l;
}
@@ -206,7 +209,7 @@ uint32_t helper_fcmp_un(CPUMBState *env, uint32_t a,
uint32_t b)
if (float32_is_signaling_nan(fa.f, &env->fp_status) ||
float32_is_signaling_nan(fb.f, &env->fp_status)) {
- update_fpu_flags(env, float_flag_invalid);
+ update_fpu_flags(env, float_flag_invalid, GETPC());
r = 1;
}
@@ -229,7 +232,7 @@ uint32_t helper_fcmp_lt(CPUMBState *env, uint32_t a,
uint32_t b)
fb.l = b;
r = float32_lt(fb.f, fa.f, &env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
- update_fpu_flags(env, flags & float_flag_invalid);
+ update_fpu_flags(env, flags & float_flag_invalid, GETPC());
return r;
}
@@ -245,7 +248,7 @@ uint32_t helper_fcmp_eq(CPUMBState *env, uint32_t a,
uint32_t b)
fb.l = b;
r = float32_eq_quiet(fa.f, fb.f, &env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
- update_fpu_flags(env, flags & float_flag_invalid);
+ update_fpu_flags(env, flags & float_flag_invalid, GETPC());
return r;
}
@@ -261,7 +264,7 @@ uint32_t helper_fcmp_le(CPUMBState *env, uint32_t a,
uint32_t b)
set_float_exception_flags(0, &env->fp_status);
r = float32_le(fa.f, fb.f, &env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
- update_fpu_flags(env, flags & float_flag_invalid);
+ update_fpu_flags(env, flags & float_flag_invalid, GETPC());
return r;
@@ -277,7 +280,7 @@ uint32_t helper_fcmp_gt(CPUMBState *env, uint32_t a,
uint32_t b)
set_float_exception_flags(0, &env->fp_status);
r = float32_lt(fa.f, fb.f, &env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
- update_fpu_flags(env, flags & float_flag_invalid);
+ update_fpu_flags(env, flags & float_flag_invalid, GETPC());
return r;
}
@@ -291,7 +294,7 @@ uint32_t helper_fcmp_ne(CPUMBState *env, uint32_t a,
uint32_t b)
set_float_exception_flags(0, &env->fp_status);
r = !float32_eq_quiet(fa.f, fb.f, &env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
- update_fpu_flags(env, flags & float_flag_invalid);
+ update_fpu_flags(env, flags & float_flag_invalid, GETPC());
return r;
}
@@ -306,7 +309,7 @@ uint32_t helper_fcmp_ge(CPUMBState *env, uint32_t a,
uint32_t b)
set_float_exception_flags(0, &env->fp_status);
r = !float32_lt(fa.f, fb.f, &env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
- update_fpu_flags(env, flags & float_flag_invalid);
+ update_fpu_flags(env, flags & float_flag_invalid, GETPC());
return r;
}
@@ -330,7 +333,7 @@ uint32_t helper_fint(CPUMBState *env, uint32_t a)
fa.l = a;
r = float32_to_int32(fa.f, &env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
- update_fpu_flags(env, flags);
+ update_fpu_flags(env, flags, GETPC());
return r;
}
@@ -344,7 +347,7 @@ uint32_t helper_fsqrt(CPUMBState *env, uint32_t a)
fa.l = a;
fd.l = float32_sqrt(fa.f, &env->fp_status);
flags = get_float_exception_flags(&env->fp_status);
- update_fpu_flags(env, flags);
+ update_fpu_flags(env, flags, GETPC());
return fd.l;
}
--
2.25.1
- [PULL 38/76] target/microblaze: Implement cmp and cmpu inline, (continued)
- [PULL 38/76] target/microblaze: Implement cmp and cmpu inline, Richard Henderson, 2020/08/31
- [PULL 39/76] target/microblaze: Convert dec_pattern to decodetree, Richard Henderson, 2020/08/31
- [PULL 40/76] target/microblaze: Convert dec_and, dec_or, dec_xor to decodetree, Richard Henderson, 2020/08/31
- [PULL 41/76] target/microblaze: Convert dec_mul to decodetree, Richard Henderson, 2020/08/31
- [PULL 42/76] target/microblaze: Convert dec_div to decodetree, Richard Henderson, 2020/08/31
- [PULL 43/76] target/microblaze: Unwind properly when raising divide-by-zero, Richard Henderson, 2020/08/31
- [PULL 44/76] target/microblaze: Convert dec_bit to decodetree, Richard Henderson, 2020/08/31
- [PULL 45/76] target/microblaze: Convert dec_barrel to decodetree, Richard Henderson, 2020/08/31
- [PULL 46/76] target/microblaze: Convert dec_imm to decodetree, Richard Henderson, 2020/08/31
- [PULL 47/76] target/microblaze: Convert dec_fpu to decodetree, Richard Henderson, 2020/08/31
- [PULL 48/76] target/microblaze: Fix cpu unwind for fpu exceptions,
Richard Henderson <=
- [PULL 49/76] target/microblaze: Mark fpu helpers TCG_CALL_NO_WG, Richard Henderson, 2020/08/31
- [PULL 51/76] target/microblaze: Cache mem_index in DisasContext, Richard Henderson, 2020/08/31
- [PULL 50/76] target/microblaze: Replace MSR_EE_FLAG with MSR_EE, Richard Henderson, 2020/08/31
- [PULL 52/76] target/microblaze: Fix cpu unwind for stackprot, Richard Henderson, 2020/08/31
- [PULL 54/76] target/microblaze: Assert no overlap in flags making up tb_flags, Richard Henderson, 2020/08/31
- [PULL 53/76] target/microblaze: Convert dec_load and dec_store to decodetree, Richard Henderson, 2020/08/31
- [PULL 55/76] target/microblaze: Move bimm to BIMM_FLAG, Richard Henderson, 2020/08/31
- [PULL 56/76] target/microblaze: Fix no-op mb_cpu_transaction_failed, Richard Henderson, 2020/08/31
- [PULL 57/76] target/microblaze: Store "current" iflags in insn_start, Richard Henderson, 2020/08/31
- [PULL 58/76] tcg: Add tcg_get_insn_start_param, Richard Henderson, 2020/08/31