From 7b88401f3b25325b1381798a0eccb3efe7751fec Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sat, 17 Aug 2013 18:31:45 +0930 Subject: [PATCH] PowerPC floating point little-endian [12 of 15] http://sourceware.org/ml/libc-alpha/2013-08/msg00087.html Fixes for little-endian in 32-bit assembly. * sysdeps/powerpc/sysdep.h (LOWORD, HIWORD, HISHORT): Define. * sysdeps/powerpc/powerpc32/fpu/s_copysign.S: Load little-endian words of double from correct stack offsets. * sysdeps/powerpc/powerpc32/fpu/s_copysignl.S: Likewise. * sysdeps/powerpc/powerpc32/fpu/s_lrint.S: Likewise. * sysdeps/powerpc/powerpc32/fpu/s_lround.S: Likewise. * sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S: Likewise. * sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S: Likewise. * sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S: Likewise. * sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S: Likewise. * sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S: Likewise. * sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S: Likewise. * sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S: Likewise. * sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S: Likewise. * sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S: Likewise. * sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S: Likewise. * sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S: Likewise. * sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S: Likewise. * sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S: Use HISHORT. * sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S: Likewise. --- ChangeLog | 23 +++++++++++++++++++++++ sysdeps/powerpc/powerpc32/fpu/s_copysign.S | 2 +- sysdeps/powerpc/powerpc32/fpu/s_copysignl.S | 2 +- sysdeps/powerpc/powerpc32/fpu/s_lrint.S | 4 ++-- sysdeps/powerpc/powerpc32/fpu/s_lround.S | 2 +- sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S | 4 ++-- sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S | 4 ++-- sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S | 4 ++-- sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S | 2 +- sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S | 4 ++-- sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S | 4 ++-- sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S | 4 ++-- sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S | 4 ++-- sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S | 4 ++-- sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S | 5 ++--- sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S | 7 +++---- sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S | 4 ++-- sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S | 6 ++---- sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S | 5 ++--- sysdeps/powerpc/sysdep.h | 15 +++++++++++++++ 20 files changed, 71 insertions(+), 38 deletions(-) diff --git a/ChangeLog b/ChangeLog index cdee05c..10c2e80 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,28 @@ 2013-10-04 Alan Modra + * sysdeps/powerpc/sysdep.h (LOWORD, HIWORD, HISHORT): Define. + * sysdeps/powerpc/powerpc32/fpu/s_copysign.S: Load little-endian + words of double from correct stack offsets. + * sysdeps/powerpc/powerpc32/fpu/s_copysignl.S: Likewise. + * sysdeps/powerpc/powerpc32/fpu/s_lrint.S: Likewise. + * sysdeps/powerpc/powerpc32/fpu/s_lround.S: Likewise. + * sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S: Likewise. + * sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S: Likewise. + * sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S: Likewise. + * sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S: Likewise. + * sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S: Likewise. + * sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S: Likewise. + * sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S: Likewise. + * sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S: Likewise. + * sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S: Likewise. + * sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S: Likewise. + * sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S: Likewise. + * sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S: Likewise. + * sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S: Use HISHORT. + * sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S: Likewise. + +2013-10-04 Alan Modra + * sysdeps/powerpc/fpu_control.h (_FPU_GETCW): Rewrite using 64-bit int/double union. (_FPU_SETCW): Likewise. diff --git a/sysdeps/powerpc/powerpc32/fpu/s_copysign.S b/sysdeps/powerpc/powerpc32/fpu/s_copysign.S index 840891f..1da24f4 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_copysign.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_copysign.S @@ -29,7 +29,7 @@ ENTRY(__copysign) stwu r1,-16(r1) cfi_adjust_cfa_offset (16) stfd fp2,8(r1) - lwz r3,8(r1) + lwz r3,8+HIWORD(r1) cmpwi r3,0 addi r1,r1,16 cfi_adjust_cfa_offset (-16) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S b/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S index 4ec8389..2ad6de2 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S @@ -30,7 +30,7 @@ ENTRY(__copysignl) fmr fp0,fp1 fabs fp1,fp1 fcmpu cr7,fp0,fp1 - lwz r3,8(r1) + lwz r3,8+HIWORD(r1) cmpwi cr6,r3,0 addi r1,r1,16 cfi_adjust_cfa_offset (-16) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_lrint.S b/sysdeps/powerpc/powerpc32/fpu/s_lrint.S index 27881f8..249fda5 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_lrint.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_lrint.S @@ -24,10 +24,10 @@ ENTRY (__lrint) stwu r1,-16(r1) fctiw fp13,fp1 stfd fp13,8(r1) - nop /* Insure the following load is in a different dispatch group */ + nop /* Ensure the following load is in a different dispatch group */ nop /* to avoid pipe stall on POWER4&5. */ nop - lwz r3,12(r1) + lwz r3,8+LOWORD(r1) addi r1,r1,16 blr END (__lrint) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_lround.S b/sysdeps/powerpc/powerpc32/fpu/s_lround.S index 92dc378..6309f86 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_lround.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_lround.S @@ -67,7 +67,7 @@ ENTRY (__lround) nop /* Ensure the following load is in a different dispatch */ nop /* group to avoid pipe stall on POWER4&5. */ nop - lwz r3,12(r1) /* Load return as integer. */ + lwz r3,8+LOWORD(r1) /* Load return as integer. */ .Lout: addi r1,r1,16 blr diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S b/sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S index 55b2850..e7a88fe 100644 --- a/sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S +++ b/sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S @@ -29,8 +29,8 @@ ENTRY (__llrint) nop /* Insure the following load is in a different dispatch group */ nop /* to avoid pipe stall on POWER4&5. */ nop - lwz r3,8(r1) - lwz r4,12(r1) + lwz r3,8+HIWORD(r1) + lwz r4,8+LOWORD(r1) addi r1,r1,16 blr END (__llrint) diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S b/sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S index cc80fcb..da24ad3 100644 --- a/sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S +++ b/sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S @@ -28,8 +28,8 @@ ENTRY (__llrintf) nop /* Insure the following load is in a different dispatch group */ nop /* to avoid pipe stall on POWER4&5. */ nop - lwz r3,8(r1) - lwz r4,12(r1) + lwz r3,8+HIWORD(r1) + lwz r4,8+LOWORD(r1) addi r1,r1,16 blr END (__llrintf) diff --git a/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S b/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S index ecd37c3..49c8a08 100644 --- a/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S +++ b/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S @@ -39,8 +39,8 @@ ENTRY (__llround) nop /* Ensure the following load is in a different dispatch */ nop /* group to avoid pipe stall on POWER4&5. */ nop - lwz r4,12(r1) - lwz r3,8(r1) + lwz r3,8+HIWORD(r1) + lwz r4,8+LOWORD(r1) addi r1,r1,16 blr END (__llround) diff --git a/sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S b/sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S index d4da625..780dd9c 100644 --- a/sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S +++ b/sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S @@ -38,7 +38,7 @@ ENTRY (__lround) nop /* Ensure the following load is in a different dispatch */ nop /* group to avoid pipe stall on POWER4&5. */ nop - lwz r3,12(r1) + lwz r3,8+LOWORD(r1) addi r1,r1,16 blr END (__lround) diff --git a/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S b/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S index f2417fd..5f7ba43 100644 --- a/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S +++ b/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S @@ -27,8 +27,8 @@ EALIGN (__isnan, 4, 0) ori r1,r1,0 stfd fp1,24(r1) /* copy FPR to GPR */ ori r1,r1,0 - lwz r4,24(r1) - lwz r5,28(r1) + lwz r4,24+HIWORD(r1) + lwz r5,24+LOWORD(r1) lis r0,0x7ff0 /* const long r0 0x7ff00000 00000000 */ clrlwi r4,r4,1 /* x = fabs(x) */ cmpw cr7,r4,r0 /* if (fabs(x) =< inf) */ diff --git a/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S b/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S index 2c095db..3ea1858 100644 --- a/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S +++ b/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S @@ -27,8 +27,8 @@ EALIGN (__isnan, 4, 0) ori r1,r1,0 stfd fp1,24(r1) /* copy FPR to GPR */ ori r1,r1,0 - lwz r4,24(r1) - lwz r5,28(r1) + lwz r4,24+HIWORD(r1) + lwz r5,24+LOWORD(r1) lis r0,0x7ff0 /* const long r0 0x7ff00000 00000000 */ clrlwi r4,r4,1 /* x = fabs(x) */ cmpw cr7,r4,r0 /* if (fabs(x) =< inf) */ diff --git a/sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S b/sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S index 3344b31..c0660cf 100644 --- a/sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S +++ b/sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S @@ -29,8 +29,8 @@ ENTRY (__llrint) /* Insure the following load is in a different dispatch group by inserting "group ending nop". */ ori r1,r1,0 - lwz r3,8(r1) - lwz r4,12(r1) + lwz r3,8+HIWORD(r1) + lwz r4,8+LOWORD(r1) addi r1,r1,16 blr END (__llrint) diff --git a/sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S b/sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S index 7f64f8d..ce29890 100644 --- a/sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S +++ b/sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S @@ -28,8 +28,8 @@ ENTRY (__llrintf) /* Insure the following load is in a different dispatch group by inserting "group ending nop". */ ori r1,r1,0 - lwz r3,8(r1) - lwz r4,12(r1) + lwz r3,8+HIWORD(r1) + lwz r4,8+LOWORD(r1) addi r1,r1,16 blr END (__llrintf) diff --git a/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S b/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S index 0ff04cb..abb0840 100644 --- a/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S +++ b/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S @@ -39,8 +39,8 @@ ENTRY (__llround) /* Insure the following load is in a different dispatch group by inserting "group ending nop". */ ori r1,r1,0 - lwz r4,12(r1) - lwz r3,8(r1) + lwz r3,8+HIWORD(r1) + lwz r4,8+LOWORD(r1) addi r1,r1,16 blr END (__llround) diff --git a/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S b/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S index b2ab5bf..095c155 100644 --- a/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S +++ b/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S @@ -54,9 +54,8 @@ ENTRY (__finite) stfd fp1,8(r1) /* Transfer FP to GPR's. */ ori 2,2,0 /* Force a new dispatch group. */ - lhz r0,8(r1) /* Fetch the upper portion of the high word of - the FP value (where the exponent and sign bits - are). */ + lhz r0,8+HISHORT(r1) /* Fetch the upper 16 bits of the FP value + (biased exponent and sign bit). */ clrlwi r0,r0,17 /* r0 = abs(r0). */ addi r1,r1,16 /* Reset the stack pointer. */ cmpwi cr7,r0,0x7ff0 /* r4 == 0x7ff0?. */ diff --git a/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S b/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S index 3f8af60..0101c8f 100644 --- a/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S +++ b/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S @@ -48,14 +48,13 @@ ENTRY (__isinf) li r3,0 bflr 29 /* If not INF, return. */ - /* Either we have -INF/+INF or a denormal. */ + /* Either we have +INF or -INF. */ stwu r1,-16(r1) /* Allocate stack space. */ stfd fp1,8(r1) /* Transfer FP to GPR's. */ ori 2,2,0 /* Force a new dispatch group. */ - lhz r4,8(r1) /* Fetch the upper portion of the high word of - the FP value (where the exponent and sign bits - are). */ + lhz r4,8+HISHORT(r1) /* Fetch the upper 16 bits of the FP value + (biased exponent and sign bit). */ addi r1,r1,16 /* Reset the stack pointer. */ cmpwi cr7,r4,0x7ff0 /* r4 == 0x7ff0? */ li r3,1 diff --git a/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S b/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S index 99ff126..0ad1dcf 100644 --- a/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S +++ b/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S @@ -53,8 +53,8 @@ ENTRY (__isnan) stwu r1,-16(r1) /* Allocate stack space. */ stfd fp1,8(r1) /* Transfer FP to GPR's. */ ori 2,2,0 /* Force a new dispatch group. */ - lwz r4,8(r1) /* Load the upper half of the FP value. */ - lwz r5,12(r1) /* Load the lower half of the FP value. */ + lwz r4,8+HIWORD(r1) /* Load the upper half of the FP value. */ + lwz r5,8+LOWORD(r1) /* Load the lower half of the FP value. */ addi r1,r1,16 /* Reset the stack pointer. */ lis r0,0x7ff0 /* Load the upper portion for an INF/NaN. */ clrlwi r4,r4,1 /* r4 = abs(r4). */ diff --git a/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S b/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S index d0071c7..ebec0e0 100644 --- a/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S +++ b/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S @@ -39,10 +39,8 @@ EALIGN (__finite, 4, 0) stfd fp1,-16(r1) /* Transfer FP to GPR's. */ ori 2,2,0 /* Force a new dispatch group. */ - - lhz r4,-16(r1) /* Fetch the upper portion of the high word of - the FP value (where the exponent and sign bits - are). */ + lhz r4,-16+HISHORT(r1) /* Fetch the upper 16 bits of the FP value + (biased exponent and sign bit). */ clrlwi r4,r4,17 /* r4 = abs(r4). */ cmpwi cr7,r4,0x7ff0 /* r4 == 0x7ff0? */ bltlr cr7 /* LT means finite, other non-finite. */ diff --git a/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S b/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S index 1aea123..8d088db 100644 --- a/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S +++ b/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S @@ -38,9 +38,8 @@ EALIGN (__isinf, 4, 0) stfd fp1,-16(r1) /* Transfer FP to GPR's. */ ori 2,2,0 /* Force a new dispatch group. */ - lhz r4,-16(r1) /* Fetch the upper portion of the high word of - the FP value (where the exponent and sign bits - are). */ + lhz r4,-16+HISHORT(r1) /* Fetch the upper 16 bits of the FP value + (biased exponent and sign bit). */ cmpwi cr7,r4,0x7ff0 /* r4 == 0x7ff0? */ li r3,1 beqlr cr7 /* EQ means INF, otherwise -INF. */ diff --git a/sysdeps/powerpc/sysdep.h b/sysdeps/powerpc/sysdep.h index 1b5334a..bc2cb66 100644 --- a/sysdeps/powerpc/sysdep.h +++ b/sysdeps/powerpc/sysdep.h @@ -144,6 +144,21 @@ #define VRSAVE 256 +/* The 32-bit words of a 64-bit dword are at these offsets in memory. */ +#if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN +# define LOWORD 0 +# define HIWORD 4 +#else +# define LOWORD 4 +# define HIWORD 0 +#endif + +/* The high 16-bit word of a 64-bit dword is at this offset in memory. */ +#if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN +# define HISHORT 6 +#else +# define HISHORT 0 +#endif /* This seems to always be the case on PPC. */ #define ALIGNARG(log2) log2 -- 2.7.4