* config/rs6000/rs6000.h (LONG_DOUBLE_LARGE_FIRST): Define.
authoramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 13 Jun 2013 03:22:20 +0000 (03:22 +0000)
committeramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 13 Jun 2013 03:22:20 +0000 (03:22 +0000)
* config/rs6000/rs6000.md (signbittf2): New insn.
(extenddftf2_internal): Use LONG_DOUBLE_LARGE_FIRST.
(abstf2_internal, cmptf_internal2): Likewise.
* config/rs6000/spe.md (spe_abstf2_cmp, spe_abstf2_tst): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@200055 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md
gcc/config/rs6000/spe.md

index 83ccd25..21d85fa 100644 (file)
@@ -1,3 +1,11 @@
+2013-06-13  Alan Modra  <amodra@gmail.com>
+
+       * config/rs6000/rs6000.h (LONG_DOUBLE_LARGE_FIRST): Define.
+       * config/rs6000/rs6000.md (signbittf2): New insn.
+       (extenddftf2_internal): Use LONG_DOUBLE_LARGE_FIRST.
+       (abstf2_internal, cmptf_internal2): Likewise.
+       * config/rs6000/spe.md (spe_abstf2_cmp, spe_abstf2_tst): Likewise.
+
 2013-06-12  Michael Meissner  <meissner@linux.vnet.ibm.com>
            Pat Haugen <pthaugen@us.ibm.com>
            Peter Bergner <bergner@vnet.ibm.com>
index e557350..021e72a 100644 (file)
@@ -715,6 +715,11 @@ extern unsigned char rs6000_recip_bits[];
    instructions for them.  Might as well be consistent with bits and bytes.  */
 #define WORDS_BIG_ENDIAN 1
 
+/* This says that for the IBM long double the larger magnitude double
+   comes first.  It's really a two element double array, and arrays
+   don't index differently between little- and big-endian.  */
+#define LONG_DOUBLE_LARGE_FIRST 1
+
 #define MAX_BITS_PER_WORD 64
 
 /* Width of a word, in units (bytes).  */
index 8be86a4..a0f462a 100644 (file)
   "frsqrtes %0,%1"
   [(set_attr "type" "fp")])
 
+;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
+;; builtins.c and optabs.c that are not correct for IBM long double
+;; when little-endian.
+(define_expand "signbittf2"
+  [(set (match_dup 2)
+       (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
+   (set (match_dup 3)
+       (subreg:DI (match_dup 2) 0))
+   (set (match_dup 4)
+       (match_dup 5))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (match_dup 6))]
+  "!TARGET_IEEEQUAD
+   && TARGET_HARD_FLOAT
+   && (TARGET_FPRS || TARGET_E500_DOUBLE)
+   && TARGET_LONG_DOUBLE_128"
+{
+  operands[2] = gen_reg_rtx (DFmode);
+  operands[3] = gen_reg_rtx (DImode);
+  if (TARGET_POWERPC64)
+    {
+      operands[4] = gen_reg_rtx (DImode);
+      operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
+      operands[6] = gen_rtx_SUBREG (SImode, operands[4],
+                                   WORDS_BIG_ENDIAN ? 4 : 0);
+    }
+  else
+    {
+      operands[4] = gen_reg_rtx (SImode);
+      operands[5] = gen_rtx_SUBREG (SImode, operands[3],
+                                   WORDS_BIG_ENDIAN ? 0 : 4);
+      operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
+    }
+})
+
 (define_expand "copysign<mode>3"
   [(set (match_dup 3)
         (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
   "&& reload_completed"
   [(pc)]
 {
-  const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
-  const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
+  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
+  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
   emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word),
                  operands[1]);
   emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word),
    && TARGET_LONG_DOUBLE_128"
   "
 {
-  const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
-  const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
+  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
+  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
   operands[3] = gen_reg_rtx (DFmode);
   operands[4] = gen_reg_rtx (CCFPmode);
   operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
    (match_dup 13)]
 {
   REAL_VALUE_TYPE rv;
-  const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
-  const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
+  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
+  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
 
   operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word);
   operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word);
index cec2b43..bf10a5d 100644 (file)
    && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128"
   "
 {
-  const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
-  const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
+  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
+  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
   operands[3] = gen_reg_rtx (DFmode);
   operands[4] = gen_reg_rtx (CCFPmode);
   operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
    && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128"
   "
 {
-  const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
-  const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
+  const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
+  const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
   operands[3] = gen_reg_rtx (DFmode);
   operands[4] = gen_reg_rtx (CCFPmode);
   operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);