@@ -3295,11 +3295,46 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
} \
}
-VSX_TEST_DC(xvtstdcdp, 2, xB(opcode), float64, VsrD(i), VsrD(i), UINT64_MAX, 0)
-VSX_TEST_DC(xvtstdcsp, 4, xB(opcode), float32, VsrW(i), VsrW(i), UINT32_MAX, 0)
VSX_TEST_DC(xststdcdp, 1, xB(opcode), float64, VsrD(0), VsrD(0), 0, 1)
VSX_TEST_DC(xststdcqp, 1, (rB(opcode) + 32), float128, f128, VsrD(0), 0, 1)
+#define VSX_TSTDC(tp) \
+static int32_t tp##_tstdc(tp b, uint32_t dcmx) \
+{ \
+ uint32_t match = 0; \
+ uint32_t sign = tp##_is_neg(b); \
+ if (tp##_is_any_nan(b)) { \
+ match = extract32(dcmx, 6, 1); \
+ } else if (tp##_is_infinity(b)) { \
+ match = extract32(dcmx, 4 + !sign, 1); \
+ } else if (tp##_is_zero(b)) { \
+ match = extract32(dcmx, 2 + !sign, 1); \
+ } else if (tp##_is_zero_or_denormal(b)) { \
+ match = extract32(dcmx, 0 + !sign, 1); \
+ } \
+ return (match != 0) ? 1 : 0; \
+}
+
+VSX_TSTDC(float32)
+VSX_TSTDC(float64)
+#undef VSX_TSTDC
+
+void helper_XVTSTDCDP(ppc_vsr_t *t, ppc_vsr_t *b, uint64_t dcmx, uint32_t v)
+{
+ int i;
+ for (i = 0; i < 2; i++) {
+ t->s64[i] = (int64_t)-float64_tstdc(b->f64[i], dcmx);
+ }
+}
+
+void helper_XVTSTDCSP(ppc_vsr_t *t, ppc_vsr_t *b, uint64_t dcmx, uint32_t v)
+{
+ int i;
+ for (i = 0; i < 4; i++) {
+ t->s32[i] = (int32_t)-float32_tstdc(b->f32[i], dcmx);
+ }
+}
+
void helper_xststdcsp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xb)
{
uint32_t dcmx, sign, exp;
@@ -521,8 +521,8 @@ DEF_HELPER_3(xvcvsxdsp, void, env, vsr, vsr)
DEF_HELPER_3(xvcvuxdsp, void, env, vsr, vsr)
DEF_HELPER_3(xvcvsxwsp, void, env, vsr, vsr)
DEF_HELPER_3(xvcvuxwsp, void, env, vsr, vsr)
-DEF_HELPER_2(xvtstdcsp, void, env, i32)
-DEF_HELPER_2(xvtstdcdp, void, env, i32)
+DEF_HELPER_FLAGS_4(XVTSTDCSP, TCG_CALL_NO_RWG, void, vsr, vsr, i64, i32)
+DEF_HELPER_FLAGS_4(XVTSTDCDP, TCG_CALL_NO_RWG, void, vsr, vsr, i64, i32)
DEF_HELPER_3(xvrspi, void, env, vsr, vsr)
DEF_HELPER_3(xvrspic, void, env, vsr, vsr)
DEF_HELPER_3(xvrspim, void, env, vsr, vsr)
@@ -199,6 +199,9 @@
@XX2_uim4 ...... ..... . uim:4 ..... ......... .. &XX2_uim xt=%xx_xt xb=%xx_xb
+%xx_uim7 6:1 2:1 16:5
+@XX2_uim7 ...... ..... ..... ..... .... . ... . .. &XX2_uim xt=%xx_xt xb=%xx_xb uim=%xx_uim7
+
&XX2_bf_xb bf xb
@XX2_bf_xb ...... bf:3 .. ..... ..... ......... . . &XX2_bf_xb xb=%xx_xb
@@ -848,6 +851,8 @@ XSCVSPDPN 111100 ..... ----- ..... 101001011 .. @XX2
## VSX Binary Floating-Point Math Support Instructions
XVXSIGSP 111100 ..... 01001 ..... 111011011 .. @XX2
+XVTSTDCDP 111100 ..... ..... ..... 1111 . 101 ... @XX2_uim7
+XVTSTDCSP 111100 ..... ..... ..... 1101 . 101 ... @XX2_uim7
## VSX Vector Test Least-Significant Bit by Byte Instruction
@@ -630,6 +630,8 @@ static void gen_mtvsrws(DisasContext *ctx)
#define OP_CPSGN 4
#define SGN_MASK_DP 0x8000000000000000ull
#define SGN_MASK_SP 0x8000000080000000ull
+#define EXP_MASK_DP 0x7FF0000000000000ull
+#define EXP_MASK_SP 0x7F8000007F800000ull
#define VSX_SCALAR_MOVE(name, op, sgn_mask) \
static void glue(gen_, name)(DisasContext *ctx) \
@@ -1119,6 +1121,30 @@ GEN_VSX_HELPER_X2(xscvhpdp, 0x16, 0x15, 0x10, PPC2_ISA300)
GEN_VSX_HELPER_R2(xscvsdqp, 0x04, 0x1A, 0x0A, PPC2_ISA300)
GEN_VSX_HELPER_X2(xscvspdp, 0x12, 0x14, 0, PPC2_VSX)
+static bool do_xvtstdc(DisasContext *ctx, arg_XX2_uim *a, unsigned vece)
+{
+ static const GVecGen2i op[] = {
+ {
+ .fnoi = gen_helper_XVTSTDCSP,
+ .vece = MO_32
+ },
+ {
+ .fnoi = gen_helper_XVTSTDCDP,
+ .vece = MO_64
+ },
+ };
+
+ REQUIRE_VSX(ctx);
+
+ tcg_gen_gvec_2i(vsr_full_offset(a->xt), vsr_full_offset(a->xb),
+ 16, 16, (int32_t)(a->uim), &op[vece - MO_32]);
+
+ return true;
+}
+
+TRANS_FLAGS2(VSX, XVTSTDCSP, do_xvtstdc, MO_32)
+TRANS_FLAGS2(VSX, XVTSTDCDP, do_xvtstdc, MO_64)
+
bool trans_XSCVSPDPN(DisasContext *ctx, arg_XX2 *a)
{
TCGv_i64 tmp;
@@ -1222,8 +1248,6 @@ GEN_VSX_HELPER_X2(xvrspic, 0x16, 0x0A, 0, PPC2_VSX)
GEN_VSX_HELPER_X2(xvrspim, 0x12, 0x0B, 0, PPC2_VSX)
GEN_VSX_HELPER_X2(xvrspip, 0x12, 0x0A, 0, PPC2_VSX)
GEN_VSX_HELPER_X2(xvrspiz, 0x12, 0x09, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvtstdcsp, 0x14, 0x1A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvtstdcdp, 0x14, 0x1E, 0, PPC2_VSX)
static bool trans_XXPERM(DisasContext *ctx, arg_XX3 *a)
{
@@ -157,14 +157,6 @@ GEN_XX2FORM_EO(xvxexpdp, 0x16, 0x1D, 0x00, PPC2_ISA300),
GEN_XX2FORM_EO(xvxsigdp, 0x16, 0x1D, 0x01, PPC2_ISA300),
GEN_XX2FORM_EO(xvxexpsp, 0x16, 0x1D, 0x08, PPC2_ISA300),
-/* DCMX = bit[25] << 6 | bit[29] << 5 | bit[11:15] */
-#define GEN_XX2FORM_DCMX(name, opc2, opc3, fl2) \
-GEN_XX3FORM(name, opc2, opc3 | 0, fl2), \
-GEN_XX3FORM(name, opc2, opc3 | 1, fl2)
-
-GEN_XX2FORM_DCMX(xvtstdcdp, 0x14, 0x1E, PPC2_ISA300),
-GEN_XX2FORM_DCMX(xvtstdcsp, 0x14, 0x1A, PPC2_ISA300),
-
GEN_XX3FORM(xsadddp, 0x00, 0x04, PPC2_VSX),
GEN_VSX_XFORM_300(xsaddqp, 0x04, 0x00, 0x0),
GEN_XX3FORM(xssubdp, 0x00, 0x05, PPC2_VSX),