e2k: implement fsqrttd/fxsqrttxx through ignoring what fsqrtid/fxsqrt{i,u}xx does
This commit is contained in:
parent
65675ac1cf
commit
400947bba3
|
@ -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)
|
||||
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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) \
|
||||
{ \
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue