diff options
author | Richard Henderson <rth@twiddle.net> | 2015-02-18 18:47:35 -0800 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2017-02-14 08:15:00 +1100 |
commit | 762e22edcd021035e1dbcf0dbc31b4794c5c1027 (patch) | |
tree | 3f2fb564feb01629b7f125ce88ee928ee25729b2 /target/openrisc/fpu_helper.c | |
parent | cc5de49ebe5b2881b88b22c13410f13657b472e0 (diff) | |
download | qemu-762e22edcd021035e1dbcf0dbc31b4794c5c1027.zip qemu-762e22edcd021035e1dbcf0dbc31b4794c5c1027.tar.gz qemu-762e22edcd021035e1dbcf0dbc31b4794c5c1027.tar.bz2 |
target/openrisc: Fix madd
Note that the specification for lf.madd.s is confused. It's
the only mention of supposed FPMADDHI/FPMADDLO special registers.
On the other hand, or1ksim implements a somewhat normal non-fused
multiply and add. Mirror that.
Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target/openrisc/fpu_helper.c')
-rw-r--r-- | target/openrisc/fpu_helper.c | 68 |
1 files changed, 24 insertions, 44 deletions
diff --git a/target/openrisc/fpu_helper.c b/target/openrisc/fpu_helper.c index c54404b..1375cea 100644 --- a/target/openrisc/fpu_helper.c +++ b/target/openrisc/fpu_helper.c @@ -146,52 +146,32 @@ FLOAT_CALC(div) FLOAT_CALC(rem) #undef FLOAT_CALC -#define FLOAT_TERNOP(name1, name2) \ -uint64_t helper_float_ ## name1 ## name2 ## _d(CPUOpenRISCState *env, \ - uint64_t fdt0, \ - uint64_t fdt1) \ -{ \ - uint64_t result, temp, hi, lo; \ - uint32_t val1, val2; \ - OpenRISCCPU *cpu = openrisc_env_get_cpu(env); \ - hi = env->fpmaddhi; \ - lo = env->fpmaddlo; \ - set_float_exception_flags(0, &cpu->env.fp_status); \ - result = float64_ ## name1(fdt0, fdt1, &cpu->env.fp_status); \ - lo &= 0xffffffff; \ - hi &= 0xffffffff; \ - temp = (hi << 32) | lo; \ - result = float64_ ## name2(result, temp, &cpu->env.fp_status); \ - val1 = result >> 32; \ - val2 = (uint32_t) (result & 0xffffffff); \ - update_fpcsr(cpu); \ - cpu->env.fpmaddlo = val2; \ - cpu->env.fpmaddhi = val1; \ - return 0; \ -} \ - \ -uint32_t helper_float_ ## name1 ## name2 ## _s(CPUOpenRISCState *env, \ - uint32_t fdt0, uint32_t fdt1) \ -{ \ - uint64_t result, temp, hi, lo; \ - uint32_t val1, val2; \ - OpenRISCCPU *cpu = openrisc_env_get_cpu(env); \ - hi = cpu->env.fpmaddhi; \ - lo = cpu->env.fpmaddlo; \ - set_float_exception_flags(0, &cpu->env.fp_status); \ - result = float64_ ## name1(fdt0, fdt1, &cpu->env.fp_status); \ - temp = (hi << 32) | lo; \ - result = float64_ ## name2(result, temp, &cpu->env.fp_status); \ - val1 = result >> 32; \ - val2 = (uint32_t) (result & 0xffffffff); \ - update_fpcsr(cpu); \ - cpu->env.fpmaddlo = val2; \ - cpu->env.fpmaddhi = val1; \ - return 0; \ + +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; } -FLOAT_TERNOP(mul, add) -#undef FLOAT_TERNOP +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; +} #define FLOAT_CMP(name) \ |