2016-07-27 09:56:22 +03:00
|
|
|
/*** Decimal Floating Point ***/
|
|
|
|
|
|
|
|
static inline TCGv_ptr gen_fprp_ptr(int reg)
|
|
|
|
{
|
|
|
|
TCGv_ptr r = tcg_temp_new_ptr();
|
2019-01-02 12:14:22 +03:00
|
|
|
tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, vsr[reg].u64[0]));
|
2016-07-27 09:56:22 +03:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2021-10-29 22:24:12 +03:00
|
|
|
#define TRANS_DFP_T_A_B_Rc(NAME) \
|
|
|
|
static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
|
|
|
|
{ \
|
|
|
|
TCGv_ptr rt, ra, rb; \
|
|
|
|
REQUIRE_INSNS_FLAGS2(ctx, DFP); \
|
|
|
|
REQUIRE_FPU(ctx); \
|
|
|
|
rt = gen_fprp_ptr(a->rt); \
|
|
|
|
ra = gen_fprp_ptr(a->ra); \
|
|
|
|
rb = gen_fprp_ptr(a->rb); \
|
|
|
|
gen_helper_##NAME(cpu_env, rt, ra, rb); \
|
|
|
|
if (unlikely(a->rc)) { \
|
|
|
|
gen_set_cr1_from_fpscr(ctx); \
|
|
|
|
} \
|
|
|
|
tcg_temp_free_ptr(rt); \
|
|
|
|
tcg_temp_free_ptr(ra); \
|
|
|
|
tcg_temp_free_ptr(rb); \
|
|
|
|
return true; \
|
2016-07-27 09:56:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#define GEN_DFP_BF_A_B(name) \
|
|
|
|
static void gen_##name(DisasContext *ctx) \
|
|
|
|
{ \
|
|
|
|
TCGv_ptr ra, rb; \
|
|
|
|
if (unlikely(!ctx->fpu_enabled)) { \
|
|
|
|
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
ra = gen_fprp_ptr(rA(ctx->opcode)); \
|
|
|
|
rb = gen_fprp_ptr(rB(ctx->opcode)); \
|
|
|
|
gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
|
|
|
|
cpu_env, ra, rb); \
|
|
|
|
tcg_temp_free_ptr(ra); \
|
|
|
|
tcg_temp_free_ptr(rb); \
|
|
|
|
}
|
|
|
|
|
2016-07-28 21:14:13 +03:00
|
|
|
#define GEN_DFP_BF_I_B(name) \
|
|
|
|
static void gen_##name(DisasContext *ctx) \
|
|
|
|
{ \
|
|
|
|
TCGv_i32 uim; \
|
|
|
|
TCGv_ptr rb; \
|
|
|
|
if (unlikely(!ctx->fpu_enabled)) { \
|
|
|
|
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
uim = tcg_const_i32(UIMM5(ctx->opcode)); \
|
|
|
|
rb = gen_fprp_ptr(rB(ctx->opcode)); \
|
|
|
|
gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
|
|
|
|
cpu_env, uim, rb); \
|
|
|
|
tcg_temp_free_i32(uim); \
|
|
|
|
tcg_temp_free_ptr(rb); \
|
|
|
|
}
|
|
|
|
|
2021-10-29 22:24:11 +03:00
|
|
|
#define TRANS_DFP_BF_A_DCM(NAME) \
|
|
|
|
static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
|
|
|
|
{ \
|
|
|
|
TCGv_ptr ra; \
|
|
|
|
REQUIRE_INSNS_FLAGS2(ctx, DFP); \
|
|
|
|
REQUIRE_FPU(ctx); \
|
|
|
|
ra = gen_fprp_ptr(a->fra); \
|
|
|
|
gen_helper_##NAME(cpu_crf[a->bf], \
|
|
|
|
cpu_env, ra, tcg_constant_i32(a->dm)); \
|
|
|
|
tcg_temp_free_ptr(ra); \
|
|
|
|
return true; \
|
2016-07-27 09:56:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
#define GEN_DFP_T_B_U32_U32_Rc(name, u32f1, u32f2) \
|
|
|
|
static void gen_##name(DisasContext *ctx) \
|
|
|
|
{ \
|
|
|
|
TCGv_ptr rt, rb; \
|
|
|
|
TCGv_i32 u32_1, u32_2; \
|
|
|
|
if (unlikely(!ctx->fpu_enabled)) { \
|
|
|
|
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
rt = gen_fprp_ptr(rD(ctx->opcode)); \
|
|
|
|
rb = gen_fprp_ptr(rB(ctx->opcode)); \
|
|
|
|
u32_1 = tcg_const_i32(u32f1(ctx->opcode)); \
|
|
|
|
u32_2 = tcg_const_i32(u32f2(ctx->opcode)); \
|
|
|
|
gen_helper_##name(cpu_env, rt, rb, u32_1, u32_2); \
|
|
|
|
if (unlikely(Rc(ctx->opcode) != 0)) { \
|
|
|
|
gen_set_cr1_from_fpscr(ctx); \
|
|
|
|
} \
|
|
|
|
tcg_temp_free_ptr(rt); \
|
|
|
|
tcg_temp_free_ptr(rb); \
|
|
|
|
tcg_temp_free_i32(u32_1); \
|
|
|
|
tcg_temp_free_i32(u32_2); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define GEN_DFP_T_A_B_I32_Rc(name, i32fld) \
|
|
|
|
static void gen_##name(DisasContext *ctx) \
|
|
|
|
{ \
|
|
|
|
TCGv_ptr rt, ra, rb; \
|
|
|
|
TCGv_i32 i32; \
|
|
|
|
if (unlikely(!ctx->fpu_enabled)) { \
|
|
|
|
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
rt = gen_fprp_ptr(rD(ctx->opcode)); \
|
|
|
|
ra = gen_fprp_ptr(rA(ctx->opcode)); \
|
|
|
|
rb = gen_fprp_ptr(rB(ctx->opcode)); \
|
|
|
|
i32 = tcg_const_i32(i32fld(ctx->opcode)); \
|
|
|
|
gen_helper_##name(cpu_env, rt, ra, rb, i32); \
|
|
|
|
if (unlikely(Rc(ctx->opcode) != 0)) { \
|
|
|
|
gen_set_cr1_from_fpscr(ctx); \
|
|
|
|
} \
|
|
|
|
tcg_temp_free_ptr(rt); \
|
|
|
|
tcg_temp_free_ptr(rb); \
|
|
|
|
tcg_temp_free_ptr(ra); \
|
|
|
|
tcg_temp_free_i32(i32); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define GEN_DFP_T_B_Rc(name) \
|
|
|
|
static void gen_##name(DisasContext *ctx) \
|
|
|
|
{ \
|
|
|
|
TCGv_ptr rt, rb; \
|
|
|
|
if (unlikely(!ctx->fpu_enabled)) { \
|
|
|
|
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
rt = gen_fprp_ptr(rD(ctx->opcode)); \
|
|
|
|
rb = gen_fprp_ptr(rB(ctx->opcode)); \
|
|
|
|
gen_helper_##name(cpu_env, rt, rb); \
|
|
|
|
if (unlikely(Rc(ctx->opcode) != 0)) { \
|
|
|
|
gen_set_cr1_from_fpscr(ctx); \
|
|
|
|
} \
|
|
|
|
tcg_temp_free_ptr(rt); \
|
|
|
|
tcg_temp_free_ptr(rb); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define GEN_DFP_T_FPR_I32_Rc(name, fprfld, i32fld) \
|
|
|
|
static void gen_##name(DisasContext *ctx) \
|
|
|
|
{ \
|
|
|
|
TCGv_ptr rt, rs; \
|
|
|
|
TCGv_i32 i32; \
|
|
|
|
if (unlikely(!ctx->fpu_enabled)) { \
|
|
|
|
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
rt = gen_fprp_ptr(rD(ctx->opcode)); \
|
|
|
|
rs = gen_fprp_ptr(fprfld(ctx->opcode)); \
|
|
|
|
i32 = tcg_const_i32(i32fld(ctx->opcode)); \
|
|
|
|
gen_helper_##name(cpu_env, rt, rs, i32); \
|
|
|
|
if (unlikely(Rc(ctx->opcode) != 0)) { \
|
|
|
|
gen_set_cr1_from_fpscr(ctx); \
|
|
|
|
} \
|
|
|
|
tcg_temp_free_ptr(rt); \
|
|
|
|
tcg_temp_free_ptr(rs); \
|
|
|
|
tcg_temp_free_i32(i32); \
|
|
|
|
}
|
|
|
|
|
2021-10-29 22:24:12 +03:00
|
|
|
TRANS_DFP_T_A_B_Rc(DADD)
|
|
|
|
TRANS_DFP_T_A_B_Rc(DADDQ)
|
|
|
|
TRANS_DFP_T_A_B_Rc(DSUB)
|
|
|
|
TRANS_DFP_T_A_B_Rc(DSUBQ)
|
|
|
|
TRANS_DFP_T_A_B_Rc(DMUL)
|
|
|
|
TRANS_DFP_T_A_B_Rc(DMULQ)
|
|
|
|
TRANS_DFP_T_A_B_Rc(DDIV)
|
|
|
|
TRANS_DFP_T_A_B_Rc(DDIVQ)
|
2016-07-27 09:56:22 +03:00
|
|
|
GEN_DFP_BF_A_B(dcmpu)
|
|
|
|
GEN_DFP_BF_A_B(dcmpuq)
|
|
|
|
GEN_DFP_BF_A_B(dcmpo)
|
|
|
|
GEN_DFP_BF_A_B(dcmpoq)
|
2021-10-29 22:24:11 +03:00
|
|
|
TRANS_DFP_BF_A_DCM(DTSTDC)
|
|
|
|
TRANS_DFP_BF_A_DCM(DTSTDCQ)
|
|
|
|
TRANS_DFP_BF_A_DCM(DTSTDG)
|
|
|
|
TRANS_DFP_BF_A_DCM(DTSTDGQ)
|
2016-07-27 09:56:22 +03:00
|
|
|
GEN_DFP_BF_A_B(dtstex)
|
|
|
|
GEN_DFP_BF_A_B(dtstexq)
|
|
|
|
GEN_DFP_BF_A_B(dtstsf)
|
|
|
|
GEN_DFP_BF_A_B(dtstsfq)
|
2016-07-28 21:14:13 +03:00
|
|
|
GEN_DFP_BF_I_B(dtstsfi)
|
|
|
|
GEN_DFP_BF_I_B(dtstsfiq)
|
2016-07-27 09:56:22 +03:00
|
|
|
GEN_DFP_T_B_U32_U32_Rc(dquai, SIMM5, RMC)
|
|
|
|
GEN_DFP_T_B_U32_U32_Rc(dquaiq, SIMM5, RMC)
|
|
|
|
GEN_DFP_T_A_B_I32_Rc(dqua, RMC)
|
|
|
|
GEN_DFP_T_A_B_I32_Rc(dquaq, RMC)
|
|
|
|
GEN_DFP_T_A_B_I32_Rc(drrnd, RMC)
|
|
|
|
GEN_DFP_T_A_B_I32_Rc(drrndq, RMC)
|
|
|
|
GEN_DFP_T_B_U32_U32_Rc(drintx, FPW, RMC)
|
|
|
|
GEN_DFP_T_B_U32_U32_Rc(drintxq, FPW, RMC)
|
|
|
|
GEN_DFP_T_B_U32_U32_Rc(drintn, FPW, RMC)
|
|
|
|
GEN_DFP_T_B_U32_U32_Rc(drintnq, FPW, RMC)
|
|
|
|
GEN_DFP_T_B_Rc(dctdp)
|
|
|
|
GEN_DFP_T_B_Rc(dctqpq)
|
|
|
|
GEN_DFP_T_B_Rc(drsp)
|
|
|
|
GEN_DFP_T_B_Rc(drdpq)
|
|
|
|
GEN_DFP_T_B_Rc(dcffix)
|
|
|
|
GEN_DFP_T_B_Rc(dcffixq)
|
|
|
|
GEN_DFP_T_B_Rc(dctfix)
|
|
|
|
GEN_DFP_T_B_Rc(dctfixq)
|
|
|
|
GEN_DFP_T_FPR_I32_Rc(ddedpd, rB, SP)
|
|
|
|
GEN_DFP_T_FPR_I32_Rc(ddedpdq, rB, SP)
|
|
|
|
GEN_DFP_T_FPR_I32_Rc(denbcd, rB, SP)
|
|
|
|
GEN_DFP_T_FPR_I32_Rc(denbcdq, rB, SP)
|
|
|
|
GEN_DFP_T_B_Rc(dxex)
|
|
|
|
GEN_DFP_T_B_Rc(dxexq)
|
2021-10-29 22:24:12 +03:00
|
|
|
TRANS_DFP_T_A_B_Rc(DIEX)
|
|
|
|
TRANS_DFP_T_A_B_Rc(DIEXQ)
|
2016-07-27 09:56:22 +03:00
|
|
|
GEN_DFP_T_FPR_I32_Rc(dscli, rA, DCM)
|
|
|
|
GEN_DFP_T_FPR_I32_Rc(dscliq, rA, DCM)
|
|
|
|
GEN_DFP_T_FPR_I32_Rc(dscri, rA, DCM)
|
|
|
|
GEN_DFP_T_FPR_I32_Rc(dscriq, rA, DCM)
|
|
|
|
|
|
|
|
#undef GEN_DFP_BF_A_B
|
|
|
|
#undef GEN_DFP_T_B_U32_U32_Rc
|
|
|
|
#undef GEN_DFP_T_A_B_I32_Rc
|
|
|
|
#undef GEN_DFP_T_B_Rc
|
|
|
|
#undef GEN_DFP_T_FPR_I32_Rc
|
2021-10-29 22:24:06 +03:00
|
|
|
|
|
|
|
static bool trans_DCFFIXQQ(DisasContext *ctx, arg_DCFFIXQQ *a)
|
|
|
|
{
|
|
|
|
TCGv_ptr rt, rb;
|
|
|
|
|
|
|
|
REQUIRE_INSNS_FLAGS2(ctx, DFP);
|
|
|
|
REQUIRE_FPU(ctx);
|
|
|
|
REQUIRE_VECTOR(ctx);
|
|
|
|
|
|
|
|
rt = gen_fprp_ptr(a->frtp);
|
|
|
|
rb = gen_avr_ptr(a->vrb);
|
|
|
|
gen_helper_DCFFIXQQ(cpu_env, rt, rb);
|
|
|
|
tcg_temp_free_ptr(rt);
|
|
|
|
tcg_temp_free_ptr(rb);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2021-10-29 22:24:09 +03:00
|
|
|
|
|
|
|
static bool trans_DCTFIXQQ(DisasContext *ctx, arg_DCTFIXQQ *a)
|
|
|
|
{
|
|
|
|
TCGv_ptr rt, rb;
|
|
|
|
|
|
|
|
REQUIRE_INSNS_FLAGS2(ctx, DFP);
|
|
|
|
REQUIRE_FPU(ctx);
|
|
|
|
REQUIRE_VECTOR(ctx);
|
|
|
|
|
|
|
|
rt = gen_avr_ptr(a->vrt);
|
|
|
|
rb = gen_fprp_ptr(a->frbp);
|
|
|
|
gen_helper_DCTFIXQQ(cpu_env, rt, rb);
|
|
|
|
tcg_temp_free_ptr(rt);
|
|
|
|
tcg_temp_free_ptr(rb);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|