aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/ppc/cpu.h10
-rw-r--r--target/ppc/dfp_helper.c394
-rw-r--r--target/ppc/fpu_helper.c122
-rw-r--r--target/ppc/helper.h2
-rw-r--r--target/ppc/int_helper.c72
-rw-r--r--target/ppc/internal.h3
-rw-r--r--target/ppc/kvm.c5
-rw-r--r--target/ppc/translate/fp-impl.inc.c99
-rw-r--r--target/ppc/translate/fp-ops.inc.c6
-rw-r--r--target/ppc/translate_init.inc.c9
10 files changed, 408 insertions, 314 deletions
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index eaee1a5575..e3e82327b7 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -235,6 +235,7 @@ typedef union _ppc_vsr_t {
} ppc_vsr_t;
typedef ppc_vsr_t ppc_avr_t;
+typedef ppc_vsr_t ppc_fprp_t;
#if !defined(CONFIG_USER_ONLY)
/* Software TLB cache */
@@ -559,6 +560,9 @@ enum {
/*****************************************************************************/
/* Floating point status and control register */
+#define FPSCR_DRN2 34 /* Decimal Floating-Point rounding control */
+#define FPSCR_DRN1 33 /* Decimal Floating-Point rounding control */
+#define FPSCR_DRN0 32 /* Decimal Floating-Point rounding control */
#define FPSCR_FX 31 /* Floating-point exception summary */
#define FPSCR_FEX 30 /* Floating-point enabled exception summary */
#define FPSCR_VX 29 /* Floating-point invalid operation exception summ. */
@@ -592,6 +596,7 @@ enum {
#define FPSCR_NI 2 /* Floating-point non-IEEE mode */
#define FPSCR_RN1 1
#define FPSCR_RN0 0 /* Floating-point rounding control */
+#define fpscr_drn (((env->fpscr) & FP_DRN) >> FPSCR_DRN0)
#define fpscr_fex (((env->fpscr) >> FPSCR_FEX) & 0x1)
#define fpscr_vx (((env->fpscr) >> FPSCR_VX) & 0x1)
#define fpscr_ox (((env->fpscr) >> FPSCR_OX) & 0x1)
@@ -627,6 +632,10 @@ enum {
#define fpscr_eex (((env->fpscr) >> FPSCR_XX) & ((env->fpscr) >> FPSCR_XE) & \
0x1F)
+#define FP_DRN2 (1ull << FPSCR_DRN2)
+#define FP_DRN1 (1ull << FPSCR_DRN1)
+#define FP_DRN0 (1ull << FPSCR_DRN0)
+#define FP_DRN (FP_DRN2 | FP_DRN1 | FP_DRN0)
#define FP_FX (1ull << FPSCR_FX)
#define FP_FEX (1ull << FPSCR_FEX)
#define FP_VX (1ull << FPSCR_VX)
@@ -662,7 +671,6 @@ enum {
#define FP_RN0 (1ull << FPSCR_RN0)
#define FP_RN (FP_RN1 | FP_RN0)
-#define FP_MODE FP_RN
#define FP_ENABLES (FP_VE | FP_OE | FP_UE | FP_ZE | FP_XE)
#define FP_STATUS (FP_FR | FP_FI | FP_FPRF)
diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index f102177572..2c65badae4 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -28,17 +28,32 @@
#include "libdecnumber/dpd/decimal64.h"
#include "libdecnumber/dpd/decimal128.h"
-#if defined(HOST_WORDS_BIGENDIAN)
-#define HI_IDX 0
-#define LO_IDX 1
-#else
-#define HI_IDX 1
-#define LO_IDX 0
-#endif
+
+static void get_dfp64(ppc_vsr_t *dst, ppc_fprp_t *dfp)
+{
+ dst->VsrD(1) = dfp->VsrD(0);
+}
+
+static void get_dfp128(ppc_vsr_t *dst, ppc_fprp_t *dfp)
+{
+ dst->VsrD(0) = dfp[0].VsrD(0);
+ dst->VsrD(1) = dfp[1].VsrD(0);
+}
+
+static void set_dfp64(ppc_fprp_t *dfp, ppc_vsr_t *src)
+{
+ dfp->VsrD(0) = src->VsrD(1);
+}
+
+static void set_dfp128(ppc_fprp_t *dfp, ppc_vsr_t *src)
+{
+ dfp[0].VsrD(0) = src->VsrD(0);
+ dfp[1].VsrD(0) = src->VsrD(1);
+}
struct PPC_DFP {
CPUPPCState *env;
- uint64_t t64[2], a64[2], b64[2];
+ ppc_vsr_t vt, va, vb;
decNumber t, a, b;
decContext context;
uint8_t crbf;
@@ -48,7 +63,7 @@ static void dfp_prepare_rounding_mode(decContext *context, uint64_t fpscr)
{
enum rounding rnd;
- switch ((fpscr >> 32) & 0x7) {
+ switch ((fpscr & FP_DRN) >> FPSCR_DRN0) {
case 0:
rnd = DEC_ROUND_HALF_EVEN;
break;
@@ -121,56 +136,64 @@ static void dfp_set_round_mode_from_immediate(uint8_t r, uint8_t rmc,
decContextSetRounding(&dfp->context, rnd);
}
-static void dfp_prepare_decimal64(struct PPC_DFP *dfp, uint64_t *a,
- uint64_t *b, CPUPPCState *env)
+static void dfp_prepare_decimal64(struct PPC_DFP *dfp, ppc_fprp_t *a,
+ ppc_fprp_t *b, CPUPPCState *env)
{
decContextDefault(&dfp->context, DEC_INIT_DECIMAL64);
dfp_prepare_rounding_mode(&dfp->context, env->fpscr);
dfp->env = env;
if (a) {
- dfp->a64[0] = *a;
- decimal64ToNumber((decimal64 *)dfp->a64, &dfp->a);
+ get_dfp64(&dfp->va, a);
+ decimal64ToNumber((decimal64 *)&dfp->va.VsrD(1), &dfp->a);
} else {
- dfp->a64[0] = 0;
+ dfp->va.VsrD(1) = 0;
decNumberZero(&dfp->a);
}
if (b) {
- dfp->b64[0] = *b;
- decimal64ToNumber((decimal64 *)dfp->b64, &dfp->b);
+ get_dfp64(&dfp->vb, b);
+ decimal64ToNumber((decimal64 *)&dfp->vb.VsrD(1), &dfp->b);
} else {
- dfp->b64[0] = 0;
+ dfp->vb.VsrD(1) = 0;
decNumberZero(&dfp->b);
}
}
-static void dfp_prepare_decimal128(struct PPC_DFP *dfp, uint64_t *a,
- uint64_t *b, CPUPPCState *env)
+static void dfp_prepare_decimal128(struct PPC_DFP *dfp, ppc_fprp_t *a,
+ ppc_fprp_t *b, CPUPPCState *env)
{
decContextDefault(&dfp->context, DEC_INIT_DECIMAL128);
dfp_prepare_rounding_mode(&dfp->context, env->fpscr);
dfp->env = env;
if (a) {
- dfp->a64[0] = a[HI_IDX];
- dfp->a64[1] = a[LO_IDX];
- decimal128ToNumber((decimal128 *)dfp->a64, &dfp->a);
+ get_dfp128(&dfp->va, a);
+ decimal128ToNumber((decimal128 *)&dfp->va, &dfp->a);
} else {
- dfp->a64[0] = dfp->a64[1] = 0;
+ dfp->va.VsrD(0) = dfp->va.VsrD(1) = 0;
decNumberZero(&dfp->a);
}
if (b) {
- dfp->b64[0] = b[HI_IDX];
- dfp->b64[1] = b[LO_IDX];
- decimal128ToNumber((decimal128 *)dfp->b64, &dfp->b);
+ get_dfp128(&dfp->vb, b);
+ decimal128ToNumber((decimal128 *)&dfp->vb, &dfp->b);
} else {
- dfp->b64[0] = dfp->b64[1] = 0;
+ dfp->vb.VsrD(0) = dfp->vb.VsrD(1) = 0;
decNumberZero(&dfp->b);
}
}
+static void dfp_finalize_decimal64(struct PPC_DFP *dfp)
+{
+ decimal64FromNumber((decimal64 *)&dfp->vt.VsrD(1), &dfp->t, &dfp->context);
+}
+
+static void dfp_finalize_decimal128(struct PPC_DFP *dfp)
+{
+ decimal128FromNumber((decimal128 *)&dfp->vt, &dfp->t, &dfp->context);
+}
+
static void dfp_set_FPSCR_flag(struct PPC_DFP *dfp, uint64_t flag,
uint64_t enabled)
{
@@ -220,8 +243,8 @@ static void dfp_set_FPRF_from_FRT_with_context(struct PPC_DFP *dfp,
default:
assert(0); /* should never get here */
}
- dfp->env->fpscr &= ~(0x1F << 12);
- dfp->env->fpscr |= (fprf << 12);
+ dfp->env->fpscr &= ~FP_FPRF;
+ dfp->env->fpscr |= (fprf << FPSCR_FPRF);
}
static void dfp_set_FPRF_from_FRT(struct PPC_DFP *dfp)
@@ -369,8 +392,8 @@ static void dfp_set_CRBF_from_T(struct PPC_DFP *dfp)
static void dfp_set_FPCC_from_CRBF(struct PPC_DFP *dfp)
{
- dfp->env->fpscr &= ~(0xF << 12);
- dfp->env->fpscr |= (dfp->crbf << 12);
+ dfp->env->fpscr &= ~FP_FPCC;
+ dfp->env->fpscr |= (dfp->crbf << FPSCR_FPCC);
}
static inline void dfp_makeQNaN(decNumber *dn)
@@ -396,19 +419,15 @@ static inline int dfp_get_digit(decNumber *dn, int n)
}
#define DFP_HELPER_TAB(op, dnop, postprocs, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a, \
+ ppc_fprp_t *b) \
{ \
struct PPC_DFP dfp; \
dfp_prepare_decimal##size(&dfp, a, b, env); \
dnop(&dfp.t, &dfp.a, &dfp.b, &dfp.context); \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
+ dfp_finalize_decimal##size(&dfp); \
postprocs(&dfp); \
- if (size == 64) { \
- t[0] = dfp.t64[0]; \
- } else if (size == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
+ set_dfp##size(t, &dfp.vt); \
}
static void ADD_PPs(struct PPC_DFP *dfp)
@@ -466,12 +485,12 @@ DFP_HELPER_TAB(ddiv, decNumberDivide, DIV_PPs, 64)
DFP_HELPER_TAB(ddivq, decNumberDivide, DIV_PPs, 128)
#define DFP_HELPER_BF_AB(op, dnop, postprocs, size) \
-uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b) \
+uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b) \
{ \
struct PPC_DFP dfp; \
dfp_prepare_decimal##size(&dfp, a, b, env); \
dnop(&dfp.t, &dfp.a, &dfp.b, &dfp.context); \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
+ dfp_finalize_decimal##size(&dfp); \
postprocs(&dfp); \
return dfp.crbf; \
}
@@ -498,7 +517,7 @@ DFP_HELPER_BF_AB(dcmpo, decNumberCompare, CMPO_PPs, 64)
DFP_HELPER_BF_AB(dcmpoq, decNumberCompare, CMPO_PPs, 128)
#define DFP_HELPER_TSTDC(op, size) \
-uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint32_t dcm) \
+uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm) \
{ \
struct PPC_DFP dfp; \
int match = 0; \
@@ -526,7 +545,7 @@ DFP_HELPER_TSTDC(dtstdc, 64)
DFP_HELPER_TSTDC(dtstdcq, 128)
#define DFP_HELPER_TSTDG(op, size) \
-uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint32_t dcm) \
+uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, uint32_t dcm) \
{ \
struct PPC_DFP dfp; \
int minexp, maxexp, nzero_digits, nzero_idx, is_negative, is_zero, \
@@ -581,7 +600,7 @@ DFP_HELPER_TSTDG(dtstdg, 64)
DFP_HELPER_TSTDG(dtstdgq, 128)
#define DFP_HELPER_TSTEX(op, size) \
-uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b) \
+uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b) \
{ \
struct PPC_DFP dfp; \
int expa, expb, a_is_special, b_is_special; \
@@ -613,14 +632,16 @@ DFP_HELPER_TSTEX(dtstex, 64)
DFP_HELPER_TSTEX(dtstexq, 128)
#define DFP_HELPER_TSTSF(op, size) \
-uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b) \
+uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b) \
{ \
struct PPC_DFP dfp; \
unsigned k; \
+ ppc_vsr_t va; \
\
dfp_prepare_decimal##size(&dfp, 0, b, env); \
\
- k = *a & 0x3F; \
+ get_dfp64(&va, a); \
+ k = va.VsrD(1) & 0x3F; \
\
if (unlikely(decNumberIsSpecial(&dfp.b))) { \
dfp.crbf = 1; \
@@ -648,7 +669,7 @@ DFP_HELPER_TSTSF(dtstsf, 64)
DFP_HELPER_TSTSF(dtstsfq, 128)
#define DFP_HELPER_TSTSFI(op, size) \
-uint32_t helper_##op(CPUPPCState *env, uint32_t a, uint64_t *b) \
+uint32_t helper_##op(CPUPPCState *env, uint32_t a, ppc_fprp_t *b) \
{ \
struct PPC_DFP dfp; \
unsigned uim; \
@@ -708,7 +729,7 @@ static void dfp_quantize(uint8_t rmc, struct PPC_DFP *dfp)
}
#define DFP_HELPER_QUAI(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b, \
uint32_t te, uint32_t rmc) \
{ \
struct PPC_DFP dfp; \
@@ -719,40 +740,28 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, \
dfp.a.exponent = (int32_t)((int8_t)(te << 3) >> 3); \
\
dfp_quantize(rmc, &dfp); \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
- &dfp.context); \
+ dfp_finalize_decimal##size(&dfp); \
QUA_PPs(&dfp); \
\
- if (size == 64) { \
- t[0] = dfp.t64[0]; \
- } else if (size == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
+ set_dfp##size(t, &dfp.vt); \
}
DFP_HELPER_QUAI(dquai, 64)
DFP_HELPER_QUAI(dquaiq, 128)
#define DFP_HELPER_QUA(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, \
- uint64_t *b, uint32_t rmc) \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a, \
+ ppc_fprp_t *b, uint32_t rmc) \
{ \
struct PPC_DFP dfp; \
\
dfp_prepare_decimal##size(&dfp, a, b, env); \
\
dfp_quantize(rmc, &dfp); \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
- &dfp.context); \
+ dfp_finalize_decimal##size(&dfp); \
QUA_PPs(&dfp); \
\
- if (size == 64) { \
- t[0] = dfp.t64[0]; \
- } else if (size == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
+ set_dfp##size(t, &dfp.vt); \
}
DFP_HELPER_QUA(dqua, 64)
@@ -813,33 +822,31 @@ static void _dfp_reround(uint8_t rmc, int32_t ref_sig, int32_t xmax,
}
#define DFP_HELPER_RRND(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, \
- uint64_t *b, uint32_t rmc) \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a, \
+ ppc_fprp_t *b, uint32_t rmc) \
{ \
struct PPC_DFP dfp; \
- int32_t ref_sig = *a & 0x3F; \
+ ppc_vsr_t va; \
+ int32_t ref_sig; \
int32_t xmax = ((size) == 64) ? 369 : 6111; \
\
dfp_prepare_decimal##size(&dfp, 0, b, env); \
\
+ get_dfp64(&va, a); \
+ ref_sig = va.VsrD(1) & 0x3f; \
+ \
_dfp_reround(rmc, ref_sig, xmax, &dfp); \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
- &dfp.context); \
+ dfp_finalize_decimal##size(&dfp); \
QUA_PPs(&dfp); \
\
- if (size == 64) { \
- t[0] = dfp.t64[0]; \
- } else if (size == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
+ set_dfp##size(t, &dfp.vt); \
}
DFP_HELPER_RRND(drrnd, 64)
DFP_HELPER_RRND(drrndq, 128)
#define DFP_HELPER_RINT(op, postprocs, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b, \
uint32_t r, uint32_t rmc) \
{ \
struct PPC_DFP dfp; \
@@ -848,15 +855,10 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, \
\
dfp_set_round_mode_from_immediate(r, rmc, &dfp); \
decNumberToIntegralExact(&dfp.t, &dfp.b, &dfp.context); \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
+ dfp_finalize_decimal##size(&dfp); \
postprocs(&dfp); \
\
- if (size == 64) { \
- t[0] = dfp.t64[0]; \
- } else if (size == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
+ set_dfp##size(t, &dfp.vt); \
}
static void RINTX_PPs(struct PPC_DFP *dfp)
@@ -878,34 +880,42 @@ static void RINTN_PPs(struct PPC_DFP *dfp)
DFP_HELPER_RINT(drintn, RINTN_PPs, 64)
DFP_HELPER_RINT(drintnq, RINTN_PPs, 128)
-void helper_dctdp(CPUPPCState *env, uint64_t *t, uint64_t *b)
+void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
{
struct PPC_DFP dfp;
- uint32_t b_short = *b;
+ ppc_vsr_t vb;
+ uint32_t b_short;
+
+ get_dfp64(&vb, b);
+ b_short = (uint32_t)vb.VsrD(1);
+
dfp_prepare_decimal64(&dfp, 0, 0, env);
decimal32ToNumber((decimal32 *)&b_short, &dfp.t);
- decimal64FromNumber((decimal64 *)t, &dfp.t, &dfp.context);
+ dfp_finalize_decimal64(&dfp);
+ set_dfp64(t, &dfp.vt);
dfp_set_FPRF_from_FRT(&dfp);
}
-void helper_dctqpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
+void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
{
struct PPC_DFP dfp;
+ ppc_vsr_t vb;
dfp_prepare_decimal128(&dfp, 0, 0, env);
- decimal64ToNumber((decimal64 *)b, &dfp.t);
+ get_dfp64(&vb, b);
+ decimal64ToNumber((decimal64 *)&vb.VsrD(1), &dfp.t);
dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp);
dfp_set_FPRF_from_FRT(&dfp);
- decimal128FromNumber((decimal128 *)&dfp.t64, &dfp.t, &dfp.context);
- t[0] = dfp.t64[HI_IDX];
- t[1] = dfp.t64[LO_IDX];
+ dfp_finalize_decimal128(&dfp);
+ set_dfp128(t, &dfp.vt);
}
-void helper_drsp(CPUPPCState *env, uint64_t *t, uint64_t *b)
+void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
{
struct PPC_DFP dfp;
uint32_t t_short = 0;
+ ppc_vsr_t vt;
dfp_prepare_decimal64(&dfp, 0, b, env);
decimal32FromNumber((decimal32 *)&t_short, &dfp.b, &dfp.context);
decimal32ToNumber((decimal32 *)&t_short, &dfp.t);
@@ -915,15 +925,16 @@ void helper_drsp(CPUPPCState *env, uint64_t *t, uint64_t *b)
dfp_check_for_UX(&dfp);
dfp_check_for_XX(&dfp);
- *t = t_short;
+ vt.VsrD(1) = (uint64_t)t_short;
+ set_dfp64(t, &vt);
}
-void helper_drdpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
+void helper_drdpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b)
{
struct PPC_DFP dfp;
dfp_prepare_decimal128(&dfp, 0, b, env);
- decimal64FromNumber((decimal64 *)&dfp.t64, &dfp.b, &dfp.context);
- decimal64ToNumber((decimal64 *)&dfp.t64, &dfp.t);
+ decimal64FromNumber((decimal64 *)&dfp.vt.VsrD(1), &dfp.b, &dfp.context);
+ decimal64ToNumber((decimal64 *)&dfp.vt.VsrD(1), &dfp.t);
dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp);
dfp_set_FPRF_from_FRT_long(&dfp);
@@ -931,26 +942,23 @@ void helper_drdpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
dfp_check_for_UX(&dfp);
dfp_check_for_XX(&dfp);
- decimal64FromNumber((decimal64 *)dfp.t64, &dfp.t, &dfp.context);
- t[0] = dfp.t64[0];
- t[1] = 0;
+ dfp.vt.VsrD(0) = dfp.vt.VsrD(1) = 0;
+ dfp_finalize_decimal64(&dfp);
+ set_dfp128(t, &dfp.vt);
}
#define DFP_HELPER_CFFIX(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \
{ \
struct PPC_DFP dfp; \
+ ppc_vsr_t vb; \
dfp_prepare_decimal##size(&dfp, 0, b, env); \
- decNumberFromInt64(&dfp.t, (int64_t)(*b)); \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
+ get_dfp64(&vb, b); \
+ decNumberFromInt64(&dfp.t, (int64_t)vb.VsrD(1)); \
+ dfp_finalize_decimal##size(&dfp); \
CFFIX_PPs(&dfp); \
\
- if (size == 64) { \
- t[0] = dfp.t64[0]; \
- } else if (size == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
+ set_dfp##size(t, &dfp.vt); \
}
static void CFFIX_PPs(struct PPC_DFP *dfp)
@@ -963,7 +971,7 @@ DFP_HELPER_CFFIX(dcffix, 64)
DFP_HELPER_CFFIX(dcffixq, 128)
#define DFP_HELPER_CTFIX(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \
{ \
struct PPC_DFP dfp; \
dfp_prepare_decimal##size(&dfp, 0, b, env); \
@@ -971,62 +979,65 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \
if (unlikely(decNumberIsSpecial(&dfp.b))) { \
uint64_t invalid_flags = FP_VX | FP_VXCVI; \
if (decNumberIsInfinite(&dfp.b)) { \
- dfp.t64[0] = decNumberIsNegative(&dfp.b) ? INT64_MIN : INT64_MAX; \
+ dfp.vt.VsrD(1) = decNumberIsNegative(&dfp.b) ? INT64_MIN : \
+ INT64_MAX; \
} else { /* NaN */ \
- dfp.t64[0] = INT64_MIN; \
+ dfp.vt.VsrD(1) = INT64_MIN; \
if (decNumberIsSNaN(&dfp.b)) { \
invalid_flags |= FP_VXSNAN; \
} \
} \
dfp_set_FPSCR_flag(&dfp, invalid_flags, FP_VE); \
} else if (unlikely(decNumberIsZero(&dfp.b))) { \
- dfp.t64[0] = 0; \
+ dfp.vt.VsrD(1) = 0; \
} else { \
decNumberToIntegralExact(&dfp.b, &dfp.b, &dfp.context); \
- dfp.t64[0] = decNumberIntegralToInt64(&dfp.b, &dfp.context); \
+ dfp.vt.VsrD(1) = decNumberIntegralToInt64(&dfp.b, &dfp.context); \
if (decContextTestStatus(&dfp.context, DEC_Invalid_operation)) { \
- dfp.t64[0] = decNumberIsNegative(&dfp.b) ? INT64_MIN : INT64_MAX; \
+ dfp.vt.VsrD(1) = decNumberIsNegative(&dfp.b) ? INT64_MIN : \
+ INT64_MAX; \
dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FP_VE); \
} else { \
dfp_check_for_XX(&dfp); \
} \
} \
\
- *t = dfp.t64[0]; \
+ set_dfp64(t, &dfp.vt); \
}
DFP_HELPER_CTFIX(dctfix, 64)
DFP_HELPER_CTFIX(dctfixq, 128)
-static inline void dfp_set_bcd_digit_64(uint64_t *t, uint8_t digit,
- unsigned n)
+static inline void dfp_set_bcd_digit_64(ppc_vsr_t *t, uint8_t digit,
+ unsigned n)
{
- *t |= ((uint64_t)(digit & 0xF) << (n << 2));
+ t->VsrD(1) |= ((uint64_t)(digit & 0xF) << (n << 2));
}
-static inline void dfp_set_bcd_digit_128(uint64_t *t, uint8_t digit,
- unsigned n)
+static inline void dfp_set_bcd_digit_128(ppc_vsr_t *t, uint8_t digit,
+ unsigned n)
{
- t[(n & 0x10) ? HI_IDX : LO_IDX] |=
+ t->VsrD((n & 0x10) ? 0 : 1) |=
((uint64_t)(digit & 0xF) << ((n & 15) << 2));
}
-static inline void dfp_set_sign_64(uint64_t *t, uint8_t sgn)
+static inline void dfp_set_sign_64(ppc_vsr_t *t, uint8_t sgn)
{
- *t <<= 4;
- *t |= (sgn & 0xF);
+ t->VsrD(1) <<= 4;
+ t->VsrD(1) |= (sgn & 0xF);
}
-static inline void dfp_set_sign_128(uint64_t *t, uint8_t sgn)
+static inline void dfp_set_sign_128(ppc_vsr_t *t, uint8_t sgn)
{
- t[HI_IDX] <<= 4;
- t[HI_IDX] |= (t[LO_IDX] >> 60);
- t[LO_IDX] <<= 4;
- t[LO_IDX] |= (sgn & 0xF);
+ t->VsrD(0) <<= 4;
+ t->VsrD(0) |= (t->VsrD(1) >> 60);
+ t->VsrD(1) <<= 4;
+ t->VsrD(1) |= (sgn & 0xF);
}
#define DFP_HELPER_DEDPD(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t sp) \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b, \
+ uint32_t sp) \
{ \
struct PPC_DFP dfp; \
uint8_t digits[34]; \
@@ -1035,11 +1046,11 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t sp) \
dfp_prepare_decimal##size(&dfp, 0, b, env); \
\
decNumberGetBCD(&dfp.b, digits); \
- dfp.t64[0] = dfp.t64[1] = 0; \
+ dfp.vt.VsrD(0) = dfp.vt.VsrD(1) = 0; \
N = dfp.b.digits; \
\
for (i = 0; (i < N) && (i < (size)/4); i++) { \
- dfp_set_bcd_digit_##size(dfp.t64, digits[N-i-1], i); \
+ dfp_set_bcd_digit_##size(&dfp.vt, digits[N - i - 1], i); \
} \
\
if (sp & 2) { \
@@ -1050,32 +1061,28 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t sp) \
} else { \
sgn = ((sp & 1) ? 0xF : 0xC); \
} \
- dfp_set_sign_##size(dfp.t64, sgn); \
+ dfp_set_sign_##size(&dfp.vt, sgn); \
} \
\
- if (size == 64) { \
- t[0] = dfp.t64[0]; \
- } else if (size == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
+ set_dfp##size(t, &dfp.vt); \
}
DFP_HELPER_DEDPD(ddedpd, 64)
DFP_HELPER_DEDPD(ddedpdq, 128)
-static inline uint8_t dfp_get_bcd_digit_64(uint64_t *t, unsigned n)
+static inline uint8_t dfp_get_bcd_digit_64(ppc_vsr_t *t, unsigned n)
{
- return *t >> ((n << 2) & 63) & 15;
+ return t->VsrD(1) >> ((n << 2) & 63) & 15;
}
-static inline uint8_t dfp_get_bcd_digit_128(uint64_t *t, unsigned n)
+static inline uint8_t dfp_get_bcd_digit_128(ppc_vsr_t *t, unsigned n)
{
- return t[(n & 0x10) ? HI_IDX : LO_IDX] >> ((n << 2) & 63) & 15;
+ return t->VsrD((n & 0x10) ? 0 : 1) >> ((n << 2) & 63) & 15;
}
#define DFP_HELPER_ENBCD(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t s) \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b, \
+ uint32_t s) \
{ \
struct PPC_DFP dfp; \
uint8_t digits[32]; \
@@ -1086,7 +1093,7 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t s) \
decNumberZero(&dfp.t); \
\
if (s) { \
- uint8_t sgnNibble = dfp_get_bcd_digit_##size(dfp.b64, offset++); \
+ uint8_t sgnNibble = dfp_get_bcd_digit_##size(&dfp.vb, offset++); \
switch (sgnNibble) { \
case 0xD: \
case 0xB: \
@@ -1106,7 +1113,8 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t s) \
\
while (offset < (size) / 4) { \
n++; \
- digits[(size) / 4 - n] = dfp_get_bcd_digit_##size(dfp.b64, offset++); \
+ digits[(size) / 4 - n] = dfp_get_bcd_digit_##size(&dfp.vb, \
+ offset++); \
if (digits[(size) / 4 - n] > 10) { \
dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE); \
return; \
@@ -1122,71 +1130,72 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t s) \
if (s && sgn) { \
dfp.t.bits |= DECNEG; \
} \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
- &dfp.context); \
+ dfp_finalize_decimal##size(&dfp); \
dfp_set_FPRF_from_FRT(&dfp); \
- if ((size) == 64) { \
- t[0] = dfp.t64[0]; \
- } else if ((size) == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
+ set_dfp##size(t, &dfp.vt); \
}
DFP_HELPER_ENBCD(denbcd, 64)
DFP_HELPER_ENBCD(denbcdq, 128)
#define DFP_HELPER_XEX(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \
{ \
struct PPC_DFP dfp; \
+ ppc_vsr_t vt; \
\
dfp_prepare_decimal##size(&dfp, 0, b, env); \
\
if (unlikely(decNumberIsSpecial(&dfp.b))) { \
if (decNumberIsInfinite(&dfp.b)) { \
- *t = -1; \
+ vt.VsrD(1) = -1; \
} else if (decNumberIsSNaN(&dfp.b)) { \
- *t = -3; \
+ vt.VsrD(1) = -3; \
} else if (decNumberIsQNaN(&dfp.b)) { \
- *t = -2; \
+ vt.VsrD(1) = -2; \
} else { \
assert(0); \
} \
+ set_dfp64(t, &vt); \
} else { \
if ((size) == 64) { \
- *t = dfp.b.exponent + 398; \
+ vt.VsrD(1) = dfp.b.exponent + 398; \
} else if ((size) == 128) { \
- *t = dfp.b.exponent + 6176; \
+ vt.VsrD(1) = dfp.b.exponent + 6176; \
} else { \
assert(0); \
} \
+ set_dfp64(t, &vt); \
} \
}
DFP_HELPER_XEX(dxex, 64)
DFP_HELPER_XEX(dxexq, 128)
-static void dfp_set_raw_exp_64(uint64_t *t, uint64_t raw)
+static void dfp_set_raw_exp_64(ppc_vsr_t *t, uint64_t raw)
{
- *t &= 0x8003ffffffffffffULL;
- *t |= (raw << (63 - 13));
+ t->VsrD(1) &= 0x8003ffffffffffffULL;
+ t->VsrD(1) |= (raw << (63 - 13));
}
-static void dfp_set_raw_exp_128(uint64_t *t, uint64_t raw)
+static void dfp_set_raw_exp_128(ppc_vsr_t *t, uint64_t raw)
{
- t[HI_IDX] &= 0x80003fffffffffffULL;
- t[HI_IDX] |= (raw << (63 - 17));
+ t->VsrD(0) &= 0x80003fffffffffffULL;
+ t->VsrD(0) |= (raw << (63 - 17));
}
#define DFP_HELPER_IEX(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a, \
+ ppc_fprp_t *b) \
{ \
struct PPC_DFP dfp; \
uint64_t raw_qnan, raw_snan, raw_inf, max_exp; \
+ ppc_vsr_t va; \
int bias; \
- int64_t exp = *((int64_t *)a); \
+ int64_t exp; \
\
+ get_dfp64(&va, a); \
+ exp = (int64_t)va.VsrD(1); \
dfp_prepare_decimal##size(&dfp, 0, b, env); \
\
if ((size) == 64) { \
@@ -1206,14 +1215,14 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \
} \
\
if (unlikely((exp < 0) || (exp > max_exp))) { \
- dfp.t64[0] = dfp.b64[0]; \
- dfp.t64[1] = dfp.b64[1]; \
+ dfp.vt.VsrD(0) = dfp.vb.VsrD(0); \
+ dfp.vt.VsrD(1) = dfp.vb.VsrD(1); \
if (exp == -1) { \
- dfp_set_raw_exp_##size(dfp.t64, raw_inf); \
+ dfp_set_raw_exp_##size(&dfp.vt, raw_inf); \
} else if (exp == -3) { \
- dfp_set_raw_exp_##size(dfp.t64, raw_snan); \
+ dfp_set_raw_exp_##size(&dfp.vt, raw_snan); \
} else { \
- dfp_set_raw_exp_##size(dfp.t64, raw_qnan); \
+ dfp_set_raw_exp_##size(&dfp.vt, raw_qnan); \
} \
} else { \
dfp.t = dfp.b; \
@@ -1221,15 +1230,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \
dfp.t.bits &= ~DECSPECIAL; \
} \
dfp.t.exponent = exp - bias; \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
- &dfp.context); \
- } \
- if (size == 64) { \
- t[0] = dfp.t64[0]; \
- } else if (size == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
+ dfp_finalize_decimal##size(&dfp); \
} \
+ set_dfp##size(t, &dfp.vt); \
}
DFP_HELPER_IEX(diex, 64)
@@ -1276,7 +1279,7 @@ static void dfp_clear_lmd_from_g5msb(uint64_t *t)
}
#define DFP_HELPER_SHIFT(op, size, shift_left) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, \
+void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a, \
uint32_t sh) \
{ \
struct PPC_DFP dfp; \
@@ -1303,26 +1306,21 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, \
dfp.t.digits = max_digits - 1; \
} \
\
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
- &dfp.context); \
+ dfp_finalize_decimal##size(&dfp); \
} else { \
if ((size) == 64) { \
- dfp.t64[0] = dfp.a64[0] & 0xFFFC000000000000ULL; \
- dfp_clear_lmd_from_g5msb(dfp.t64); \
+ dfp.vt.VsrD(1) = dfp.va.VsrD(1) & \
+ 0xFFFC000000000000ULL; \
+ dfp_clear_lmd_from_g5msb(&dfp.vt.VsrD(1)); \
} else { \
- dfp.t64[HI_IDX] = dfp.a64[HI_IDX] & \
- 0xFFFFC00000000000ULL; \
- dfp_clear_lmd_from_g5msb(dfp.t64 + HI_IDX); \
- dfp.t64[LO_IDX] = 0; \
+ dfp.vt.VsrD(0) = dfp.va.VsrD(0) & \
+ 0xFFFFC00000000000ULL; \
+ dfp_clear_lmd_from_g5msb(&dfp.vt.VsrD(0)); \
+ dfp.vt.VsrD(1) = 0; \
} \
} \
\
- if ((size) == 64) { \
- t[0] = dfp.t64[0]; \
- } else { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
+ set_dfp##size(t, &dfp.vt); \
}
DFP_HELPER_SHIFT(dscli, 64, 1)
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 4b1a2e6178..dc383242f7 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -180,7 +180,7 @@ static void set_fprf_from_class(CPUPPCState *env, int class)
};
bool isneg = class & is_neg;
- env->fpscr &= ~(0x1F << FPSCR_FPRF);
+ env->fpscr &= ~FP_FPRF;
env->fpscr |= fprf[ctz32(class)][isneg] << FPSCR_FPRF;
}
@@ -199,12 +199,12 @@ COMPUTE_FPRF(float128)
static void finish_invalid_op_excp(CPUPPCState *env, int op, uintptr_t retaddr)
{
/* Update the floating-point invalid operation summary */
- env->fpscr |= 1 << FPSCR_VX;
+ env->fpscr |= FP_VX;
/* Update the floating-point exception summary */
env->fpscr |= FP_FX;
if (fpscr_ve != 0) {
/* Update the floating-point enabled exception summary */
- env->fpscr |= 1 << FPSCR_FEX;
+ env->fpscr |= FP_FEX;
if (fp_exceptions_enabled(env)) {
raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
POWERPC_EXCP_FP | op, retaddr);
@@ -215,11 +215,11 @@ static void finish_invalid_op_excp(CPUPPCState *env, int op, uintptr_t retaddr)
static void finish_invalid_op_arith(CPUPPCState *env, int op,
bool set_fpcc, uintptr_t retaddr)
{
- env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
+ env->fpscr &= ~(FP_FR | FP_FI);
if (fpscr_ve == 0) {
if (set_fpcc) {
- env->fpscr &= ~(0xF << FPSCR_FPCC);
- env->fpscr |= 0x11 << FPSCR_FPCC;
+ env->fpscr &= ~FP_FPCC;
+ env->fpscr |= (FP_C | FP_FU);
}
}
finish_invalid_op_excp(env, op, retaddr);
@@ -228,7 +228,7 @@ static void finish_invalid_op_arith(CPUPPCState *env, int op,
/* Signalling NaN */
static void float_invalid_op_vxsnan(CPUPPCState *env, uintptr_t retaddr)
{
- env->fpscr |= 1 << FPSCR_VXSNAN;
+ env->fpscr |= FP_VXSNAN;
finish_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, retaddr);
}
@@ -236,7 +236,7 @@ static void float_invalid_op_vxsnan(CPUPPCState *env, uintptr_t retaddr)
static void float_invalid_op_vxisi(CPUPPCState *env, bool set_fpcc,
uintptr_t retaddr)
{
- env->fpscr |= 1 << FPSCR_VXISI;
+ env->fpscr |= FP_VXISI;
finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXISI, set_fpcc, retaddr);
}
@@ -244,7 +244,7 @@ static void float_invalid_op_vxisi(CPUPPCState *env, bool set_fpcc,
static void float_invalid_op_vxidi(CPUPPCState *env, bool set_fpcc,
uintptr_t retaddr)
{
- env->fpscr |= 1 << FPSCR_VXIDI;
+ env->fpscr |= FP_VXIDI;
finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXIDI, set_fpcc, retaddr);
}
@@ -252,7 +252,7 @@ static void float_invalid_op_vxidi(CPUPPCState *env, bool set_fpcc,
static void float_invalid_op_vxzdz(CPUPPCState *env, bool set_fpcc,
uintptr_t retaddr)
{
- env->fpscr |= 1 << FPSCR_VXZDZ;
+ env->fpscr |= FP_VXZDZ;
finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXZDZ, set_fpcc, retaddr);
}
@@ -260,7 +260,7 @@ static void float_invalid_op_vxzdz(CPUPPCState *env, bool set_fpcc,
static void float_invalid_op_vximz(CPUPPCState *env, bool set_fpcc,
uintptr_t retaddr)
{
- env->fpscr |= 1 << FPSCR_VXIMZ;
+ env->fpscr |= FP_VXIMZ;
finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXIMZ, set_fpcc, retaddr);
}
@@ -268,7 +268,7 @@ static void float_invalid_op_vximz(CPUPPCState *env, bool set_fpcc,
static void float_invalid_op_vxsqrt(CPUPPCState *env, bool set_fpcc,
uintptr_t retaddr)
{
- env->fpscr |= 1 << FPSCR_VXSQRT;
+ env->fpscr |= FP_VXSQRT;
finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXSQRT, set_fpcc, retaddr);
}
@@ -276,13 +276,13 @@ static void float_invalid_op_vxsqrt(CPUPPCState *env, bool set_fpcc,
static void float_invalid_op_vxvc(CPUPPCState *env, bool set_fpcc,
uintptr_t retaddr)
{
- env->fpscr |= 1 << FPSCR_VXVC;
+ env->fpscr |= FP_VXVC;
if (set_fpcc) {
- env->fpscr &= ~(0xF << FPSCR_FPCC);
- env->fpscr |= 0x11 << FPSCR_FPCC;
+ env->fpscr &= ~FP_FPCC;
+ env->fpscr |= (FP_C | FP_FU);
}
/* Update the floating-point invalid operation summary */
- env->fpscr |= 1 << FPSCR_VX;
+ env->fpscr |= FP_VX;
/* Update the floating-point exception summary */
env->fpscr |= FP_FX;
/* We must update the target FPR before raising the exception */
@@ -292,7 +292,7 @@ static void float_invalid_op_vxvc(CPUPPCState *env, bool set_fpcc,
cs->exception_index = POWERPC_EXCP_PROGRAM;
env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_VXVC;
/* Update the floating-point enabled exception summary */
- env->fpscr |= 1 << FPSCR_FEX;
+ env->fpscr |= FP_FEX;
/* Exception is differed */
}
}
@@ -301,12 +301,12 @@ static void float_invalid_op_vxvc(CPUPPCState *env, bool set_fpcc,
static void float_invalid_op_vxcvi(CPUPPCState *env, bool set_fpcc,
uintptr_t retaddr)
{
- env->fpscr |= 1 << FPSCR_VXCVI;
- env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
+ env->fpscr |= FP_VXCVI;
+ env->fpscr &= ~(FP_FR | FP_FI);
if (fpscr_ve == 0) {
if (set_fpcc) {
- env->fpscr &= ~(0xF << FPSCR_FPCC);
- env->fpscr |= 0x11 << FPSCR_FPCC;
+ env->fpscr &= ~FP_FPCC;
+ env->fpscr |= (FP_C | FP_FU);
}
}
finish_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, retaddr);
@@ -314,13 +314,13 @@ static void float_invalid_op_vxcvi(CPUPPCState *env, bool set_fpcc,
static inline void float_zero_divide_excp(CPUPPCState *env, uintptr_t raddr)
{
- env->fpscr |= 1 << FPSCR_ZX;
- env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
+ env->fpscr |= FP_ZX;
+ env->fpscr &= ~(FP_FR | FP_FI);
/* Update the floating-point exception summary */
env->fpscr |= FP_FX;
if (fpscr_ze != 0) {
/* Update the floating-point enabled exception summary */
- env->fpscr |= 1 << FPSCR_FEX;
+ env->fpscr |= FP_FEX;
if (fp_exceptions_enabled(env)) {
raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
POWERPC_EXCP_FP | POWERPC_EXCP_FP_ZX,
@@ -333,19 +333,19 @@ static inline void float_overflow_excp(CPUPPCState *env)
{
CPUState *cs = env_cpu(env);
- env->fpscr |= 1 << FPSCR_OX;
+ env->fpscr |= FP_OX;
/* Update the floating-point exception summary */
env->fpscr |= FP_FX;
if (fpscr_oe != 0) {
/* XXX: should adjust the result */
/* Update the floating-point enabled exception summary */
- env->fpscr |= 1 << FPSCR_FEX;
+ env->fpscr |= FP_FEX;
/* We must update the target FPR before raising the exception */
cs->exception_index = POWERPC_EXCP_PROGRAM;
env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_OX;
} else {
- env->fpscr |= 1 << FPSCR_XX;
- env->fpscr |= 1 << FPSCR_FI;
+ env->fpscr |= FP_XX;
+ env->fpscr |= FP_FI;
}
}
@@ -353,13 +353,13 @@ static inline void float_underflow_excp(CPUPPCState *env)
{
CPUState *cs = env_cpu(env);
- env->fpscr |= 1 << FPSCR_UX;
+ env->fpscr |= FP_UX;
/* Update the floating-point exception summary */
env->fpscr |= FP_FX;
if (fpscr_ue != 0) {
/* XXX: should adjust the result */
/* Update the floating-point enabled exception summary */
- env->fpscr |= 1 << FPSCR_FEX;
+ env->fpscr |= FP_FEX;
/* We must update the target FPR before raising the exception */
cs->exception_index = POWERPC_EXCP_PROGRAM;
env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_UX;
@@ -370,13 +370,13 @@ static inline void float_inexact_excp(CPUPPCState *env)
{
CPUState *cs = env_cpu(env);
- env->fpscr |= 1 << FPSCR_FI;
- env->fpscr |= 1 << FPSCR_XX;
+ env->fpscr |= FP_FI;
+ env->fpscr |= FP_XX;
/* Update the floating-point exception summary */
env->fpscr |= FP_FX;
if (fpscr_xe != 0) {
/* Update the floating-point enabled exception summary */
- env->fpscr |= 1 << FPSCR_FEX;
+ env->fpscr |= FP_FEX;
/* We must update the target FPR before raising the exception */
cs->exception_index = POWERPC_EXCP_PROGRAM;
env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_XX;
@@ -433,7 +433,7 @@ void helper_fpscr_clrbit(CPUPPCState *env, uint32_t bit)
case FPSCR_VXCVI:
if (!fpscr_ix) {
/* Set VX bit to zero */
- env->fpscr &= ~(1 << FPSCR_VX);
+ env->fpscr &= ~FP_VX;
}
break;
case FPSCR_OX:
@@ -447,7 +447,7 @@ void helper_fpscr_clrbit(CPUPPCState *env, uint32_t bit)
case FPSCR_XE:
if (!fpscr_eex) {
/* Set the FEX bit */
- env->fpscr &= ~(1 << FPSCR_FEX);
+ env->fpscr &= ~FP_FEX;
}
break;
default:
@@ -504,7 +504,7 @@ void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit)
case FPSCR_VXSOFT:
case FPSCR_VXSQRT:
case FPSCR_VXCVI:
- env->fpscr |= 1 << FPSCR_VX;
+ env->fpscr |= FP_VX;
env->fpscr |= FP_FX;
if (fpscr_ve != 0) {
goto raise_ve;
@@ -580,7 +580,7 @@ void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit)
break;
raise_excp:
/* Update the floating-point enabled exception summary */
- env->fpscr |= 1 << FPSCR_FEX;
+ env->fpscr |= FP_FEX;
/* We have to update Rc1 before raising the exception */
cs->exception_index = POWERPC_EXCP_PROGRAM;
break;
@@ -596,8 +596,8 @@ void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
prev = env->fpscr;
new = (target_ulong)arg;
- new &= ~0x60000000LL;
- new |= prev & 0x60000000LL;
+ new &= ~(FP_FEX | FP_VX);
+ new |= prev & (FP_FEX | FP_VX);
for (i = 0; i < sizeof(target_ulong) * 2; i++) {
if (mask & (1 << i)) {
env->fpscr &= ~(0xFLL << (4 * i));
@@ -606,17 +606,17 @@ void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
}
/* Update VX and FEX */
if (fpscr_ix != 0) {
- env->fpscr |= 1 << FPSCR_VX;
+ env->fpscr |= FP_VX;
} else {
- env->fpscr &= ~(1 << FPSCR_VX);
+ env->fpscr &= ~FP_VX;
}
if ((fpscr_ex & fpscr_eex) != 0) {
- env->fpscr |= 1 << FPSCR_FEX;
+ env->fpscr |= FP_FEX;
cs->exception_index = POWERPC_EXCP_PROGRAM;
/* XXX: we should compute it properly */
env->error_code = POWERPC_EXCP_FP;
} else {
- env->fpscr &= ~(1 << FPSCR_FEX);
+ env->fpscr &= ~FP_FEX;
}
fpscr_set_rounding_mode(env);
}
@@ -639,7 +639,7 @@ static void do_float_check_status(CPUPPCState *env, uintptr_t raddr)
if (status & float_flag_inexact) {
float_inexact_excp(env);
} else {
- env->fpscr &= ~(1 << FPSCR_FI); /* clear the FPSCR[FI] bit */
+ env->fpscr &= ~FP_FI; /* clear the FPSCR[FI] bit */
}
if (cs->exception_index == POWERPC_EXCP_PROGRAM &&
@@ -1138,8 +1138,8 @@ void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
ret = 0x02UL;
}
- env->fpscr &= ~(0x0F << FPSCR_FPRF);
- env->fpscr |= ret << FPSCR_FPRF;
+ env->fpscr &= ~FP_FPCC;
+ env->fpscr |= ret << FPSCR_FPCC;
env->crf[crfD] = ret;
if (unlikely(ret == 0x01UL
&& (float64_is_signaling_nan(farg1.d, &env->fp_status) ||
@@ -1169,9 +1169,9 @@ void helper_fcmpo(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
ret = 0x02UL;
}
- env->fpscr &= ~(0x0F << FPSCR_FPRF);
- env->fpscr |= ret << FPSCR_FPRF;
- env->crf[crfD] = ret;
+ env->fpscr &= ~FP_FPCC;
+ env->fpscr |= ret << FPSCR_FPCC;
+ env->crf[crfD] = (uint32_t) ret;
if (unlikely(ret == 0x01UL)) {
float_invalid_op_vxvc(env, 1, GETPC());
if (float64_is_signaling_nan(farg1.d, &env->fp_status) ||
@@ -2431,8 +2431,8 @@ void helper_xscmpexpdp(CPUPPCState *env, uint32_t opcode,
}
}
- env->fpscr &= ~(0x0F << FPSCR_FPRF);
- env->fpscr |= cc << FPSCR_FPRF;
+ env->fpscr &= ~FP_FPCC;
+ env->fpscr |= cc << FPSCR_FPCC;
env->crf[BF(opcode)] = cc;
do_float_check_status(env, GETPC());
@@ -2460,8 +2460,8 @@ void helper_xscmpexpqp(CPUPPCState *env, uint32_t opcode,
}
}
- env->fpscr &= ~(0x0F << FPSCR_FPRF);
- env->fpscr |= cc << FPSCR_FPRF;
+ env->fpscr &= ~FP_FPCC;
+ env->fpscr |= cc << FPSCR_FPCC;
env->crf[BF(opcode)] = cc;
do_float_check_status(env, GETPC());
@@ -2505,8 +2505,8 @@ void helper_##op(CPUPPCState *env, uint32_t opcode, \
cc |= CRF_EQ; \
} \
\
- env->fpscr &= ~(0x0F << FPSCR_FPRF); \
- env->fpscr |= cc << FPSCR_FPRF; \
+ env->fpscr &= ~FP_FPCC; \
+ env->fpscr |= cc << FPSCR_FPCC; \
env->crf[BF(opcode)] = cc; \
\
do_float_check_status(env, GETPC()); \
@@ -2553,8 +2553,8 @@ void helper_##op(CPUPPCState *env, uint32_t opcode, \
cc |= CRF_EQ; \
} \
\
- env->fpscr &= ~(0x0F << FPSCR_FPRF); \
- env->fpscr |= cc << FPSCR_FPRF; \
+ env->fpscr &= ~FP_FPCC; \
+ env->fpscr |= cc << FPSCR_FPCC; \
env->crf[BF(opcode)] = cc; \
\
do_float_check_status(env, GETPC()); \
@@ -3242,8 +3242,8 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
\
if (scrf) { \
cc = sign << CRF_LT_BIT | match << CRF_EQ_BIT; \
- env->fpscr &= ~(0x0F << FPSCR_FPRF); \
- env->fpscr |= cc << FPSCR_FPRF; \
+ env->fpscr &= ~FP_FPCC; \
+ env->fpscr |= cc << FPSCR_FPCC; \
env->crf[BF(opcode)] = cc; \
} else { \
t.tfld = match ? fld_max : 0; \
@@ -3286,8 +3286,8 @@ void helper_xststdcsp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xb)
&env->fp_status), &env->fp_status);
cc = sign << CRF_LT_BIT | match << CRF_EQ_BIT | not_sp << CRF_SO_BIT;
- env->fpscr &= ~(0x0F << FPSCR_FPRF);
- env->fpscr |= cc << FPSCR_FPRF;
+ env->fpscr &= ~FP_FPCC;
+ env->fpscr |= cc << FPSCR_FPCC;
env->crf[BF(opcode)] = cc;
}
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 54ea9b9500..f843814b8a 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -686,7 +686,7 @@ DEF_HELPER_3(store_601_batu, void, env, i32, tl)
#endif
#define dh_alias_fprp ptr
-#define dh_ctype_fprp uint64_t *
+#define dh_ctype_fprp ppc_fprp_t *
#define dh_is_signed_fprp dh_is_signed_ptr
DEF_HELPER_4(dadd, void, env, fprp, fprp, fprp)
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index 46deb57a34..6d238b989d 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -2052,15 +2052,11 @@ void helper_vsubecuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
#define NATIONAL_PLUS 0x2B
#define NATIONAL_NEG 0x2D
-#if defined(HOST_WORDS_BIGENDIAN)
#define BCD_DIG_BYTE(n) (15 - ((n) / 2))
-#else
-#define BCD_DIG_BYTE(n) ((n) / 2)
-#endif
static int bcd_get_sgn(ppc_avr_t *bcd)
{
- switch (bcd->u8[BCD_DIG_BYTE(0)] & 0xF) {
+ switch (bcd->VsrB(BCD_DIG_BYTE(0)) & 0xF) {
case BCD_PLUS_PREF_1:
case BCD_PLUS_PREF_2:
case BCD_PLUS_ALT_1:
@@ -2095,9 +2091,9 @@ static uint8_t bcd_get_digit(ppc_avr_t *bcd, int n, int *invalid)
{
uint8_t result;
if (n & 1) {
- result = bcd->u8[BCD_DIG_BYTE(n)] >> 4;
+ result = bcd->VsrB(BCD_DIG_BYTE(n)) >> 4;
} else {
- result = bcd->u8[BCD_DIG_BYTE(n)] & 0xF;
+ result = bcd->VsrB(BCD_DIG_BYTE(n)) & 0xF;
}
if (unlikely(result > 9)) {
@@ -2109,11 +2105,11 @@ static uint8_t bcd_get_digit(ppc_avr_t *bcd, int n, int *invalid)
static void bcd_put_digit(ppc_avr_t *bcd, uint8_t digit, int n)
{
if (n & 1) {
- bcd->u8[BCD_DIG_BYTE(n)] &= 0x0F;
- bcd->u8[BCD_DIG_BYTE(n)] |= (digit << 4);
+ bcd->VsrB(BCD_DIG_BYTE(n)) &= 0x0F;
+ bcd->VsrB(BCD_DIG_BYTE(n)) |= (digit << 4);
} else {
- bcd->u8[BCD_DIG_BYTE(n)] &= 0xF0;
- bcd->u8[BCD_DIG_BYTE(n)] |= digit;
+ bcd->VsrB(BCD_DIG_BYTE(n)) &= 0xF0;
+ bcd->VsrB(BCD_DIG_BYTE(n)) |= digit;
}
}
@@ -2228,21 +2224,21 @@ uint32_t helper_bcdadd(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
if (!invalid) {
if (sgna == sgnb) {
- result.u8[BCD_DIG_BYTE(0)] = bcd_preferred_sgn(sgna, ps);
+ result.VsrB(BCD_DIG_BYTE(0)) = bcd_preferred_sgn(sgna, ps);
bcd_add_mag(&result, a, b, &invalid, &overflow);
cr = bcd_cmp_zero(&result);
} else {
int magnitude = bcd_cmp_mag(a, b);
if (magnitude > 0) {
- result.u8[BCD_DIG_BYTE(0)] = bcd_preferred_sgn(sgna, ps);
+ result.VsrB(BCD_DIG_BYTE(0)) = bcd_preferred_sgn(sgna, ps);
bcd_sub_mag(&result, a, b, &invalid, &overflow);
cr = (sgna > 0) ? CRF_GT : CRF_LT;
} else if (magnitude < 0) {
- result.u8[BCD_DIG_BYTE(0)] = bcd_preferred_sgn(sgnb, ps);
+ result.VsrB(BCD_DIG_BYTE(0)) = bcd_preferred_sgn(sgnb, ps);
bcd_sub_mag(&result, b, a, &invalid, &overflow);
cr = (sgnb > 0) ? CRF_GT : CRF_LT;
} else {
- result.u8[BCD_DIG_BYTE(0)] = bcd_preferred_sgn(0, ps);
+ result.VsrB(BCD_DIG_BYTE(0)) = bcd_preferred_sgn(0, ps);
cr = CRF_EQ;
}
}
@@ -2353,15 +2349,15 @@ uint32_t helper_bcdcfz(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps)
int zone_lead = ps ? 0xF : 0x3;
int digit = 0;
ppc_avr_t ret = { .u64 = { 0, 0 } };
- int sgnb = b->u8[BCD_DIG_BYTE(0)] >> 4;
+ int sgnb = b->VsrB(BCD_DIG_BYTE(0)) >> 4;
if (unlikely((sgnb < 0xA) && ps)) {
invalid = 1;
}
for (i = 0; i < 16; i++) {
- zone_digit = i ? b->u8[BCD_DIG_BYTE(i * 2)] >> 4 : zone_lead;
- digit = b->u8[BCD_DIG_BYTE(i * 2)] & 0xF;
+ zone_digit = i ? b->VsrB(BCD_DIG_BYTE(i * 2)) >> 4 : zone_lead;
+ digit = b->VsrB(BCD_DIG_BYTE(i * 2)) & 0xF;
if (unlikely(zone_digit != zone_lead || digit > 0x9)) {
invalid = 1;
break;
@@ -2407,7 +2403,7 @@ uint32_t helper_bcdctz(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps)
break;
}
- ret.u8[BCD_DIG_BYTE(i * 2)] = zone_lead + digit;
+ ret.VsrB(BCD_DIG_BYTE(i * 2)) = zone_lead + digit;
}
if (ps) {
@@ -2519,7 +2515,7 @@ uint32_t helper_bcdcpsgn(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
}
*r = *a;
- bcd_put_digit(r, b->u8[BCD_DIG_BYTE(0)] & 0xF, 0);
+ bcd_put_digit(r, b->VsrB(BCD_DIG_BYTE(0)) & 0xF, 0);
for (i = 1; i < 32; i++) {
bcd_get_digit(a, i, &invalid);
@@ -2549,11 +2545,7 @@ uint32_t helper_bcdsetsgn(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps)
uint32_t helper_bcds(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
{
int cr;
-#if defined(HOST_WORDS_BIGENDIAN)
- int i = a->s8[7];
-#else
- int i = a->s8[8];
-#endif
+ int i = a->VsrSB(7);
bool ox_flag = false;
int sgnb = bcd_get_sgn(b);
ppc_avr_t ret = *b;
@@ -2602,11 +2594,7 @@ uint32_t helper_bcdus(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
}
}
-#if defined(HOST_WORDS_BIGENDIAN)
- i = a->s8[7];
-#else
- i = a->s8[8];
-#endif
+ i = a->VsrSB(7);
if (i >= 32) {
ox_flag = true;
ret.VsrD(1) = ret.VsrD(0) = 0;
@@ -2637,13 +2625,11 @@ uint32_t helper_bcdsr(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
ppc_avr_t ret = *b;
ret.VsrD(1) &= ~0xf;
-#if defined(HOST_WORDS_BIGENDIAN)
- int i = a->s8[7];
- ppc_avr_t bcd_one = { .u64 = { 0, 0x10 } };
-#else
- int i = a->s8[8];
- ppc_avr_t bcd_one = { .u64 = { 0x10, 0 } };
-#endif
+ int i = a->VsrSB(7);
+ ppc_avr_t bcd_one;
+
+ bcd_one.VsrD(0) = 0;
+ bcd_one.VsrD(1) = 0x10;
if (bcd_is_valid(b) == false) {
return CRF_SO;
@@ -2679,11 +2665,7 @@ uint32_t helper_bcdtrunc(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
{
uint64_t mask;
uint32_t ox_flag = 0;
-#if defined(HOST_WORDS_BIGENDIAN)
- int i = a->s16[3] + 1;
-#else
- int i = a->s16[4] + 1;
-#endif
+ int i = a->VsrSH(3) + 1;
ppc_avr_t ret = *b;
if (bcd_is_valid(b) == false) {
@@ -2728,11 +2710,7 @@ uint32_t helper_bcdutrunc(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
}
}
-#if defined(HOST_WORDS_BIGENDIAN)
- i = a->s16[3];
-#else
- i = a->s16[4];
-#endif
+ i = a->VsrSH(3);
if (i > 16 && i < 33) {
mask = (uint64_t)-1 >> (128 - i * 4);
if (ret.VsrD(0) & ~mask) {
diff --git a/target/ppc/internal.h b/target/ppc/internal.h
index d3d327e548..15d655b356 100644
--- a/target/ppc/internal.h
+++ b/target/ppc/internal.h
@@ -157,6 +157,9 @@ EXTRACT_HELPER(FPL, 25, 1);
EXTRACT_HELPER(FPFLM, 17, 8);
EXTRACT_HELPER(FPW, 16, 1);
+/* mffscrni */
+EXTRACT_HELPER(RM, 11, 2);
+
/* addpcis */
EXTRACT_HELPER_SPLIT_3(DX, 10, 6, 6, 5, 16, 1, 1, 0, 0)
#if defined(TARGET_PPC64)
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 8c5b1f25cc..820724cc7d 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -993,6 +993,10 @@ int kvm_arch_put_registers(CPUState *cs, int level)
}
kvm_set_one_reg(cs, KVM_REG_PPC_TB_OFFSET, &env->tb_env->tb_offset);
+
+ if (level > KVM_PUT_RUNTIME_STATE) {
+ kvm_put_one_spr(cs, KVM_REG_PPC_DPDES, SPR_DPDES);
+ }
#endif /* TARGET_PPC64 */
}
@@ -1297,6 +1301,7 @@ int kvm_arch_get_registers(CPUState *cs)
}
kvm_get_one_reg(cs, KVM_REG_PPC_TB_OFFSET, &env->tb_env->tb_offset);
+ kvm_get_one_spr(cs, KVM_REG_PPC_DPDES, SPR_DPDES);
#endif
}
diff --git a/target/ppc/translate/fp-impl.inc.c b/target/ppc/translate/fp-impl.inc.c
index 7cd9d8db05..d8e27bf4d5 100644
--- a/target/ppc/translate/fp-impl.inc.c
+++ b/target/ppc/translate/fp-impl.inc.c
@@ -634,11 +634,108 @@ static void gen_mffsl(DisasContext *ctx)
gen_reset_fpstatus();
tcg_gen_extu_tl_i64(t0, cpu_fpscr);
/* Mask everything except mode, status, and enables. */
- tcg_gen_andi_i64(t0, t0, FP_MODE | FP_STATUS | FP_ENABLES);
+ tcg_gen_andi_i64(t0, t0, FP_DRN | FP_STATUS | FP_ENABLES | FP_RN);
set_fpr(rD(ctx->opcode), t0);
tcg_temp_free_i64(t0);
}
+/* mffsce */
+static void gen_mffsce(DisasContext *ctx)
+{
+ TCGv_i64 t0;
+ TCGv_i32 mask;
+
+ if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) {
+ return gen_mffs(ctx);
+ }
+
+ if (unlikely(!ctx->fpu_enabled)) {
+ gen_exception(ctx, POWERPC_EXCP_FPU);
+ return;
+ }
+
+ t0 = tcg_temp_new_i64();
+
+ gen_reset_fpstatus();
+ tcg_gen_extu_tl_i64(t0, cpu_fpscr);
+ set_fpr(rD(ctx->opcode), t0);
+
+ /* Clear exception enable bits in the FPSCR. */
+ tcg_gen_andi_i64(t0, t0, ~FP_ENABLES);
+ mask = tcg_const_i32(0x0003);
+ gen_helper_store_fpscr(cpu_env, t0, mask);
+
+ tcg_temp_free_i32(mask);
+ tcg_temp_free_i64(t0);
+}
+
+static void gen_helper_mffscrn(DisasContext *ctx, TCGv_i64 t1)
+{
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i32 mask = tcg_const_i32(0x0001);
+
+ gen_reset_fpstatus();
+ tcg_gen_extu_tl_i64(t0, cpu_fpscr);
+ tcg_gen_andi_i64(t0, t0, FP_DRN | FP_ENABLES | FP_RN);
+ set_fpr(rD(ctx->opcode), t0);
+
+ /* Mask FPSCR value to clear RN. */
+ tcg_gen_andi_i64(t0, t0, ~FP_RN);
+
+ /* Merge RN into FPSCR value. */
+ tcg_gen_or_i64(t0, t0, t1);
+
+ gen_helper_store_fpscr(cpu_env, t0, mask);
+
+ tcg_temp_free_i32(mask);
+ tcg_temp_free_i64(t0);
+}
+
+/* mffscrn */
+static void gen_mffscrn(DisasContext *ctx)
+{
+ TCGv_i64 t1;
+
+ if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) {
+ return gen_mffs(ctx);
+ }
+
+ if (unlikely(!ctx->fpu_enabled)) {
+ gen_exception(ctx, POWERPC_EXCP_FPU);
+ return;
+ }
+
+ t1 = tcg_temp_new_i64();
+ get_fpr(t1, rB(ctx->opcode));
+ /* Mask FRB to get just RN. */
+ tcg_gen_andi_i64(t1, t1, FP_RN);
+
+ gen_helper_mffscrn(ctx, t1);
+
+ tcg_temp_free_i64(t1);
+}
+
+/* mffscrni */
+static void gen_mffscrni(DisasContext *ctx)
+{
+ TCGv_i64 t1;
+
+ if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) {
+ return gen_mffs(ctx);
+ }
+
+ if (unlikely(!ctx->fpu_enabled)) {
+ gen_exception(ctx, POWERPC_EXCP_FPU);
+ return;
+ }
+
+ t1 = tcg_const_i64((uint64_t)RM(ctx->opcode));
+
+ gen_helper_mffscrn(ctx, t1);
+
+ tcg_temp_free_i64(t1);
+}
+
/* mtfsb0 */
static void gen_mtfsb0(DisasContext *ctx)
{
diff --git a/target/ppc/translate/fp-ops.inc.c b/target/ppc/translate/fp-ops.inc.c
index 88ebc2526c..88fab65628 100644
--- a/target/ppc/translate/fp-ops.inc.c
+++ b/target/ppc/translate/fp-ops.inc.c
@@ -105,8 +105,14 @@ GEN_HANDLER_E(fmrgew, 0x3F, 0x06, 0x1E, 0x00000001, PPC_NONE, PPC2_VSX207),
GEN_HANDLER_E(fmrgow, 0x3F, 0x06, 0x1A, 0x00000001, PPC_NONE, PPC2_VSX207),
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
GEN_HANDLER_E_2(mffs, 0x3F, 0x07, 0x12, 0x00, 0x00000000, PPC_FLOAT, PPC_NONE),
+GEN_HANDLER_E_2(mffsce, 0x3F, 0x07, 0x12, 0x01, 0x00000000, PPC_FLOAT,
+ PPC2_ISA300),
GEN_HANDLER_E_2(mffsl, 0x3F, 0x07, 0x12, 0x18, 0x00000000, PPC_FLOAT,
PPC2_ISA300),
+GEN_HANDLER_E_2(mffscrn, 0x3F, 0x07, 0x12, 0x16, 0x00000000, PPC_FLOAT,
+ PPC_NONE),
+GEN_HANDLER_E_2(mffscrni, 0x3F, 0x07, 0x12, 0x17, 0x00000000, PPC_FLOAT,
+ PPC_NONE),
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00000000, PPC_FLOAT),
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 0fb11c7ac6..ba726dec4d 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -8200,11 +8200,10 @@ static void gen_spr_power8_dpdes(CPUPPCState *env)
{
#if !defined(CONFIG_USER_ONLY)
/* Directed Privileged Door-bell Exception State, used for IPI */
- spr_register_kvm_hv(env, SPR_DPDES, "DPDES",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_DPDES, 0x00000000);
+ spr_register(env, SPR_DPDES, "DPDES",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, SPR_NOACCESS,
+ 0x00000000);
#endif
}