mirror of
https://github.com/qemu/qemu.git
synced 2024-11-29 06:43:37 +08:00
target/i386: Floating point arithmetic helper AVX prep
Prepare the "easy" floating point vector helpers for AVX No functional changes to existing helpers. Signed-off-by: Paul Brook <paul@nowt.org> Message-Id: <20220424220204.2493824-16-paul@nowt.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
d45b0de63d
commit
3403cafeee
@ -553,40 +553,58 @@ void glue(helper_pshufhw, SUFFIX)(Reg *d, Reg *s, int order)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SHIFT == 1
|
||||
#if SHIFT >= 1
|
||||
/* FPU ops */
|
||||
/* XXX: not accurate */
|
||||
|
||||
#define SSE_HELPER_S(name, F) \
|
||||
void glue(helper_ ## name ## ps, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)\
|
||||
#define SSE_HELPER_P(name, F) \
|
||||
void glue(helper_ ## name ## ps, SUFFIX)(CPUX86State *env, \
|
||||
Reg *d, Reg *s) \
|
||||
{ \
|
||||
d->ZMM_S(0) = F(32, d->ZMM_S(0), s->ZMM_S(0)); \
|
||||
d->ZMM_S(1) = F(32, d->ZMM_S(1), s->ZMM_S(1)); \
|
||||
d->ZMM_S(2) = F(32, d->ZMM_S(2), s->ZMM_S(2)); \
|
||||
d->ZMM_S(3) = F(32, d->ZMM_S(3), s->ZMM_S(3)); \
|
||||
Reg *v = d; \
|
||||
int i; \
|
||||
for (i = 0; i < 2 << SHIFT; i++) { \
|
||||
d->ZMM_S(i) = F(32, v->ZMM_S(i), s->ZMM_S(i)); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
void helper_ ## name ## ss(CPUX86State *env, Reg *d, Reg *s) \
|
||||
void glue(helper_ ## name ## pd, SUFFIX)(CPUX86State *env, \
|
||||
Reg *d, Reg *s) \
|
||||
{ \
|
||||
d->ZMM_S(0) = F(32, d->ZMM_S(0), s->ZMM_S(0)); \
|
||||
} \
|
||||
\
|
||||
void glue(helper_ ## name ## pd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)\
|
||||
{ \
|
||||
d->ZMM_D(0) = F(64, d->ZMM_D(0), s->ZMM_D(0)); \
|
||||
d->ZMM_D(1) = F(64, d->ZMM_D(1), s->ZMM_D(1)); \
|
||||
} \
|
||||
\
|
||||
void helper_ ## name ## sd(CPUX86State *env, Reg *d, Reg *s) \
|
||||
{ \
|
||||
d->ZMM_D(0) = F(64, d->ZMM_D(0), s->ZMM_D(0)); \
|
||||
Reg *v = d; \
|
||||
int i; \
|
||||
for (i = 0; i < 1 << SHIFT; i++) { \
|
||||
d->ZMM_D(i) = F(64, v->ZMM_D(i), s->ZMM_D(i)); \
|
||||
} \
|
||||
}
|
||||
|
||||
#if SHIFT == 1
|
||||
|
||||
#define SSE_HELPER_S(name, F) \
|
||||
SSE_HELPER_P(name, F) \
|
||||
\
|
||||
void helper_ ## name ## ss(CPUX86State *env, Reg *d, Reg *s)\
|
||||
{ \
|
||||
Reg *v = d; \
|
||||
d->ZMM_S(0) = F(32, v->ZMM_S(0), s->ZMM_S(0)); \
|
||||
} \
|
||||
\
|
||||
void helper_ ## name ## sd(CPUX86State *env, Reg *d, Reg *s)\
|
||||
{ \
|
||||
Reg *v = d; \
|
||||
d->ZMM_D(0) = F(64, v->ZMM_D(0), s->ZMM_D(0)); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define SSE_HELPER_S(name, F) SSE_HELPER_P(name, F)
|
||||
|
||||
#endif
|
||||
|
||||
#define FPU_ADD(size, a, b) float ## size ## _add(a, b, &env->sse_status)
|
||||
#define FPU_SUB(size, a, b) float ## size ## _sub(a, b, &env->sse_status)
|
||||
#define FPU_MUL(size, a, b) float ## size ## _mul(a, b, &env->sse_status)
|
||||
#define FPU_DIV(size, a, b) float ## size ## _div(a, b, &env->sse_status)
|
||||
#define FPU_SQRT(size, a, b) float ## size ## _sqrt(b, &env->sse_status)
|
||||
|
||||
/* Note that the choice of comparison op here is important to get the
|
||||
* special cases right: for min and max Intel specifies that (-0,0),
|
||||
@ -603,8 +621,34 @@ SSE_HELPER_S(mul, FPU_MUL)
|
||||
SSE_HELPER_S(div, FPU_DIV)
|
||||
SSE_HELPER_S(min, FPU_MIN)
|
||||
SSE_HELPER_S(max, FPU_MAX)
|
||||
SSE_HELPER_S(sqrt, FPU_SQRT)
|
||||
|
||||
void glue(helper_sqrtps, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 2 << SHIFT; i++) {
|
||||
d->ZMM_S(i) = float32_sqrt(s->ZMM_S(i), &env->sse_status);
|
||||
}
|
||||
}
|
||||
|
||||
void glue(helper_sqrtpd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 1 << SHIFT; i++) {
|
||||
d->ZMM_D(i) = float64_sqrt(s->ZMM_D(i), &env->sse_status);
|
||||
}
|
||||
}
|
||||
|
||||
#if SHIFT == 1
|
||||
void helper_sqrtss(CPUX86State *env, Reg *d, Reg *s)
|
||||
{
|
||||
d->ZMM_S(0) = float32_sqrt(s->ZMM_S(0), &env->sse_status);
|
||||
}
|
||||
|
||||
void helper_sqrtsd(CPUX86State *env, Reg *d, Reg *s)
|
||||
{
|
||||
d->ZMM_D(0) = float64_sqrt(s->ZMM_D(0), &env->sse_status);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* float to float conversions */
|
||||
void glue(helper_cvtps2pd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
|
||||
@ -822,18 +866,12 @@ int64_t helper_cvttsd2sq(CPUX86State *env, ZMMReg *s)
|
||||
void glue(helper_rsqrtps, SUFFIX)(CPUX86State *env, ZMMReg *d, ZMMReg *s)
|
||||
{
|
||||
uint8_t old_flags = get_float_exception_flags(&env->sse_status);
|
||||
d->ZMM_S(0) = float32_div(float32_one,
|
||||
float32_sqrt(s->ZMM_S(0), &env->sse_status),
|
||||
&env->sse_status);
|
||||
d->ZMM_S(1) = float32_div(float32_one,
|
||||
float32_sqrt(s->ZMM_S(1), &env->sse_status),
|
||||
&env->sse_status);
|
||||
d->ZMM_S(2) = float32_div(float32_one,
|
||||
float32_sqrt(s->ZMM_S(2), &env->sse_status),
|
||||
&env->sse_status);
|
||||
d->ZMM_S(3) = float32_div(float32_one,
|
||||
float32_sqrt(s->ZMM_S(3), &env->sse_status),
|
||||
&env->sse_status);
|
||||
int i;
|
||||
for (i = 0; i < 2 << SHIFT; i++) {
|
||||
d->ZMM_S(i) = float32_div(float32_one,
|
||||
float32_sqrt(s->ZMM_S(i), &env->sse_status),
|
||||
&env->sse_status);
|
||||
}
|
||||
set_float_exception_flags(old_flags, &env->sse_status);
|
||||
}
|
||||
|
||||
@ -849,10 +887,10 @@ void helper_rsqrtss(CPUX86State *env, ZMMReg *d, ZMMReg *s)
|
||||
void glue(helper_rcpps, SUFFIX)(CPUX86State *env, ZMMReg *d, ZMMReg *s)
|
||||
{
|
||||
uint8_t old_flags = get_float_exception_flags(&env->sse_status);
|
||||
d->ZMM_S(0) = float32_div(float32_one, s->ZMM_S(0), &env->sse_status);
|
||||
d->ZMM_S(1) = float32_div(float32_one, s->ZMM_S(1), &env->sse_status);
|
||||
d->ZMM_S(2) = float32_div(float32_one, s->ZMM_S(2), &env->sse_status);
|
||||
d->ZMM_S(3) = float32_div(float32_one, s->ZMM_S(3), &env->sse_status);
|
||||
int i;
|
||||
for (i = 0; i < 2 << SHIFT; i++) {
|
||||
d->ZMM_S(i) = float32_div(float32_one, s->ZMM_S(i), &env->sse_status);
|
||||
}
|
||||
set_float_exception_flags(old_flags, &env->sse_status);
|
||||
}
|
||||
|
||||
@ -947,18 +985,24 @@ void glue(helper_hsubpd, SUFFIX)(CPUX86State *env, ZMMReg *d, ZMMReg *s)
|
||||
MOVE(*d, r);
|
||||
}
|
||||
|
||||
void glue(helper_addsubps, SUFFIX)(CPUX86State *env, ZMMReg *d, ZMMReg *s)
|
||||
void glue(helper_addsubps, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
|
||||
{
|
||||
d->ZMM_S(0) = float32_sub(d->ZMM_S(0), s->ZMM_S(0), &env->sse_status);
|
||||
d->ZMM_S(1) = float32_add(d->ZMM_S(1), s->ZMM_S(1), &env->sse_status);
|
||||
d->ZMM_S(2) = float32_sub(d->ZMM_S(2), s->ZMM_S(2), &env->sse_status);
|
||||
d->ZMM_S(3) = float32_add(d->ZMM_S(3), s->ZMM_S(3), &env->sse_status);
|
||||
Reg *v = d;
|
||||
int i;
|
||||
for (i = 0; i < 2 << SHIFT; i += 2) {
|
||||
d->ZMM_S(i) = float32_sub(v->ZMM_S(i), s->ZMM_S(i), &env->sse_status);
|
||||
d->ZMM_S(i+1) = float32_add(v->ZMM_S(i+1), s->ZMM_S(i+1), &env->sse_status);
|
||||
}
|
||||
}
|
||||
|
||||
void glue(helper_addsubpd, SUFFIX)(CPUX86State *env, ZMMReg *d, ZMMReg *s)
|
||||
void glue(helper_addsubpd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
|
||||
{
|
||||
d->ZMM_D(0) = float64_sub(d->ZMM_D(0), s->ZMM_D(0), &env->sse_status);
|
||||
d->ZMM_D(1) = float64_add(d->ZMM_D(1), s->ZMM_D(1), &env->sse_status);
|
||||
Reg *v = d;
|
||||
int i;
|
||||
for (i = 0; i < 1 << SHIFT; i += 2) {
|
||||
d->ZMM_D(i) = float64_sub(v->ZMM_D(i), s->ZMM_D(i), &env->sse_status);
|
||||
d->ZMM_D(i+1) = float64_add(v->ZMM_D(i+1), s->ZMM_D(i+1), &env->sse_status);
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: unordered */
|
||||
@ -2258,6 +2302,8 @@ void glue(helper_aeskeygenassist, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef SSE_HELPER_S
|
||||
|
||||
#undef SHIFT
|
||||
#undef XMM_ONLY
|
||||
#undef Reg
|
||||
|
Loading…
Reference in New Issue
Block a user