Use unions to avoid violating C99 strict aliasing rules.
This commit is contained in:
parent
ffa157ec1e
commit
ce346529a3
@ -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];
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user