e2k: implement fsqrttd/fxsqrttxx through ignoring what fsqrtid/fxsqrt{i,u}xx does

This commit is contained in:
Alibek Omarov 2021-02-04 03:02:32 +03:00 committed by Denis Drakhnia
parent 65675ac1cf
commit 400947bba3
4 changed files with 69 additions and 12 deletions

View File

@ -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)

View File

@ -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) \

View File

@ -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) \
{ \

View File

@ -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: