target/ppc: Implement DCTFIXQQ
Implement the following PowerISA v3.1 instruction: dctfixqq: DFP Convert To Fixed Quadword Quad Signed-off-by: Luis Pires <luis.pires@eldorado.org.br> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20211029192417.400707-8-luis.pires@eldorado.org.br> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
21d7826fdb
commit
328747f32f
@ -51,6 +51,11 @@ static void set_dfp128(ppc_fprp_t *dfp, ppc_vsr_t *src)
|
|||||||
dfp[1].VsrD(0) = src->VsrD(1);
|
dfp[1].VsrD(0) = src->VsrD(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_dfp128_to_avr(ppc_avr_t *dst, ppc_vsr_t *src)
|
||||||
|
{
|
||||||
|
*dst = *src;
|
||||||
|
}
|
||||||
|
|
||||||
struct PPC_DFP {
|
struct PPC_DFP {
|
||||||
CPUPPCState *env;
|
CPUPPCState *env;
|
||||||
ppc_vsr_t vt, va, vb;
|
ppc_vsr_t vt, va, vb;
|
||||||
@ -1020,6 +1025,53 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \
|
|||||||
DFP_HELPER_CTFIX(dctfix, 64)
|
DFP_HELPER_CTFIX(dctfix, 64)
|
||||||
DFP_HELPER_CTFIX(dctfixq, 128)
|
DFP_HELPER_CTFIX(dctfixq, 128)
|
||||||
|
|
||||||
|
void helper_DCTFIXQQ(CPUPPCState *env, ppc_avr_t *t, ppc_fprp_t *b)
|
||||||
|
{
|
||||||
|
struct PPC_DFP dfp;
|
||||||
|
dfp_prepare_decimal128(&dfp, 0, b, env);
|
||||||
|
|
||||||
|
if (unlikely(decNumberIsSpecial(&dfp.b))) {
|
||||||
|
uint64_t invalid_flags = FP_VX | FP_VXCVI;
|
||||||
|
if (decNumberIsInfinite(&dfp.b)) {
|
||||||
|
if (decNumberIsNegative(&dfp.b)) {
|
||||||
|
dfp.vt.VsrD(0) = INT64_MIN;
|
||||||
|
dfp.vt.VsrD(1) = 0;
|
||||||
|
} else {
|
||||||
|
dfp.vt.VsrD(0) = INT64_MAX;
|
||||||
|
dfp.vt.VsrD(1) = UINT64_MAX;
|
||||||
|
}
|
||||||
|
} else { /* NaN */
|
||||||
|
dfp.vt.VsrD(0) = INT64_MIN;
|
||||||
|
dfp.vt.VsrD(1) = 0;
|
||||||
|
if (decNumberIsSNaN(&dfp.b)) {
|
||||||
|
invalid_flags |= FP_VXSNAN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dfp_set_FPSCR_flag(&dfp, invalid_flags, FP_VE);
|
||||||
|
} else if (unlikely(decNumberIsZero(&dfp.b))) {
|
||||||
|
dfp.vt.VsrD(0) = 0;
|
||||||
|
dfp.vt.VsrD(1) = 0;
|
||||||
|
} else {
|
||||||
|
decNumberToIntegralExact(&dfp.b, &dfp.b, &dfp.context);
|
||||||
|
decNumberIntegralToInt128(&dfp.b, &dfp.context,
|
||||||
|
&dfp.vt.VsrD(1), &dfp.vt.VsrD(0));
|
||||||
|
if (decContextTestStatus(&dfp.context, DEC_Invalid_operation)) {
|
||||||
|
if (decNumberIsNegative(&dfp.b)) {
|
||||||
|
dfp.vt.VsrD(0) = INT64_MIN;
|
||||||
|
dfp.vt.VsrD(1) = 0;
|
||||||
|
} else {
|
||||||
|
dfp.vt.VsrD(0) = INT64_MAX;
|
||||||
|
dfp.vt.VsrD(1) = UINT64_MAX;
|
||||||
|
}
|
||||||
|
dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FP_VE);
|
||||||
|
} else {
|
||||||
|
dfp_check_for_XX(&dfp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set_dfp128_to_avr(t, &dfp.vt);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void dfp_set_bcd_digit_64(ppc_vsr_t *t, uint8_t digit,
|
static inline void dfp_set_bcd_digit_64(ppc_vsr_t *t, uint8_t digit,
|
||||||
unsigned n)
|
unsigned n)
|
||||||
{
|
{
|
||||||
|
@ -739,6 +739,7 @@ DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
|
|||||||
DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
|
DEF_HELPER_3(DCFFIXQQ, void, env, fprp, avr)
|
||||||
DEF_HELPER_3(dctfix, void, env, fprp, fprp)
|
DEF_HELPER_3(dctfix, void, env, fprp, fprp)
|
||||||
DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
|
DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
|
||||||
|
DEF_HELPER_3(DCTFIXQQ, void, env, avr, fprp)
|
||||||
DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
|
DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
|
||||||
DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
|
DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
|
||||||
DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
|
DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
|
||||||
|
@ -54,6 +54,10 @@
|
|||||||
%x_frtp 22:4 !function=times_2
|
%x_frtp 22:4 !function=times_2
|
||||||
@X_frtp_vrb ...... ....0 ..... vrb:5 .......... . &X_frtp_vrb frtp=%x_frtp
|
@X_frtp_vrb ...... ....0 ..... vrb:5 .......... . &X_frtp_vrb frtp=%x_frtp
|
||||||
|
|
||||||
|
&X_vrt_frbp vrt frbp
|
||||||
|
%x_frbp 12:4 !function=times_2
|
||||||
|
@X_vrt_frbp ...... vrt:5 ..... ....0 .......... . &X_vrt_frbp frbp=%x_frbp
|
||||||
|
|
||||||
### Fixed-Point Load Instructions
|
### Fixed-Point Load Instructions
|
||||||
|
|
||||||
LBZ 100010 ..... ..... ................ @D
|
LBZ 100010 ..... ..... ................ @D
|
||||||
@ -167,6 +171,7 @@ SETNBCR 011111 ..... ..... ----- 0111100000 - @X_bi
|
|||||||
### Decimal Floating-Point Conversion Instructions
|
### Decimal Floating-Point Conversion Instructions
|
||||||
|
|
||||||
DCFFIXQQ 111111 ..... 00000 ..... 1111100010 - @X_frtp_vrb
|
DCFFIXQQ 111111 ..... 00000 ..... 1111100010 - @X_frtp_vrb
|
||||||
|
DCTFIXQQ 111111 ..... 00001 ..... 1111100010 - @X_vrt_frbp
|
||||||
|
|
||||||
## Vector Bit Manipulation Instruction
|
## Vector Bit Manipulation Instruction
|
||||||
|
|
||||||
|
@ -247,3 +247,20 @@ static bool trans_DCFFIXQQ(DisasContext *ctx, arg_DCFFIXQQ *a)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user