@@ -3241,63 +3241,6 @@ void helper_XVXSIGSP(ppc_vsr_t *xt, ppc_vsr_t *xb)
*xt = t;
}
-/*
- * VSX_TEST_DC - VSX floating point test data class
- * op - instruction mnemonic
- * nels - number of elements (1, 2 or 4)
- * xbn - VSR register number
- * tp - type (float32 or float64)
- * fld - vsr_t field (VsrD(*) or VsrW(*))
- * tfld - target vsr_t field (VsrD(*) or VsrW(*))
- * fld_max - target field max
- * scrf - set result in CR and FPCC
- */
-#define VSX_TEST_DC(op, nels, xbn, tp, fld, tfld, fld_max, scrf) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t *xt = &env->vsr[xT(opcode)]; \
- ppc_vsr_t *xb = &env->vsr[xbn]; \
- ppc_vsr_t t = { }; \
- uint32_t i, sign, dcmx; \
- uint32_t cc, match = 0; \
- \
- if (!scrf) { \
- dcmx = DCMX_XV(opcode); \
- } else { \
- t = *xt; \
- dcmx = DCMX(opcode); \
- } \
- \
- for (i = 0; i < nels; i++) { \
- sign = tp##_is_neg(xb->fld); \
- if (tp##_is_any_nan(xb->fld)) { \
- match = extract32(dcmx, 6, 1); \
- } else if (tp##_is_infinity(xb->fld)) { \
- match = extract32(dcmx, 4 + !sign, 1); \
- } else if (tp##_is_zero(xb->fld)) { \
- match = extract32(dcmx, 2 + !sign, 1); \
- } else if (tp##_is_zero_or_denormal(xb->fld)) { \
- match = extract32(dcmx, 0 + !sign, 1); \
- } \
- \
- if (scrf) { \
- cc = sign << CRF_LT_BIT | match << CRF_EQ_BIT; \
- env->fpscr &= ~FP_FPCC; \
- env->fpscr |= cc << FPSCR_FPCC; \
- env->crf[BF(opcode)] = cc; \
- } else { \
- t.tfld = match ? fld_max : 0; \
- } \
- match = 0; \
- } \
- if (!scrf) { \
- *xt = t; \
- } \
-}
-
-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) \
{ \
@@ -3317,6 +3260,7 @@ static int32_t tp##_tstdc(tp b, uint32_t dcmx) \
VSX_TSTDC(float32)
VSX_TSTDC(float64)
+VSX_TSTDC(float128)
#undef VSX_TSTDC
void helper_XVTSTDCDP(ppc_vsr_t *t, ppc_vsr_t *b, uint64_t dcmx, uint32_t v)
@@ -3335,34 +3279,44 @@ void helper_XVTSTDCSP(ppc_vsr_t *t, ppc_vsr_t *b, uint64_t dcmx, uint32_t v)
}
}
-void helper_xststdcsp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xb)
+static bool not_SP_value(float64 val)
{
- uint32_t dcmx, sign, exp;
- uint32_t cc, match = 0, not_sp = 0;
- float64 arg = xb->VsrD(0);
- float64 arg_sp;
-
- dcmx = DCMX(opcode);
- exp = (arg >> 52) & 0x7FF;
- sign = float64_is_neg(arg);
-
- if (float64_is_any_nan(arg)) {
- match = extract32(dcmx, 6, 1);
- } else if (float64_is_infinity(arg)) {
- match = extract32(dcmx, 4 + !sign, 1);
- } else if (float64_is_zero(arg)) {
- match = extract32(dcmx, 2 + !sign, 1);
- } else if (float64_is_zero_or_denormal(arg) || (exp > 0 && exp < 0x381)) {
- match = extract32(dcmx, 0 + !sign, 1);
- }
-
- arg_sp = helper_todouble(helper_tosingle(arg));
- not_sp = arg != arg_sp;
+ return val != helper_todouble(helper_tosingle(val));
+}
+/*
+ * VSX_XS_TSTDC - VSX Scalar Test Data Class
+ * NAME - instruction name
+ * FLD - vsr_t field (VsrD(0) or f128)
+ * TP - type (float64 or float128)
+ */
+#define VSX_XS_TSTDC(NAME, FLD, TP) \
+ void helper_##NAME(CPUPPCState *env, uint32_t bf, \
+ uint32_t dcmx, ppc_vsr_t *b) \
+ { \
+ uint32_t cc, match, sign = TP##_is_neg(b->FLD); \
+ match = TP##_tstdc(b->FLD, dcmx); \
+ cc = sign << CRF_LT_BIT | match << CRF_EQ_BIT; \
+ env->fpscr &= ~FP_FPCC; \
+ env->fpscr |= cc << FPSCR_FPCC; \
+ env->crf[bf] = cc; \
+ }
+
+VSX_XS_TSTDC(XSTSTDCDP, VsrD(0), float64)
+VSX_XS_TSTDC(XSTSTDCQP, f128, float128)
+#undef VSX_XS_TSTDC
+
+void helper_XSTSTDCSP(CPUPPCState *env, uint32_t bf,
+ uint32_t dcmx, ppc_vsr_t *b)
+{
+ uint32_t cc, match, sign = float64_is_neg(b->VsrD(0));
+ uint32_t exp = (b->VsrD(0) >> 52) & 0x7FF;
+ int not_sp = (int)not_SP_value(b->VsrD(0));
+ match = float64_tstdc(b->VsrD(0), dcmx) || (exp > 0 && exp < 0x381);
cc = sign << CRF_LT_BIT | match << CRF_EQ_BIT | not_sp << CRF_SO_BIT;
env->fpscr &= ~FP_FPCC;
env->fpscr |= cc << FPSCR_FPCC;
- env->crf[BF(opcode)] = cc;
+ env->crf[bf] = cc;
}
void helper_xsrqpi(CPUPPCState *env, uint32_t opcode,
@@ -417,9 +417,9 @@ DEF_HELPER_3(xscvuxdsp, void, env, vsr, vsr)
DEF_HELPER_3(xscvsxdsp, void, env, vsr, vsr)
DEF_HELPER_4(xscvudqp, void, env, i32, vsr, vsr)
DEF_HELPER_3(xscvuxddp, void, env, vsr, vsr)
-DEF_HELPER_3(xststdcsp, void, env, i32, vsr)
-DEF_HELPER_2(xststdcdp, void, env, i32)
-DEF_HELPER_2(xststdcqp, void, env, i32)
+DEF_HELPER_4(XSTSTDCSP, void, env, i32, i32, vsr)
+DEF_HELPER_4(XSTSTDCDP, void, env, i32, i32, vsr)
+DEF_HELPER_4(XSTSTDCQP, void, env, i32, i32, vsr)
DEF_HELPER_3(xsrdpi, void, env, vsr, vsr)
DEF_HELPER_3(xsrdpic, void, env, vsr, vsr)
DEF_HELPER_3(xsrdpim, void, env, vsr, vsr)
@@ -202,6 +202,9 @@
%xx_uim7 6:1 2:1 16:5
@XX2_uim7 ...... ..... ..... ..... .... . ... . .. &XX2_uim xt=%xx_xt xb=%xx_xb uim=%xx_uim7
+&XX2_bf_uim bf xb uim
+@XX2_bf_uim ...... bf:3 uim:7 ..... ......... . . &XX2_bf_uim
+
&XX2_bf_xb bf xb
@XX2_bf_xb ...... bf:3 .. ..... ..... ......... . . &XX2_bf_xb xb=%xx_xb
@@ -853,6 +856,9 @@ XSCVSPDPN 111100 ..... ----- ..... 101001011 .. @XX2
XVXSIGSP 111100 ..... 01001 ..... 111011011 .. @XX2
XVTSTDCDP 111100 ..... ..... ..... 1111 . 101 ... @XX2_uim7
XVTSTDCSP 111100 ..... ..... ..... 1101 . 101 ... @XX2_uim7
+XSTSTDCSP 111100 ... ....... ..... 100101010 . - @XX2_bf_uim xb=%xx_xb
+XSTSTDCDP 111100 ... ....... ..... 101101010 . - @XX2_bf_uim xb=%xx_xb
+XSTSTDCQP 111111 ... ....... xb:5 1011000100 - @XX2_bf_uim
## VSX Vector Test Least-Significant Bit by Byte Instruction
@@ -1137,6 +1137,23 @@ static bool do_xvtstdc(DisasContext *ctx, arg_XX2_uim *a, unsigned vece)
TRANS_FLAGS2(VSX, XVTSTDCSP, do_xvtstdc, MO_32)
TRANS_FLAGS2(VSX, XVTSTDCDP, do_xvtstdc, MO_64)
+static bool do_XX2_bf_uim(DisasContext *ctx, arg_XX2_bf_uim *a, bool vsr,
+ void (*gen_helper)(TCGv_env, TCGv_i32, TCGv_i32, TCGv_ptr))
+{
+ TCGv_ptr xb;
+
+ REQUIRE_VSX(ctx);
+ xb = vsr ? gen_vsr_ptr(a->xb) : gen_avr_ptr(a->xb);
+ gen_helper(cpu_env, tcg_constant_i32(a->bf), tcg_constant_i32(a->uim), xb);
+ tcg_temp_free_ptr(xb);
+
+ return true;
+}
+
+TRANS_FLAGS2(ISA300, XSTSTDCSP, do_XX2_bf_uim, true, gen_helper_XSTSTDCSP)
+TRANS_FLAGS2(ISA300, XSTSTDCDP, do_XX2_bf_uim, true, gen_helper_XSTSTDCDP)
+TRANS_FLAGS2(ISA300, XSTSTDCQP, do_XX2_bf_uim, false, gen_helper_XSTSTDCQP)
+
bool trans_XSCVSPDPN(DisasContext *ctx, arg_XX2 *a)
{
TCGv_i64 tmp;
@@ -1183,9 +1200,6 @@ GEN_VSX_HELPER_X2(xssqrtsp, 0x16, 0x00, 0, PPC2_VSX207)
GEN_VSX_HELPER_X2(xsrsqrtesp, 0x14, 0x00, 0, PPC2_VSX207)
GEN_VSX_HELPER_X2(xscvsxdsp, 0x10, 0x13, 0, PPC2_VSX207)
GEN_VSX_HELPER_X2(xscvuxdsp, 0x10, 0x12, 0, PPC2_VSX207)
-GEN_VSX_HELPER_X1(xststdcsp, 0x14, 0x12, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xststdcdp, 0x14, 0x16, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xststdcqp, 0x04, 0x16, 0, PPC2_ISA300)
GEN_VSX_HELPER_X3(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
GEN_VSX_HELPER_X3(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -147,10 +147,6 @@ GEN_HANDLER_E(xsiexpdp, 0x3C, 0x16, 0x1C, 0, PPC_NONE, PPC2_ISA300),
GEN_VSX_XFORM_300(xsiexpqp, 0x4, 0x1B, 0x00000001),
#endif
-GEN_XX2FORM(xststdcdp, 0x14, 0x16, PPC2_ISA300),
-GEN_XX2FORM(xststdcsp, 0x14, 0x12, PPC2_ISA300),
-GEN_VSX_XFORM_300(xststdcqp, 0x04, 0x16, 0x00000001),
-
GEN_XX3FORM(xviexpsp, 0x00, 0x1B, PPC2_ISA300),
GEN_XX3FORM(xviexpdp, 0x00, 0x1F, PPC2_ISA300),
GEN_XX2FORM_EO(xvxexpdp, 0x16, 0x1D, 0x00, PPC2_ISA300),