aboutsummaryrefslogtreecommitdiff
path: root/target/mips/fpu_helper.c
diff options
context:
space:
mode:
authorAleksandar Markovic <aleksandar.qemu.devel@gmail.com>2020-05-18 22:09:15 +0200
committerAleksandar Markovic <aleksandar.qemu.devel@gmail.com>2020-06-09 17:32:45 +0200
commit9579f7816855757c747f9428a8e53d0fe0a0e9b7 (patch)
tree8e8d33ad908f49522fdeef485635904781d44064 /target/mips/fpu_helper.c
parent485cd2e4ce35f24428bd1783ad31325acc67b350 (diff)
target/mips: fpu: Refactor conversion from ieee to mips exception flags
The original coversion function is used for regular and MSA floating point instructions handling. Since there are some nuanced differences between regular and MSA floating point exception handling, provide two instances of the conversion function, rather than just a single common one. Inline both instances of this function instances for the sake of performance. Improve variable naming in surrounding code for clarity. Reviewed-by: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com> Signed-off-by: Aleksandar Markovic <aleksandar.qemu.devel@gmail.com> Message-Id: <20200518200920.17344-17-aleksandar.qemu.devel@gmail.com>
Diffstat (limited to 'target/mips/fpu_helper.c')
-rw-r--r--target/mips/fpu_helper.c55
1 files changed, 30 insertions, 25 deletions
diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index dbb8ca5692..7a3a61cab3 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -189,43 +189,48 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt)
}
}
-int ieee_ex_to_mips(int xcpt)
+static inline int ieee_to_mips_xcpt(int ieee_xcpt)
{
- int ret = 0;
- if (xcpt) {
- if (xcpt & float_flag_invalid) {
- ret |= FP_INVALID;
- }
- if (xcpt & float_flag_overflow) {
- ret |= FP_OVERFLOW;
- }
- if (xcpt & float_flag_underflow) {
- ret |= FP_UNDERFLOW;
- }
- if (xcpt & float_flag_divbyzero) {
- ret |= FP_DIV0;
- }
- if (xcpt & float_flag_inexact) {
- ret |= FP_INEXACT;
- }
+ int mips_xcpt = 0;
+
+ if (ieee_xcpt & float_flag_invalid) {
+ mips_xcpt |= FP_INVALID;
+ }
+ if (ieee_xcpt & float_flag_overflow) {
+ mips_xcpt |= FP_OVERFLOW;
}
- return ret;
+ if (ieee_xcpt & float_flag_underflow) {
+ mips_xcpt |= FP_UNDERFLOW;
+ }
+ if (ieee_xcpt & float_flag_divbyzero) {
+ mips_xcpt |= FP_DIV0;
+ }
+ if (ieee_xcpt & float_flag_inexact) {
+ mips_xcpt |= FP_INEXACT;
+ }
+
+ return mips_xcpt;
}
static inline void update_fcr31(CPUMIPSState *env, uintptr_t pc)
{
- int tmp = ieee_ex_to_mips(get_float_exception_flags(
- &env->active_fpu.fp_status));
+ int ieee_exception_flags = get_float_exception_flags(
+ &env->active_fpu.fp_status);
+ int mips_exception_flags = 0;
+
+ if (ieee_exception_flags) {
+ mips_exception_flags = ieee_to_mips_xcpt(ieee_exception_flags);
+ }
- SET_FP_CAUSE(env->active_fpu.fcr31, tmp);
+ SET_FP_CAUSE(env->active_fpu.fcr31, mips_exception_flags);
- if (tmp) {
+ if (mips_exception_flags) {
set_float_exception_flags(0, &env->active_fpu.fp_status);
- if (GET_FP_ENABLE(env->active_fpu.fcr31) & tmp) {
+ if (GET_FP_ENABLE(env->active_fpu.fcr31) & mips_exception_flags) {
do_raise_exception(env, EXCP_FPE, pc);
} else {
- UPDATE_FP_FLAGS(env->active_fpu.fcr31, tmp);
+ UPDATE_FP_FLAGS(env->active_fpu.fcr31, mips_exception_flags);
}
}
}