aboutsummaryrefslogtreecommitdiff
path: root/target/openrisc/fpu_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/openrisc/fpu_helper.c')
-rw-r--r--target/openrisc/fpu_helper.c252
1 files changed, 49 insertions, 203 deletions
diff --git a/target/openrisc/fpu_helper.c b/target/openrisc/fpu_helper.c
index 977a1e8e55..265ce13337 100644
--- a/target/openrisc/fpu_helper.c
+++ b/target/openrisc/fpu_helper.c
@@ -24,121 +24,70 @@
#include "exception.h"
#include "fpu/softfloat.h"
-static inline uint32_t ieee_ex_to_openrisc(OpenRISCCPU *cpu, int fexcp)
+static int ieee_ex_to_openrisc(int fexcp)
{
int ret = 0;
- if (fexcp) {
- if (fexcp & float_flag_invalid) {
- cpu->env.fpcsr |= FPCSR_IVF;
- ret = 1;
- }
- if (fexcp & float_flag_overflow) {
- cpu->env.fpcsr |= FPCSR_OVF;
- ret = 1;
- }
- if (fexcp & float_flag_underflow) {
- cpu->env.fpcsr |= FPCSR_UNF;
- ret = 1;
- }
- if (fexcp & float_flag_divbyzero) {
- cpu->env.fpcsr |= FPCSR_DZF;
- ret = 1;
- }
- if (fexcp & float_flag_inexact) {
- cpu->env.fpcsr |= FPCSR_IXF;
- ret = 1;
- }
+ if (fexcp & float_flag_invalid) {
+ ret |= FPCSR_IVF;
+ }
+ if (fexcp & float_flag_overflow) {
+ ret |= FPCSR_OVF;
+ }
+ if (fexcp & float_flag_underflow) {
+ ret |= FPCSR_UNF;
+ }
+ if (fexcp & float_flag_divbyzero) {
+ ret |= FPCSR_DZF;
+ }
+ if (fexcp & float_flag_inexact) {
+ ret |= FPCSR_IXF;
}
-
return ret;
}
-static inline void update_fpcsr(OpenRISCCPU *cpu)
+void HELPER(update_fpcsr)(CPUOpenRISCState *env)
{
- int tmp = ieee_ex_to_openrisc(cpu,
- get_float_exception_flags(&cpu->env.fp_status));
-
- SET_FP_CAUSE(cpu->env.fpcsr, tmp);
- if ((GET_FP_ENABLE(cpu->env.fpcsr) & tmp) &&
- (cpu->env.fpcsr & FPCSR_FPEE)) {
- helper_exception(&cpu->env, EXCP_FPE);
- } else {
- UPDATE_FP_FLAGS(cpu->env.fpcsr, tmp);
+ int tmp = get_float_exception_flags(&env->fp_status);
+
+ if (tmp) {
+ set_float_exception_flags(0, &env->fp_status);
+ tmp = ieee_ex_to_openrisc(tmp);
+ if (tmp) {
+ env->fpcsr |= tmp;
+ if (env->fpcsr & FPCSR_FPEE) {
+ helper_exception(env, EXCP_FPE);
+ }
+ }
}
}
uint64_t HELPER(itofd)(CPUOpenRISCState *env, uint64_t val)
{
- uint64_t itofd;
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-
- set_float_exception_flags(0, &cpu->env.fp_status);
- itofd = int32_to_float64(val, &cpu->env.fp_status);
- update_fpcsr(cpu);
-
- return itofd;
+ return int32_to_float64(val, &env->fp_status);
}
uint32_t HELPER(itofs)(CPUOpenRISCState *env, uint32_t val)
{
- uint32_t itofs;
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-
- set_float_exception_flags(0, &cpu->env.fp_status);
- itofs = int32_to_float32(val, &cpu->env.fp_status);
- update_fpcsr(cpu);
-
- return itofs;
+ return int32_to_float32(val, &env->fp_status);
}
uint64_t HELPER(ftoid)(CPUOpenRISCState *env, uint64_t val)
{
- uint64_t ftoid;
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-
- set_float_exception_flags(0, &cpu->env.fp_status);
- ftoid = float32_to_int64(val, &cpu->env.fp_status);
- update_fpcsr(cpu);
-
- return ftoid;
+ return float32_to_int64(val, &env->fp_status);
}
uint32_t HELPER(ftois)(CPUOpenRISCState *env, uint32_t val)
{
- uint32_t ftois;
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-
- set_float_exception_flags(0, &cpu->env.fp_status);
- ftois = float32_to_int32(val, &cpu->env.fp_status);
- update_fpcsr(cpu);
-
- return ftois;
+ return float32_to_int32(val, &env->fp_status);
}
-#define FLOAT_OP(name, p) void helper_float_##_##p(void)
-
#define FLOAT_CALC(name) \
uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, \
uint64_t fdt0, uint64_t fdt1) \
-{ \
- uint64_t result; \
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env); \
- set_float_exception_flags(0, &cpu->env.fp_status); \
- result = float64_ ## name(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
- return result; \
-} \
- \
+{ return float64_ ## name(fdt0, fdt1, &env->fp_status); } \
uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, \
uint32_t fdt0, uint32_t fdt1) \
-{ \
- uint32_t result; \
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env); \
- set_float_exception_flags(0, &cpu->env.fp_status); \
- result = float32_ ## name(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
- return result; \
-} \
+{ return float32_ ## name(fdt0, fdt1, &env->fp_status); }
FLOAT_CALC(add)
FLOAT_CALC(sub)
@@ -151,132 +100,29 @@ FLOAT_CALC(rem)
uint64_t helper_float_madd_d(CPUOpenRISCState *env, uint64_t a,
uint64_t b, uint64_t c)
{
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
- uint64_t result;
- set_float_exception_flags(0, &cpu->env.fp_status);
- /* Note that or1ksim doesn't use merged operation. */
- result = float64_mul(b, c, &cpu->env.fp_status);
- result = float64_add(result, a, &cpu->env.fp_status);
- update_fpcsr(cpu);
- return result;
+ /* Note that or1ksim doesn't use fused operation. */
+ b = float64_mul(b, c, &env->fp_status);
+ return float64_add(a, b, &env->fp_status);
}
uint32_t helper_float_madd_s(CPUOpenRISCState *env, uint32_t a,
uint32_t b, uint32_t c)
{
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
- uint32_t result;
- set_float_exception_flags(0, &cpu->env.fp_status);
- /* Note that or1ksim doesn't use merged operation. */
- result = float32_mul(b, c, &cpu->env.fp_status);
- result = float32_add(result, a, &cpu->env.fp_status);
- update_fpcsr(cpu);
- return result;
+ /* Note that or1ksim doesn't use fused operation. */
+ b = float32_mul(b, c, &env->fp_status);
+ return float32_add(a, b, &env->fp_status);
}
-#define FLOAT_CMP(name) \
-uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, \
- uint64_t fdt0, uint64_t fdt1) \
-{ \
- int res; \
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env); \
- set_float_exception_flags(0, &cpu->env.fp_status); \
- res = float64_ ## name(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
- return res; \
-} \
- \
-uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, \
- uint32_t fdt0, uint32_t fdt1)\
-{ \
- int res; \
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env); \
- set_float_exception_flags(0, &cpu->env.fp_status); \
- res = float32_ ## name(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
- return res; \
-}
+#define FLOAT_CMP(name, impl) \
+target_ulong helper_float_ ## name ## _d(CPUOpenRISCState *env, \
+ uint64_t fdt0, uint64_t fdt1) \
+{ return float64_ ## impl(fdt0, fdt1, &env->fp_status); } \
+target_ulong helper_float_ ## name ## _s(CPUOpenRISCState *env, \
+ uint32_t fdt0, uint32_t fdt1) \
+{ return float32_ ## impl(fdt0, fdt1, &env->fp_status); }
-FLOAT_CMP(le)
-FLOAT_CMP(eq)
-FLOAT_CMP(lt)
+FLOAT_CMP(le, le)
+FLOAT_CMP(lt, lt)
+FLOAT_CMP(eq, eq_quiet)
#undef FLOAT_CMP
-
-
-#define FLOAT_CMPNE(name) \
-uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, \
- uint64_t fdt0, uint64_t fdt1) \
-{ \
- int res; \
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env); \
- set_float_exception_flags(0, &cpu->env.fp_status); \
- res = !float64_eq_quiet(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
- return res; \
-} \
- \
-uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, \
- uint32_t fdt0, uint32_t fdt1) \
-{ \
- int res; \
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env); \
- set_float_exception_flags(0, &cpu->env.fp_status); \
- res = !float32_eq_quiet(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
- return res; \
-}
-
-FLOAT_CMPNE(ne)
-#undef FLOAT_CMPNE
-
-#define FLOAT_CMPGT(name) \
-uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, \
- uint64_t fdt0, uint64_t fdt1) \
-{ \
- int res; \
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env); \
- set_float_exception_flags(0, &cpu->env.fp_status); \
- res = !float64_le(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
- return res; \
-} \
- \
-uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, \
- uint32_t fdt0, uint32_t fdt1) \
-{ \
- int res; \
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env); \
- set_float_exception_flags(0, &cpu->env.fp_status); \
- res = !float32_le(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
- return res; \
-}
-FLOAT_CMPGT(gt)
-#undef FLOAT_CMPGT
-
-#define FLOAT_CMPGE(name) \
-uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env, \
- uint64_t fdt0, uint64_t fdt1) \
-{ \
- int res; \
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env); \
- set_float_exception_flags(0, &cpu->env.fp_status); \
- res = !float64_lt(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
- return res; \
-} \
- \
-uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env, \
- uint32_t fdt0, uint32_t fdt1) \
-{ \
- int res; \
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env); \
- set_float_exception_flags(0, &cpu->env.fp_status); \
- res = !float32_lt(fdt0, fdt1, &cpu->env.fp_status); \
- update_fpcsr(cpu); \
- return res; \
-}
-
-FLOAT_CMPGE(ge)
-#undef FLOAT_CMPGE