e2k: Add fscale{s,d} and fxscalesx ops.
This commit is contained in:
parent
7c4ff94e5f
commit
6277820c04
@ -144,6 +144,8 @@ DEF_HELPER_3_32_64(fmin)
|
||||
DEF_HELPER_3_32_64(fmax)
|
||||
DEF_HELPER_3_32_64(fmul)
|
||||
DEF_HELPER_3_32_64(fdiv)
|
||||
DEF_HELPER_3(fscaled, i64, env, i64, i32)
|
||||
DEF_HELPER_3(fscales, i32, env, i32, i32)
|
||||
|
||||
/* Float x80 ops */
|
||||
DEF_HELPER_3(fxaddxx, void, env, f80, f80)
|
||||
@ -151,6 +153,7 @@ DEF_HELPER_3(fxsubxx, void, env, f80, f80)
|
||||
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)
|
||||
|
||||
/* Float 32/64/80 Comparisons */
|
||||
#define DEF_HELPER_3_32_64_80(name) \
|
||||
|
@ -334,3 +334,26 @@ uint32_t HELPER(frsqrts)(CPUE2KState *env, uint32_t x)
|
||||
return float32_val(z);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define IMPL_FSCALE(name, ty, exp_len, exp_off, mul, cvt) \
|
||||
ty HELPER(name)(CPUE2KState *env, ty src1, uint32_t src2) \
|
||||
{ \
|
||||
ty max = (1 << exp_len) - 1; \
|
||||
ty bias = max >> 1; \
|
||||
ty exp = src2 <= bias ? bias + src2 : max; \
|
||||
ty s2 = exp << exp_off; \
|
||||
return mul(env, src1, s2); \
|
||||
}
|
||||
|
||||
IMPL_FSCALE(fscaled, uint64_t, 11, 52, helper_fmuld, uint64_to_float64)
|
||||
IMPL_FSCALE(fscales, uint32_t, 8, 23, helper_fmuls, uint32_to_float32)
|
||||
|
||||
void HELPER(fxscalesx)(CPUE2KState *env, floatx80 *src1, uint32_t src2)
|
||||
{
|
||||
floatx80 s2;
|
||||
uint16_t max = (1 << 15) - 1;
|
||||
uint16_t bias = max >> 1;
|
||||
s2.low = 1UL << 63;
|
||||
s2.high = src2 <= bias ? bias + src2 : max;
|
||||
helper_fxmulxx(env, src1, &s2);
|
||||
}
|
||||
|
@ -2457,6 +2457,19 @@ static void gen_alopf1_dedd(Instr *instr,
|
||||
gen_al_result_i64(instr, dst, tag);
|
||||
}
|
||||
|
||||
static void gen_alopf1_deds(Instr *instr,
|
||||
void (*op)(TCGv_i64, TCGv_env, TCGv_i64, TCGv_i32))
|
||||
{
|
||||
Src64 s1 = get_src1_i64(instr);
|
||||
Src32 s2 = get_src2_i32(instr);
|
||||
TCGv_i32 tag = get_temp_i32(instr);
|
||||
TCGv_i64 dst = get_temp_i64(instr);
|
||||
|
||||
gen_tag2_i64(tag, s1.tag, s2.tag);
|
||||
(*op)(dst, cpu_env, s1.value, s2.value);
|
||||
gen_al_result_i64(instr, dst, tag);
|
||||
}
|
||||
|
||||
static void gen_alopf1_sss(Instr *instr,
|
||||
void (*op)(TCGv_i32, TCGv_i32, TCGv_i32))
|
||||
{
|
||||
@ -2869,6 +2882,19 @@ static inline void gen_alopf1_f80(Src80 *ret, Src80 src1, Src80 src2,
|
||||
tcg_temp_free_ptr(t0);
|
||||
}
|
||||
|
||||
static inline void gen_alopf1_xexs_raw(Src80 *ret, Src80 src1, Src32 src2,
|
||||
void (*op)(TCGv_env, TCGv_ptr, TCGv_i32))
|
||||
{
|
||||
TCGv_ptr t0 = tcg_temp_new_ptr();
|
||||
|
||||
gen_tag2_i64(ret->tag, src1.tag, src2.tag);
|
||||
tcg_gen_addi_ptr(t0, cpu_env, offsetof(CPUE2KState, t0.f80));
|
||||
gen_temp_reg_write_i64_i32(src1.lo, src1.hi, t0);
|
||||
(*op)(cpu_env, t0, src2.value);
|
||||
gen_temp_reg_read_i64_i32(t0, ret->lo, ret->hi);
|
||||
tcg_temp_free_ptr(t0);
|
||||
}
|
||||
|
||||
static inline void gen_alopf1_xxx(Instr *instr,
|
||||
void (*op)(TCGv_env, TCGv_ptr, TCGv_ptr))
|
||||
{
|
||||
@ -2896,6 +2922,17 @@ static inline void gen_alopf1_xxs(Instr *instr,
|
||||
temp_free_src80(&t0);
|
||||
}
|
||||
|
||||
static inline void gen_alopf1_xexi(Instr *instr,
|
||||
void (*op)(TCGv_env, TCGv_ptr, TCGv_i32))
|
||||
{
|
||||
Src80 src1 = get_src1_i80(instr);
|
||||
Src32 src2 = get_src2_i32(instr);
|
||||
Src80 res = get_temp_src80(instr);
|
||||
|
||||
gen_alopf1_xexs_raw(&res, src1, src2, op);
|
||||
gen_al_result_i80(instr, res.lo, res.hi, res.tag);
|
||||
}
|
||||
|
||||
static inline void gen_alopf1_xxd(Instr *instr,
|
||||
void (*op)(TCGv_env, TCGv_ptr, TCGv_ptr))
|
||||
{
|
||||
@ -3534,6 +3571,9 @@ static void gen_op(DisasContext *ctx, Instr *instr)
|
||||
case OP_PFDIVD: gen_alopf1_dedd(instr, gen_helper_fdivd); break;
|
||||
case OP_PFMIND: gen_alopf1_dedd(instr, gen_helper_fmind); break;
|
||||
case OP_PFMAXD: gen_alopf1_dedd(instr, gen_helper_fmaxd); break;
|
||||
case OP_FSCALED: gen_alopf1_deds(instr, gen_helper_fscaled); break;
|
||||
case OP_FSCALES: gen_alopf1_sess(instr, gen_helper_fscales); break;
|
||||
case OP_FXSCALESX: gen_alopf1_xexi(instr, gen_helper_fxscalesx); break;
|
||||
case OP_FXDIVTSS:
|
||||
case OP_FXDIVTDD:
|
||||
case OP_FXDIVTSX:
|
||||
@ -3766,9 +3806,6 @@ static void gen_op(DisasContext *ctx, Instr *instr)
|
||||
case OP_PFSTOIFS:
|
||||
case OP_PFDTOIFD:
|
||||
case OP_PUTTST:
|
||||
case OP_FSCALES:
|
||||
case OP_FSCALED:
|
||||
case OP_FXSCALESX:
|
||||
case OP_STAAQP:
|
||||
case OP_QPAND:
|
||||
case OP_QPANDN:
|
||||
|
Loading…
Reference in New Issue
Block a user