Use unions to avoid violating C99 strict aliasing rules.

This commit is contained in:
des 2004-03-16 20:42:02 +00:00
parent ffa157ec1e
commit ce346529a3
6 changed files with 50 additions and 43 deletions

View File

@ -47,13 +47,14 @@ static const int map[] = {
int
__flt_rounds()
{
double fpcrval;
u_int64_t old;
union {
double fpcrval;
u_int64_t intval;
} u;
__asm__("trapb");
__asm__("mf_fpcr %0" : "=f" (fpcrval));
__asm__("mf_fpcr %0" : "=f" (u.fpcrval));
__asm__("trapb");
old = *(u_int64_t *)&fpcrval;
return map[(old >> 58) & 0x3];
return map[(u.intval >> 58) & 0x3];
}

View File

@ -41,11 +41,12 @@ __FBSDID("$FreeBSD$");
fp_rnd_t
fpgetround()
{
double fpcrval;
u_int64_t old;
union {
double fpcrval;
u_int64_t intval;
} u;
GET_FPCR(fpcrval);
old = *(u_int64_t *)&fpcrval;
GET_FPCR(u.fpcrval);
return ((old & FPCR_DYN_MASK) >> FPCR_DYN_SHIFT);
return ((u.intval & FPCR_DYN_MASK) >> FPCR_DYN_SHIFT);
}

View File

@ -41,11 +41,12 @@ __FBSDID("$FreeBSD$");
fp_except_t
fpgetsticky()
{
double fpcrval;
u_int64_t old;
union {
double fpcrval;
u_int64_t intval;
} u;
GET_FPCR(fpcrval);
old = *(u_int64_t *)&fpcrval;
return (((old >> IEEE_STATUS_TO_FPCR_SHIFT) & IEEE_STATUS_MASK)
GET_FPCR(u.fpcrval);
return (((u.intval >> IEEE_STATUS_TO_FPCR_SHIFT) & IEEE_STATUS_MASK)
>> IEEE_STATUS_TO_EXCSUM_SHIFT);
}

View File

@ -42,17 +42,20 @@ fp_rnd_t
fpsetround(rnd_dir)
fp_rnd_t rnd_dir;
{
double fpcrval;
union {
double fpcrval;
u_int64_t intval;
} u;
u_int64_t old, new;
GET_FPCR(fpcrval);
old = *(u_int64_t *)&fpcrval;
GET_FPCR(u.fpcrval);
old = u.intval;
new = old & (~FPCR_DYN_MASK);
new |= ((long) rnd_dir << FPCR_DYN_SHIFT) & FPCR_DYN_MASK;
*(u_int64_t *)&fpcrval = new;
SET_FPCR(fpcrval);
u.intval = new;
SET_FPCR(u.fpcrval);
return ((old & FPCR_DYN_MASK) >> FPCR_DYN_SHIFT);
}

View File

@ -42,16 +42,20 @@ fp_except_t
fpsetsticky(sticky)
fp_except_t sticky;
{
double fpcrval;
u_int64_t old,new ;
union {
double fpcrval;
u_int64_t intval;
} u;
u_int64_t old, new;
GET_FPCR(fpcrval);
old = *(u_int64_t *)&fpcrval;
GET_FPCR(u.fpcrval);
old = u.intval;
new = old & ~ (IEEE_STATUS_MASK << IEEE_STATUS_TO_FPCR_SHIFT);
new |= ((sticky << IEEE_STATUS_TO_EXCSUM_SHIFT) & IEEE_STATUS_MASK)
<< IEEE_STATUS_TO_FPCR_SHIFT;
*(u_int64_t *)&fpcrval = new;
SET_FPCR(fpcrval);
u.intval = new;
SET_FPCR(u.fpcrval);
return (((old >> IEEE_STATUS_TO_FPCR_SHIFT) & IEEE_STATUS_MASK)
>> IEEE_STATUS_TO_EXCSUM_SHIFT);

View File

@ -57,10 +57,9 @@ void \
_Qp_ ## qname ## toq(u_int *c, ntype n) \
{ \
struct fpemu fe; \
atype *a; \
union { atype a[2]; ntype n; } u = { .n = n }; \
__asm __volatile("stx %%fsr, %0" : "=m" (fe.fe_fsr) :); \
a = (atype *)&n; \
fe.fe_f1.fp_sign = a[0] >> 31; \
fe.fe_f1.fp_sign = u.a[0] >> 31; \
fe.fe_f1.fp_sticky = 0; \
fe.fe_f1.fp_class = __fpu_ ## fname ## tof(&fe.fe_f1, __VA_ARGS__); \
c[0] = __fpu_ftoq(&fe, &fe.fe_f1, c); \
@ -72,15 +71,13 @@ type \
_Qp_qto ## qname(u_int *c) \
{ \
struct fpemu fe; \
u_int *a; \
type n; \
union { u_int a; type n; } u; \
__asm __volatile("stx %%fsr, %0" : "=m" (fe.fe_fsr) :); \
a = (u_int *)&n; \
fe.fe_f1.fp_sign = c[0] >> 31; \
fe.fe_f1.fp_sticky = 0; \
fe.fe_f1.fp_class = __fpu_qtof(&fe.fe_f1, c[0], c[1], c[2], c[3]); \
a[0] = __fpu_fto ## fname(&fe, &fe.fe_f1, ## __VA_ARGS__); \
return (n); \
u.a = __fpu_fto ## fname(&fe, &fe.fe_f1, ## __VA_ARGS__); \
return (u.n); \
}
#define FCC_EQ(fcc) ((fcc) == FSR_CC_EQ)
@ -126,19 +123,19 @@ _QP_OP(div)
_QP_OP(mul)
_QP_OP(sub)
_QP_TTOQ(d, d, double, u_int, a[0], a[1])
_QP_TTOQ(i, i, int, u_int, a[0])
_QP_TTOQ(s, s, float, u_int, a[0])
_QP_TTOQ(x, x, long, u_long, a[0])
_QP_TTOQ(ui, i, u_int, u_int, a[0])
_QP_TTOQ(ux, x, u_long, u_long, a[0])
_QP_TTOQ(d, d, double, u_int, u.a[0], u.a[1])
_QP_TTOQ(i, i, int, u_int, u.a[0])
_QP_TTOQ(s, s, float, u_int, u.a[0])
_QP_TTOQ(x, x, long, u_long, u.a[0])
_QP_TTOQ(ui, i, u_int, u_int, u.a[0])
_QP_TTOQ(ux, x, u_long, u_long, u.a[0])
_QP_QTOT(d, d, double, a)
_QP_QTOT(d, d, double, &u.a)
_QP_QTOT(i, i, int)
_QP_QTOT(s, s, float)
_QP_QTOT(x, x, long, a)
_QP_QTOT(x, x, long, &u.a)
_QP_QTOT(ui, i, u_int)
_QP_QTOT(ux, x, u_long, a)
_QP_QTOT(ux, x, u_long, &u.a)
_QP_CMP(eq, 0, FCC_EQ)
_QP_CMP(ge, 0, FCC_GE)