mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 11:39:53 +00:00
target/ppc: Change VSX instructions behavior to fill with zeros
ISA v3.1 changed some VSX instructions behavior by changing what the other words/doubleword in the result should contain when the result is only one word/doubleword. e.g. xsmaxdp operates on doubleword 0 and saves the result also in doubleword 0. Before, the second doubleword result was undefined according to the ISA, but now it's stated that it should be zeroed. Even tough the result was undefined before, hardware implementing these instructions already filled these fields with 0s. Changing every ISA version in QEMU to this behavior makes the results match what happens in hardware. Signed-off-by: Víctor Colombo <victor.colombo@eldorado.org.br> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20220204181944.65063-1-victor.colombo@eldorado.org.br> Signed-off-by: Cédric Le Goater <clg@kaod.org>
This commit is contained in:
parent
10895ab6f7
commit
205eb5a89e
@ -1696,7 +1696,7 @@ uint32_t helper_efdcmpeq(CPUPPCState *env, uint64_t op1, uint64_t op2)
|
|||||||
void helper_##name(CPUPPCState *env, ppc_vsr_t *xt, \
|
void helper_##name(CPUPPCState *env, ppc_vsr_t *xt, \
|
||||||
ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
||||||
{ \
|
{ \
|
||||||
ppc_vsr_t t = *xt; \
|
ppc_vsr_t t = { }; \
|
||||||
int i; \
|
int i; \
|
||||||
\
|
\
|
||||||
helper_reset_fpstatus(env); \
|
helper_reset_fpstatus(env); \
|
||||||
@ -1772,7 +1772,7 @@ void helper_xsaddqp(CPUPPCState *env, uint32_t opcode,
|
|||||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
|
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
|
||||||
ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
||||||
{ \
|
{ \
|
||||||
ppc_vsr_t t = *xt; \
|
ppc_vsr_t t = { }; \
|
||||||
int i; \
|
int i; \
|
||||||
\
|
\
|
||||||
helper_reset_fpstatus(env); \
|
helper_reset_fpstatus(env); \
|
||||||
@ -1843,7 +1843,7 @@ void helper_xsmulqp(CPUPPCState *env, uint32_t opcode,
|
|||||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
|
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
|
||||||
ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
||||||
{ \
|
{ \
|
||||||
ppc_vsr_t t = *xt; \
|
ppc_vsr_t t = { }; \
|
||||||
int i; \
|
int i; \
|
||||||
\
|
\
|
||||||
helper_reset_fpstatus(env); \
|
helper_reset_fpstatus(env); \
|
||||||
@ -1919,7 +1919,7 @@ void helper_xsdivqp(CPUPPCState *env, uint32_t opcode,
|
|||||||
#define VSX_RE(op, nels, tp, fld, sfprf, r2sp) \
|
#define VSX_RE(op, nels, tp, fld, sfprf, r2sp) \
|
||||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
||||||
{ \
|
{ \
|
||||||
ppc_vsr_t t = *xt; \
|
ppc_vsr_t t = { }; \
|
||||||
int i; \
|
int i; \
|
||||||
\
|
\
|
||||||
helper_reset_fpstatus(env); \
|
helper_reset_fpstatus(env); \
|
||||||
@ -1959,7 +1959,7 @@ VSX_RE(xvresp, 4, float32, VsrW(i), 0, 0)
|
|||||||
#define VSX_SQRT(op, nels, tp, fld, sfprf, r2sp) \
|
#define VSX_SQRT(op, nels, tp, fld, sfprf, r2sp) \
|
||||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
||||||
{ \
|
{ \
|
||||||
ppc_vsr_t t = *xt; \
|
ppc_vsr_t t = { }; \
|
||||||
int i; \
|
int i; \
|
||||||
\
|
\
|
||||||
helper_reset_fpstatus(env); \
|
helper_reset_fpstatus(env); \
|
||||||
@ -2004,7 +2004,7 @@ VSX_SQRT(xvsqrtsp, 4, float32, VsrW(i), 0, 0)
|
|||||||
#define VSX_RSQRTE(op, nels, tp, fld, sfprf, r2sp) \
|
#define VSX_RSQRTE(op, nels, tp, fld, sfprf, r2sp) \
|
||||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
||||||
{ \
|
{ \
|
||||||
ppc_vsr_t t = *xt; \
|
ppc_vsr_t t = { }; \
|
||||||
int i; \
|
int i; \
|
||||||
\
|
\
|
||||||
helper_reset_fpstatus(env); \
|
helper_reset_fpstatus(env); \
|
||||||
@ -2472,7 +2472,7 @@ void helper_xscmpuqp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xa,
|
|||||||
void helper_##name(CPUPPCState *env, ppc_vsr_t *xt, \
|
void helper_##name(CPUPPCState *env, ppc_vsr_t *xt, \
|
||||||
ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
||||||
{ \
|
{ \
|
||||||
ppc_vsr_t t = *xt; \
|
ppc_vsr_t t = { }; \
|
||||||
int i; \
|
int i; \
|
||||||
\
|
\
|
||||||
for (i = 0; i < nels; i++) { \
|
for (i = 0; i < nels; i++) { \
|
||||||
@ -2498,7 +2498,7 @@ VSX_MAX_MIN(xvminsp, minnum, 4, float32, VsrW(i))
|
|||||||
void helper_##name(CPUPPCState *env, \
|
void helper_##name(CPUPPCState *env, \
|
||||||
ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
||||||
{ \
|
{ \
|
||||||
ppc_vsr_t t = *xt; \
|
ppc_vsr_t t = { }; \
|
||||||
bool vxsnan_flag = false, vex_flag = false; \
|
bool vxsnan_flag = false, vex_flag = false; \
|
||||||
\
|
\
|
||||||
if (unlikely(float64_is_any_nan(xa->VsrD(0)) || \
|
if (unlikely(float64_is_any_nan(xa->VsrD(0)) || \
|
||||||
@ -2533,7 +2533,7 @@ VSX_MAX_MINC(xsmincdp, 0);
|
|||||||
void helper_##name(CPUPPCState *env, \
|
void helper_##name(CPUPPCState *env, \
|
||||||
ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb) \
|
||||||
{ \
|
{ \
|
||||||
ppc_vsr_t t = *xt; \
|
ppc_vsr_t t = { }; \
|
||||||
bool vxsnan_flag = false, vex_flag = false; \
|
bool vxsnan_flag = false, vex_flag = false; \
|
||||||
\
|
\
|
||||||
if (unlikely(float64_is_any_nan(xa->VsrD(0)))) { \
|
if (unlikely(float64_is_any_nan(xa->VsrD(0)))) { \
|
||||||
@ -2654,7 +2654,7 @@ VSX_CMP(xvcmpnesp, 4, float32, VsrW(i), eq, 0, 0)
|
|||||||
#define VSX_CVT_FP_TO_FP(op, nels, stp, ttp, sfld, tfld, sfprf) \
|
#define VSX_CVT_FP_TO_FP(op, nels, stp, ttp, sfld, tfld, sfprf) \
|
||||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
||||||
{ \
|
{ \
|
||||||
ppc_vsr_t t = *xt; \
|
ppc_vsr_t t = { }; \
|
||||||
int i; \
|
int i; \
|
||||||
\
|
\
|
||||||
for (i = 0; i < nels; i++) { \
|
for (i = 0; i < nels; i++) { \
|
||||||
@ -2833,7 +2833,7 @@ uint64_t helper_xscvspdpn(CPUPPCState *env, uint64_t xb)
|
|||||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
||||||
{ \
|
{ \
|
||||||
int all_flags = env->fp_status.float_exception_flags, flags; \
|
int all_flags = env->fp_status.float_exception_flags, flags; \
|
||||||
ppc_vsr_t t = *xt; \
|
ppc_vsr_t t = { }; \
|
||||||
int i; \
|
int i; \
|
||||||
\
|
\
|
||||||
for (i = 0; i < nels; i++) { \
|
for (i = 0; i < nels; i++) { \
|
||||||
@ -2917,7 +2917,7 @@ VSX_CVT_FP_TO_INT_VECTOR(xscvqpuwz, float128, uint32, f128, VsrD(0), 0x0ULL)
|
|||||||
#define VSX_CVT_INT_TO_FP(op, nels, stp, ttp, sfld, tfld, sfprf, r2sp) \
|
#define VSX_CVT_INT_TO_FP(op, nels, stp, ttp, sfld, tfld, sfprf, r2sp) \
|
||||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
||||||
{ \
|
{ \
|
||||||
ppc_vsr_t t = *xt; \
|
ppc_vsr_t t = { }; \
|
||||||
int i; \
|
int i; \
|
||||||
\
|
\
|
||||||
for (i = 0; i < nels; i++) { \
|
for (i = 0; i < nels; i++) { \
|
||||||
@ -2990,7 +2990,7 @@ VSX_CVT_INT_TO_FP_VECTOR(xscvudqp, uint64, float128, VsrD(0), f128)
|
|||||||
#define VSX_ROUND(op, nels, tp, fld, rmode, sfprf) \
|
#define VSX_ROUND(op, nels, tp, fld, rmode, sfprf) \
|
||||||
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
|
||||||
{ \
|
{ \
|
||||||
ppc_vsr_t t = *xt; \
|
ppc_vsr_t t = { }; \
|
||||||
int i; \
|
int i; \
|
||||||
FloatRoundMode curr_rounding_mode; \
|
FloatRoundMode curr_rounding_mode; \
|
||||||
\
|
\
|
||||||
|
@ -747,6 +747,7 @@ static void glue(gen_, name)(DisasContext *ctx) \
|
|||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
set_cpu_vsr(xT(ctx->opcode), xb, true); \
|
set_cpu_vsr(xT(ctx->opcode), xb, true); \
|
||||||
|
set_cpu_vsr(xT(ctx->opcode), tcg_constant_i64(0), false); \
|
||||||
tcg_temp_free_i64(xb); \
|
tcg_temp_free_i64(xb); \
|
||||||
tcg_temp_free_i64(sgm); \
|
tcg_temp_free_i64(sgm); \
|
||||||
}
|
}
|
||||||
@ -1073,6 +1074,7 @@ static void gen_##name(DisasContext *ctx) \
|
|||||||
get_cpu_vsr(t0, xB(ctx->opcode), true); \
|
get_cpu_vsr(t0, xB(ctx->opcode), true); \
|
||||||
gen_helper_##name(t1, cpu_env, t0); \
|
gen_helper_##name(t1, cpu_env, t0); \
|
||||||
set_cpu_vsr(xT(ctx->opcode), t1, true); \
|
set_cpu_vsr(xT(ctx->opcode), t1, true); \
|
||||||
|
set_cpu_vsr(xT(ctx->opcode), tcg_constant_i64(0), false); \
|
||||||
tcg_temp_free_i64(t0); \
|
tcg_temp_free_i64(t0); \
|
||||||
tcg_temp_free_i64(t1); \
|
tcg_temp_free_i64(t1); \
|
||||||
}
|
}
|
||||||
@ -1700,7 +1702,7 @@ static void gen_xsiexpdp(DisasContext *ctx)
|
|||||||
tcg_gen_shli_i64(t0, t0, 52);
|
tcg_gen_shli_i64(t0, t0, 52);
|
||||||
tcg_gen_or_i64(xth, xth, t0);
|
tcg_gen_or_i64(xth, xth, t0);
|
||||||
set_cpu_vsr(xT(ctx->opcode), xth, true);
|
set_cpu_vsr(xT(ctx->opcode), xth, true);
|
||||||
/* dword[1] is undefined */
|
set_cpu_vsr(xT(ctx->opcode), tcg_constant_i64(0), false);
|
||||||
tcg_temp_free_i64(t0);
|
tcg_temp_free_i64(t0);
|
||||||
tcg_temp_free_i64(xth);
|
tcg_temp_free_i64(xth);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user