target-i386: Fix several SSE3 instructions.

haddp[sd], hsubp[sd] and addsubp[sd] operate on floats, thus it is
necessary to use the appropriate floating point calculation functions.
If this is not done, those functions operate merely on integers, which
is not correct.

Signed-off-by: Max Reitz <max@tyndur.org>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
Max Reitz 2011-09-16 17:29:04 +02:00 committed by Blue Swirl
parent 4e1837f855
commit 5c6562c204

View File

@ -859,51 +859,51 @@ void helper_insertq_i(XMMReg *d, int index, int length)
void helper_haddps(XMMReg *d, XMMReg *s)
{
XMMReg r;
r.XMM_S(0) = d->XMM_S(0) + d->XMM_S(1);
r.XMM_S(1) = d->XMM_S(2) + d->XMM_S(3);
r.XMM_S(2) = s->XMM_S(0) + s->XMM_S(1);
r.XMM_S(3) = s->XMM_S(2) + s->XMM_S(3);
r.XMM_S(0) = float32_add(d->XMM_S(0), d->XMM_S(1), &env->sse_status);
r.XMM_S(1) = float32_add(d->XMM_S(2), d->XMM_S(3), &env->sse_status);
r.XMM_S(2) = float32_add(s->XMM_S(0), s->XMM_S(1), &env->sse_status);
r.XMM_S(3) = float32_add(s->XMM_S(2), s->XMM_S(3), &env->sse_status);
*d = r;
}
void helper_haddpd(XMMReg *d, XMMReg *s)
{
XMMReg r;
r.XMM_D(0) = d->XMM_D(0) + d->XMM_D(1);
r.XMM_D(1) = s->XMM_D(0) + s->XMM_D(1);
r.XMM_D(0) = float64_add(d->XMM_D(0), d->XMM_D(1), &env->sse_status);
r.XMM_D(1) = float64_add(s->XMM_D(0), s->XMM_D(1), &env->sse_status);
*d = r;
}
void helper_hsubps(XMMReg *d, XMMReg *s)
{
XMMReg r;
r.XMM_S(0) = d->XMM_S(0) - d->XMM_S(1);
r.XMM_S(1) = d->XMM_S(2) - d->XMM_S(3);
r.XMM_S(2) = s->XMM_S(0) - s->XMM_S(1);
r.XMM_S(3) = s->XMM_S(2) - s->XMM_S(3);
r.XMM_S(0) = float32_sub(d->XMM_S(0), d->XMM_S(1), &env->sse_status);
r.XMM_S(1) = float32_sub(d->XMM_S(2), d->XMM_S(3), &env->sse_status);
r.XMM_S(2) = float32_sub(s->XMM_S(0), s->XMM_S(1), &env->sse_status);
r.XMM_S(3) = float32_sub(s->XMM_S(2), s->XMM_S(3), &env->sse_status);
*d = r;
}
void helper_hsubpd(XMMReg *d, XMMReg *s)
{
XMMReg r;
r.XMM_D(0) = d->XMM_D(0) - d->XMM_D(1);
r.XMM_D(1) = s->XMM_D(0) - s->XMM_D(1);
r.XMM_D(0) = float64_sub(d->XMM_D(0), d->XMM_D(1), &env->sse_status);
r.XMM_D(1) = float64_sub(s->XMM_D(0), s->XMM_D(1), &env->sse_status);
*d = r;
}
void helper_addsubps(XMMReg *d, XMMReg *s)
{
d->XMM_S(0) = d->XMM_S(0) - s->XMM_S(0);
d->XMM_S(1) = d->XMM_S(1) + s->XMM_S(1);
d->XMM_S(2) = d->XMM_S(2) - s->XMM_S(2);
d->XMM_S(3) = d->XMM_S(3) + s->XMM_S(3);
d->XMM_S(0) = float32_sub(d->XMM_S(0), s->XMM_S(0), &env->sse_status);
d->XMM_S(1) = float32_add(d->XMM_S(1), s->XMM_S(1), &env->sse_status);
d->XMM_S(2) = float32_sub(d->XMM_S(2), s->XMM_S(2), &env->sse_status);
d->XMM_S(3) = float32_add(d->XMM_S(3), s->XMM_S(3), &env->sse_status);
}
void helper_addsubpd(XMMReg *d, XMMReg *s)
{
d->XMM_D(0) = d->XMM_D(0) - s->XMM_D(0);
d->XMM_D(1) = d->XMM_D(1) + s->XMM_D(1);
d->XMM_D(0) = float64_sub(d->XMM_D(0), s->XMM_D(0), &env->sse_status);
d->XMM_D(1) = float64_add(d->XMM_D(1), s->XMM_D(1), &env->sse_status);
}
/* XXX: unordered */