mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-11 07:40:05 +00:00
PowerPC floating point little-endian [11 of 15]
http://sourceware.org/ml/libc-alpha/2013-07/msg00202.html Another little-endian fix. * sysdeps/powerpc/fpu_control.h (_FPU_GETCW): Rewrite using 64-bit int/double union. (_FPU_SETCW): Likewise. * sysdeps/powerpc/fpu/tst-setcontext-fpscr.c (_GET_DI_FPSCR): Likewise. (_SET_DI_FPSCR, _GET_SI_FPSCR, _SET_SI_FPSCR): Likewise.
This commit is contained in:
parent
da13146da1
commit
9c008155b7
@ -1,3 +1,11 @@
|
|||||||
|
2013-10-04 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* sysdeps/powerpc/fpu_control.h (_FPU_GETCW): Rewrite using
|
||||||
|
64-bit int/double union.
|
||||||
|
(_FPU_SETCW): Likewise.
|
||||||
|
* sysdeps/powerpc/fpu/tst-setcontext-fpscr.c (_GET_DI_FPSCR): Likewise.
|
||||||
|
(_SET_DI_FPSCR, _GET_SI_FPSCR, _SET_SI_FPSCR): Likewise.
|
||||||
|
|
||||||
2013-10-04 Alan Modra <amodra@gmail.com>
|
2013-10-04 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* sysdeps/powerpc/fpu/s_llround.c (__llround): Rewrite.
|
* sysdeps/powerpc/fpu/s_llround.c (__llround): Rewrite.
|
||||||
|
@ -83,7 +83,7 @@ ElfW(Addr) query_auxv(int type)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef unsigned long long di_fpscr_t __attribute__ ((__mode__ (__DI__)));
|
typedef unsigned int di_fpscr_t __attribute__ ((__mode__ (__DI__)));
|
||||||
typedef unsigned int si_fpscr_t __attribute__ ((__mode__ (__SI__)));
|
typedef unsigned int si_fpscr_t __attribute__ ((__mode__ (__SI__)));
|
||||||
|
|
||||||
#define _FPSCR_RESERVED 0xfffffff8ffffff04ULL
|
#define _FPSCR_RESERVED 0xfffffff8ffffff04ULL
|
||||||
@ -95,49 +95,50 @@ typedef unsigned int si_fpscr_t __attribute__ ((__mode__ (__SI__)));
|
|||||||
#define _FPSCR_TEST1_RN 0x0000000000000002ULL
|
#define _FPSCR_TEST1_RN 0x0000000000000002ULL
|
||||||
|
|
||||||
/* Macros for accessing the hardware control word on Power6[x]. */
|
/* Macros for accessing the hardware control word on Power6[x]. */
|
||||||
# define _GET_DI_FPSCR(__fpscr) ({ \
|
#define _GET_DI_FPSCR(__fpscr) \
|
||||||
union { double d; \
|
({union { double d; di_fpscr_t fpscr; } u; \
|
||||||
di_fpscr_t fpscr; } \
|
register double fr; \
|
||||||
tmp __attribute__ ((__aligned__(8))); \
|
__asm__ ("mffs %0" : "=f" (fr)); \
|
||||||
__asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0"); \
|
u.d = fr; \
|
||||||
(__fpscr)=tmp.fpscr; \
|
(__fpscr) = u.fpscr; \
|
||||||
tmp.fpscr; })
|
u.fpscr; \
|
||||||
|
})
|
||||||
|
|
||||||
/* We make sure to zero fp0 after we use it in order to prevent stale data
|
/* We make sure to zero fp after we use it in order to prevent stale data
|
||||||
in an fp register from making a test-case pass erroneously. */
|
in an fp register from making a test-case pass erroneously. */
|
||||||
# define _SET_DI_FPSCR(__fpscr) { \
|
# define _SET_DI_FPSCR(__fpscr) \
|
||||||
union { double d; di_fpscr_t fpscr; } \
|
{ union { double d; di_fpscr_t fpscr; } u; \
|
||||||
tmp __attribute__ ((__aligned__(8))); \
|
register double fr; \
|
||||||
tmp.fpscr = __fpscr; \
|
u.fpscr = __fpscr; \
|
||||||
|
fr = u.d; \
|
||||||
/* Set the entire 64-bit FPSCR. */ \
|
/* Set the entire 64-bit FPSCR. */ \
|
||||||
__asm__ ("lfd%U0 0,%0; " \
|
__asm__ (".machine push; " \
|
||||||
".machine push; " \
|
|
||||||
".machine \"power6\"; " \
|
".machine \"power6\"; " \
|
||||||
"mtfsf 255,0,1,0; " \
|
"mtfsf 255,%0,1,0; " \
|
||||||
".machine pop" : : "m" (tmp.d) : "fr0"); \
|
".machine pop" : : "f" (fr)); \
|
||||||
tmp.d = 0; \
|
fr = 0.0; \
|
||||||
__asm__("lfd%U0 0,%0" : : "m" (tmp.d) : "fr0"); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# define _GET_SI_FPSCR(__fpscr) ({ \
|
# define _GET_SI_FPSCR(__fpscr) \
|
||||||
union { double d; \
|
({union { double d; di_fpscr_t fpscr; } u; \
|
||||||
si_fpscr_t cw[2]; } \
|
register double fr; \
|
||||||
tmp __attribute__ ((__aligned__(8))); \
|
__asm__ ("mffs %0" : "=f" (fr)); \
|
||||||
__asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0"); \
|
u.d = fr; \
|
||||||
(__fpscr)=tmp.cw[1]; \
|
(__fpscr) = (si_fpscr_t) u.fpscr; \
|
||||||
tmp.cw[0]; })
|
(si_fpscr_t) u.fpscr; \
|
||||||
|
})
|
||||||
|
|
||||||
/* We make sure to zero fp0 after we use it in order to prevent stale data
|
/* We make sure to zero fp after we use it in order to prevent stale data
|
||||||
in an fp register from making a test-case pass erroneously. */
|
in an fp register from making a test-case pass erroneously. */
|
||||||
# define _SET_SI_FPSCR(__fpscr) { \
|
# define _SET_SI_FPSCR(__fpscr) \
|
||||||
union { double d; si_fpscr_t fpscr[2]; } \
|
{ union { double d; di_fpscr_t fpscr; } u; \
|
||||||
tmp __attribute__ ((__aligned__(8))); \
|
register double fr; \
|
||||||
/* More-or-less arbitrary; this is a QNaN. */ \
|
/* More-or-less arbitrary; this is a QNaN. */ \
|
||||||
tmp.fpscr[0] = 0xFFF80000; \
|
u.fpscr = 0xfff80000ULL << 32; \
|
||||||
tmp.fpscr[1] = __fpscr; \
|
u.fpscr |= __fpscr & 0xffffffffULL; \
|
||||||
__asm__ ("lfd%U0 0,%0; mtfsf 255,0" : : "m" (tmp.d) : "fr0"); \
|
fr = u.d; \
|
||||||
tmp.d = 0; \
|
__asm__ ("mtfsf 255,%0" : : "f" (fr)); \
|
||||||
__asm__("lfd%U0 0,%0" : : "m" (tmp.d) : "fr0"); \
|
fr = 0.0; \
|
||||||
}
|
}
|
||||||
|
|
||||||
void prime_special_regs(int which)
|
void prime_special_regs(int which)
|
||||||
|
@ -93,21 +93,25 @@ extern fpu_control_t __fpu_control;
|
|||||||
# define _FPU_IEEE 0x000000f0
|
# define _FPU_IEEE 0x000000f0
|
||||||
|
|
||||||
/* Type of the control word. */
|
/* Type of the control word. */
|
||||||
typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
|
typedef unsigned int fpu_control_t;
|
||||||
|
|
||||||
/* Macros for accessing the hardware control word. */
|
/* Macros for accessing the hardware control word. */
|
||||||
# define _FPU_GETCW(cw) ( { \
|
# define _FPU_GETCW(cw) \
|
||||||
union { double __d; fpu_control_t __cw[2]; } \
|
({union { double __d; unsigned long long __ll; } __u; \
|
||||||
__tmp __attribute__ ((__aligned__(8))); \
|
register double __fr; \
|
||||||
__asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (__tmp.__d) : : "fr0"); \
|
__asm__ ("mffs %0" : "=f" (__fr)); \
|
||||||
(cw) = __tmp.__cw[1]; \
|
__u.__d = __fr; \
|
||||||
__tmp.__cw[1]; } )
|
(cw) = (fpu_control_t) __u.__ll; \
|
||||||
# define _FPU_SETCW(cw) { \
|
(fpu_control_t) __u.__ll; \
|
||||||
union { double __d; fpu_control_t __cw[2]; } \
|
})
|
||||||
__tmp __attribute__ ((__aligned__(8))); \
|
|
||||||
__tmp.__cw[0] = 0xFFF80000; /* More-or-less arbitrary; this is a QNaN. */ \
|
# define _FPU_SETCW(cw) \
|
||||||
__tmp.__cw[1] = (cw); \
|
{ union { double __d; unsigned long long __ll; } __u; \
|
||||||
__asm__ ("lfd%U0 0,%0; mtfsf 255,0" : : "m" (__tmp.__d) : "fr0"); \
|
register double __fr; \
|
||||||
|
__u.__ll = 0xfff80000LL << 32; /* This is a QNaN. */ \
|
||||||
|
__u.__ll |= (cw) & 0xffffffffLL; \
|
||||||
|
__fr = __u.__d; \
|
||||||
|
__asm__ ("mtfsf 255,%0" : : "f" (__fr)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Default control word set at startup. */
|
/* Default control word set at startup. */
|
||||||
|
Loading…
Reference in New Issue
Block a user