From 400947bba3a340ace1e41357ad8d6f1421cfd90e Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Thu, 4 Feb 2021 03:02:32 +0300 Subject: [PATCH] e2k: implement fsqrttd/fxsqrttxx through ignoring what fsqrtid/fxsqrt{i,u}xx does --- target/e2k/cpu.h | 12 +++++++++++ target/e2k/helper.h | 2 ++ target/e2k/helper_fpu.c | 23 +++++++++++++++++++- target/e2k/translate/alc.c | 44 ++++++++++++++++++++++++++++---------- 4 files changed, 69 insertions(+), 12 deletions(-) diff --git a/target/e2k/cpu.h b/target/e2k/cpu.h index 4d42c64965..20ca2c58d4 100644 --- a/target/e2k/cpu.h +++ b/target/e2k/cpu.h @@ -8,6 +8,18 @@ void e2k_tcg_initialize(void); +/* a1ba: fsqrtid, fxsqrtixx, fxsqrtuxx are instructions that + * calculate intermediate square root + * I don't think the results of these instructions are meant to be used + * somewhere else than final square root instruction (fsqrttd, fxsqrttxx) + * Correctly emulating that instruction may impact performance + * + * Uncomment this macro to have correct implementation, + * or left as is to just copy values + */ + +/* #define TARGET_E2K_PRECISE_FSQRTID */ + #define GEN_MASK(start, len) (((1UL << (len)) - 1) << (start)) #define GET_BIT(v, index) (((v) >> (index)) & 1) diff --git a/target/e2k/helper.h b/target/e2k/helper.h index a4818ac2c6..d5cee041e6 100644 --- a/target/e2k/helper.h +++ b/target/e2k/helper.h @@ -149,6 +149,7 @@ DEF_HELPER_3(fscales, i32, env, i32, i32) DEF_HELPER_2(frcps, i32, env, i32) DEF_HELPER_2(fsqrts, i32, env, i32) DEF_HELPER_2(frsqrts, i32, env, i32) +DEF_HELPER_3(fsqrttd, i64, env, i64, i64) /* Float x80 ops */ DEF_HELPER_3(fxaddxx, void, env, f80, f80) @@ -157,6 +158,7 @@ DEF_HELPER_3(fxrsubxx, void, env, f80, f80) DEF_HELPER_3(fxmulxx, void, env, f80, f80) DEF_HELPER_3(fxdivxx, void, env, f80, f80) DEF_HELPER_3(fxscalesx, void, env, f80, i32) +DEF_HELPER_3(fxsqrttxx, void, env, f80, f80) /* Float 32/64/80 Comparisons */ #define DEF_HELPER_3_32_64_80(name) \ diff --git a/target/e2k/helper_fpu.c b/target/e2k/helper_fpu.c index 858a693f91..8c6bf7fb1f 100644 --- a/target/e2k/helper_fpu.c +++ b/target/e2k/helper_fpu.c @@ -307,7 +307,6 @@ uint64_t HELPER(fdtoifd)(CPUE2KState *env, uint64_t flags, uint64_t f) } /* TODO: test if valid, test exception flags */ -#if 1 uint32_t HELPER(frcps)(CPUE2KState *env, uint32_t x) { int old_flags = save_exception_flags(env); @@ -333,8 +332,30 @@ uint32_t HELPER(frsqrts)(CPUE2KState *env, uint32_t x) merge_exception_flags(env, old_flags); return float32_val(y); } + +#ifdef TARGET_E2K_PRECISE_FSQRTID +uint64 HELPER(fsqrtid)(CPUE2KState *env, uint64_t x) +{ +#error implement + return x; +} #endif +uint64_t HELPER(fsqrttd)(CPUE2KState *env, uint64_t x, uint64_t unused) +{ + int old_flags = save_exception_flags(env); + uint64_t y = float64_sqrt(make_float64(x), &env->fp_status); + merge_exception_flags(env, old_flags); + return float64_val(y); +} + +void HELPER(fxsqrttxx)(CPUE2KState *env, floatx80 *x, floatx80 *unused) +{ + int old_flags = save_exception_flags(env); + *x = floatx80_sqrt(*x, &env->fp_status); + merge_exception_flags(env, old_flags); +} + #define IMPL_FSCALE(name, ty, exp_len, exp_off, mul, cvt) \ ty HELPER(name)(CPUE2KState *env, ty src1, uint32_t src2) \ { \ diff --git a/target/e2k/translate/alc.c b/target/e2k/translate/alc.c index d8961b08e1..37e8ddb6c7 100644 --- a/target/e2k/translate/alc.c +++ b/target/e2k/translate/alc.c @@ -3127,6 +3127,23 @@ static inline void gen_alopf2_dx(Instr *instr, gen_al_result_i80(instr, res.lo, res.hi, res.tag); } +static inline void gen_mov_f80(Src80 *ret, Src80 src2) +{ + tcg_gen_mov_i32(ret->hi, src2.hi); + tcg_gen_mov_i64(ret->lo, src2.lo); +} + +static inline void gen_alopf2_xx(Instr *instr, + void (*op)(Src80 *ret, Src80 src2)) +{ + Src80 src2 = get_src2_i80(instr); + Src80 res = get_temp_src80(instr); + + gen_tag1_i64(res.tag, src2.tag); + (*op)(&res, src2); + gen_al_result_i80(instr, res.lo, res.hi, res.tag); +} + static AlopDesc *find_op(Instr *instr) { /* ALES2/5 may be allocated but must not be used */ @@ -3639,16 +3656,26 @@ static void gen_op(DisasContext *ctx, Instr *instr) case OP_FRCPS: gen_alopf2_ses(instr, gen_helper_frcps); break; case OP_FSQRTS: gen_alopf2_ses(instr, gen_helper_fsqrts); break; case OP_FRSQRTS: gen_alopf2_ses(instr, gen_helper_frsqrts); break; +#ifndef TARGET_E2K_PRECISE_FSQRTID + case OP_FSQRTID: gen_alopf2_dd(instr, tcg_gen_mov_i64); break; + case OP_FXSQRTISX: gen_alopf2_sx(instr, gen_fstofx); break; + case OP_FXSQRTIDX: gen_alopf2_dx(instr, gen_fdtofx); break; + case OP_FXSQRTIXX: gen_alopf2_xx(instr, gen_mov_f80); break; + /* FIXME: these are not ALOPF2! */ + case OP_FXSQRTUSX: /* fallthrough */ + case OP_FXSQRTUDX: /* fallthrough */ + case OP_FXSQRTUXX: gen_alopf2_xx(instr, gen_mov_f80); break; +#else +#error Not implemented +#endif + case OP_FSQRTTD: gen_alopf1_dedd(instr, gen_helper_fsqrttd); break; + case OP_FXSQRTTSX: gen_alopf1_xsx(instr, gen_helper_fxsqrttxx); break; + case OP_FXSQRTTDX: gen_alopf1_xdx(instr, gen_helper_fxsqrttxx); break; + case OP_FXSQRTTXX: gen_alopf1_xxx(instr, gen_helper_fxsqrttxx); break; case OP_FXDIVTSS: case OP_FXDIVTDD: case OP_FXDIVTSX: case OP_FXDIVTDX: - case OP_FXSQRTUSX: - case OP_FXSQRTUDX: - case OP_FXSQRTUXX: - case OP_FXSQRTTSX: - case OP_FXSQRTTDX: - case OP_FXSQRTTXX: case OP_VFSI: case OP_LDCSB: case OP_LDDSB: @@ -3674,9 +3701,6 @@ static void gen_op(DisasContext *ctx, Instr *instr) case OP_LDFSD: case OP_LDGSD: case OP_LDSSD: - case OP_FXSQRTISX: - case OP_FXSQRTIDX: - case OP_FXSQRTIXX: case OP_MOVTRS: case OP_MOVTRCS: case OP_MOVTRD: @@ -3733,7 +3757,6 @@ static void gen_op(DisasContext *ctx, Instr *instr) case OP_AAURRD: case OP_AAURRQ: */ - case OP_FSQRTTD: case OP_PFMULS: case OP_PFADDS: case OP_PFSUBS: @@ -3817,7 +3840,6 @@ static void gen_op(DisasContext *ctx, Instr *instr) case OP_LDFSQ: case OP_LDGSQ: case OP_LDSSQ: - case OP_FSQRTID: case OP_PFSQRTS: case OP_GETTD: case OP_GETTC: