提交 762e22ed 编写于 作者: R Richard Henderson

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: NBastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: NRichard Henderson <rth@twiddle.net>
上级 cc5de49e
...@@ -279,9 +279,6 @@ typedef struct CPUOpenRISCState { ...@@ -279,9 +279,6 @@ typedef struct CPUOpenRISCState {
uint64_t mac; /* Multiply registers MACHI:MACLO */ uint64_t mac; /* Multiply registers MACHI:MACLO */
target_ulong fpmaddhi; /* Multiply and add float register FPMADDHI */
target_ulong fpmaddlo; /* Multiply and add float register FPMADDLO */
target_ulong epcr; /* Exception PC register */ target_ulong epcr; /* Exception PC register */
target_ulong eear; /* Exception EA register */ target_ulong eear; /* Exception EA register */
......
...@@ -146,52 +146,32 @@ FLOAT_CALC(div) ...@@ -146,52 +146,32 @@ FLOAT_CALC(div)
FLOAT_CALC(rem) FLOAT_CALC(rem)
#undef FLOAT_CALC #undef FLOAT_CALC
#define FLOAT_TERNOP(name1, name2) \
uint64_t helper_float_ ## name1 ## name2 ## _d(CPUOpenRISCState *env, \ uint64_t helper_float_madd_d(CPUOpenRISCState *env, uint64_t a,
uint64_t fdt0, \ uint64_t b, uint64_t c)
uint64_t fdt1) \ {
{ \ OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
uint64_t result, temp, hi, lo; \ uint64_t result;
uint32_t val1, val2; \ set_float_exception_flags(0, &cpu->env.fp_status);
OpenRISCCPU *cpu = openrisc_env_get_cpu(env); \ /* Note that or1ksim doesn't use merged operation. */
hi = env->fpmaddhi; \ result = float64_mul(b, c, &cpu->env.fp_status);
lo = env->fpmaddlo; \ result = float64_add(result, a, &cpu->env.fp_status);
set_float_exception_flags(0, &cpu->env.fp_status); \ update_fpcsr(cpu);
result = float64_ ## name1(fdt0, fdt1, &cpu->env.fp_status); \ return result;
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; \
} }
FLOAT_TERNOP(mul, add) uint32_t helper_float_madd_s(CPUOpenRISCState *env, uint32_t a,
#undef FLOAT_TERNOP 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) \ #define FLOAT_CMP(name) \
......
...@@ -29,11 +29,8 @@ DEF_HELPER_FLAGS_2(itofs, TCG_CALL_NO_WG, i32, env, i32) ...@@ -29,11 +29,8 @@ DEF_HELPER_FLAGS_2(itofs, TCG_CALL_NO_WG, i32, env, i32)
DEF_HELPER_FLAGS_2(ftoid, TCG_CALL_NO_WG, i64, env, i64) DEF_HELPER_FLAGS_2(ftoid, TCG_CALL_NO_WG, i64, env, i64)
DEF_HELPER_FLAGS_2(ftois, TCG_CALL_NO_WG, i32, env, i32) DEF_HELPER_FLAGS_2(ftois, TCG_CALL_NO_WG, i32, env, i32)
#define FOP_MADD(op) \ DEF_HELPER_FLAGS_4(float_madd_s, TCG_CALL_NO_WG, i32, env, i32, i32, i32)
DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \ DEF_HELPER_FLAGS_4(float_madd_d, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_WG, i64, env, i64, i64)
FOP_MADD(muladd)
#undef FOP_MADD
#define FOP_CALC(op) \ #define FOP_CALC(op) \
DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \ DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \
......
...@@ -61,7 +61,6 @@ static TCGv cpu_lock_addr; ...@@ -61,7 +61,6 @@ static TCGv cpu_lock_addr;
static TCGv cpu_lock_value; static TCGv cpu_lock_value;
static TCGv_i32 fpcsr; static TCGv_i32 fpcsr;
static TCGv_i64 cpu_mac; /* MACHI:MACLO */ static TCGv_i64 cpu_mac; /* MACHI:MACLO */
static TCGv fpmaddhi, fpmaddlo;
static TCGv_i32 env_flags; static TCGv_i32 env_flags;
#include "exec/gen-icount.h" #include "exec/gen-icount.h"
...@@ -108,12 +107,6 @@ void openrisc_translate_init(void) ...@@ -108,12 +107,6 @@ void openrisc_translate_init(void)
cpu_mac = tcg_global_mem_new_i64(cpu_env, cpu_mac = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUOpenRISCState, mac), offsetof(CPUOpenRISCState, mac),
"mac"); "mac");
fpmaddhi = tcg_global_mem_new(cpu_env,
offsetof(CPUOpenRISCState, fpmaddhi),
"fpmaddhi");
fpmaddlo = tcg_global_mem_new(cpu_env,
offsetof(CPUOpenRISCState, fpmaddlo),
"fpmaddlo");
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
cpu_R[i] = tcg_global_mem_new(cpu_env, cpu_R[i] = tcg_global_mem_new(cpu_env,
offsetof(CPUOpenRISCState, gpr[i]), offsetof(CPUOpenRISCState, gpr[i]),
...@@ -1324,7 +1317,8 @@ static void dec_float(DisasContext *dc, uint32_t insn) ...@@ -1324,7 +1317,8 @@ static void dec_float(DisasContext *dc, uint32_t insn)
case 0x07: /* lf.madd.s */ case 0x07: /* lf.madd.s */
LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb); LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb);
gen_helper_float_muladd_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); gen_helper_float_madd_s(cpu_R[rd], cpu_env, cpu_R[rd],
cpu_R[ra], cpu_R[rb]);
break; break;
case 0x08: /* lf.sfeq.s */ case 0x08: /* lf.sfeq.s */
...@@ -1409,7 +1403,8 @@ static void dec_float(DisasContext *dc, uint32_t insn) ...@@ -1409,7 +1403,8 @@ static void dec_float(DisasContext *dc, uint32_t insn)
case 0x17: lf.madd.d case 0x17: lf.madd.d
LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb); LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb);
check_of64s(dc); check_of64s(dc);
gen_helper_float_muladd_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]); gen_helper_float_madd_d(cpu_R[rd], cpu_env, cpu_R[rd],
cpu_R[ra], cpu_R[rb]);
break; break;
case 0x18: lf.sfeq.d case 0x18: lf.sfeq.d
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册