Fix long (and long long) to long double, unsigned to long double and unsigned
long (and unsigned long long) to long double conversions. - Add a parameter that specifies the position of the sign bit to the _QP_TTOQ macro, previously it always looked at bit 31. Pass a negative number to disable sign inspection for unsigned types. This fixes _Qp_xtoq(), _Qp_uitoq() and _Qp_uxtoq(). - In the functions __fpu_itof() and __fpu_xtof(), look at the sign bit to decide whether we're doing a conversion from an unsigned type. If so, don't negate the mantissa if the integer exceeds the biggest signed number. PR: 55773 Patch by: Stephen Paskaluk (based upon) MFC after: 2 weeks
This commit is contained in:
parent
b83d3b8bcc
commit
194c67c3c8
@ -101,7 +101,14 @@ __fpu_itof(fp, i)
|
||||
* fpu_norm()'s handling of `supernormals'; see fpu_subr.c.
|
||||
*/
|
||||
fp->fp_exp = FP_LG;
|
||||
fp->fp_mant[0] = (int)i < 0 ? -i : i;
|
||||
/*
|
||||
* The sign bit decides whether i should be interpreted as
|
||||
* a signed or unsigned entity.
|
||||
*/
|
||||
if (fp->fp_sign && (int)i < 0)
|
||||
fp->fp_mant[0] = -i;
|
||||
else
|
||||
fp->fp_mant[0] = i;
|
||||
fp->fp_mant[1] = 0;
|
||||
fp->fp_mant[2] = 0;
|
||||
fp->fp_mant[3] = 0;
|
||||
@ -127,7 +134,14 @@ __fpu_xtof(fp, i)
|
||||
* fpu_norm()'s handling of `supernormals'; see fpu_subr.c.
|
||||
*/
|
||||
fp->fp_exp = FP_LG2;
|
||||
*((int64_t*)fp->fp_mant) = (int64_t)i < 0 ? -i : i;
|
||||
/*
|
||||
* The sign bit decides whether i should be interpreted as
|
||||
* a signed or unsigned entity.
|
||||
*/
|
||||
if (fp->fp_sign && (int64_t)i < 0)
|
||||
*((int64_t*)fp->fp_mant) = -i;
|
||||
else
|
||||
*((int64_t*)fp->fp_mant) = i;
|
||||
fp->fp_mant[2] = 0;
|
||||
fp->fp_mant[3] = 0;
|
||||
__fpu_norm(fp);
|
||||
|
@ -51,7 +51,7 @@ _Qp_ ## op(u_int *c, u_int *a, u_int *b) \
|
||||
c[0] = __fpu_ftoq(&fe, r, c); \
|
||||
}
|
||||
|
||||
#define _QP_TTOQ(qname, fname, ntype, atype, ...) \
|
||||
#define _QP_TTOQ(qname, fname, ntype, signpos, atype, ...) \
|
||||
void _Qp_ ## qname ## toq(u_int *c, ntype n); \
|
||||
void \
|
||||
_Qp_ ## qname ## toq(u_int *c, ntype n) \
|
||||
@ -59,7 +59,7 @@ _Qp_ ## qname ## toq(u_int *c, ntype n) \
|
||||
struct fpemu fe; \
|
||||
union { atype a[2]; ntype n; } u = { .n = n }; \
|
||||
__asm __volatile("stx %%fsr, %0" : "=m" (fe.fe_fsr) :); \
|
||||
fe.fe_f1.fp_sign = u.a[0] >> 31; \
|
||||
fe.fe_f1.fp_sign = (signpos >= 0) ? u.a[0] >> signpos : 0; \
|
||||
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); \
|
||||
@ -123,12 +123,12 @@ _QP_OP(div)
|
||||
_QP_OP(mul)
|
||||
_QP_OP(sub)
|
||||
|
||||
_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_TTOQ(d, d, double, 31, u_int, u.a[0], u.a[1])
|
||||
_QP_TTOQ(i, i, int, 31, u_int, u.a[0])
|
||||
_QP_TTOQ(s, s, float, 31, u_int, u.a[0])
|
||||
_QP_TTOQ(x, x, long, 63, u_long, u.a[0])
|
||||
_QP_TTOQ(ui, i, u_int, -1, u_int, u.a[0])
|
||||
_QP_TTOQ(ux, x, u_long, -1, u_long, u.a[0])
|
||||
|
||||
_QP_QTOT(d, d, double, &u.a)
|
||||
_QP_QTOT(i, i, int)
|
||||
|
Loading…
Reference in New Issue
Block a user