rs6000.c (rs6000_override_options): Set real_format_for_mode for IBM extended format...
authorDavid Edelsohn <edelsohn@gnu.org>
Mon, 7 Oct 2002 19:12:04 +0000 (19:12 +0000)
committerDavid Edelsohn <dje@gcc.gnu.org>
Mon, 7 Oct 2002 19:12:04 +0000 (15:12 -0400)
        * config/rs6000/rs6000.c (rs6000_override_options): Set
        real_format_for_mode for IBM extended format, if enabled.
        (easy_fp_constant): Add TFmode.
        (rs6000_legitimize_address): Add TFmode.
        (rs6000_legitimate_address): Same.
        (function_arg_advance): TFmode uses two FPRs.
        (rs6000_emit_prologue): Fix warning.
        (rs6000_output_function_epilogue): Add TFmode.
        (output_toc): Add TFmode.
        * rs6000.h (SLOW_UNALIGNED_ACCESS): Add TFmode.
        (LEGITIMATE_OFFSET_ADDRESS_P): Add TFmode.
        * rs6000.md (movtf splitter): Load TFmode constant.

From-SVN: r57904

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

index adffbeb11cc9b4fa946a7139e3c0cb3f159dc0c3..558eaa7506cf4d0cfb3a048c27984125854cbd18 100644 (file)
@@ -1,4 +1,20 @@
+2002-10-07  David Edelsohn  <edelsohn@gnu.org>
+
+       * config/rs6000/rs6000.c (rs6000_override_options): Set
+       real_format_for_mode for IBM extended format, if enabled.
+       (easy_fp_constant): Add TFmode.
+       (rs6000_legitimize_address): Add TFmode.
+       (rs6000_legitimate_address): Same.
+       (function_arg_advance): TFmode uses two FPRs.
+       (rs6000_emit_prologue): Fix warning.
+       (rs6000_output_function_epilogue): Add TFmode.
+       (output_toc): Add TFmode.
+       * rs6000.h (SLOW_UNALIGNED_ACCESS): Add TFmode.
+       (LEGITIMATE_OFFSET_ADDRESS_P): Add TFmode.
+       * rs6000.md (movtf splitter): Load TFmode constant.
+
 2002-10-07  Dale Johannesen  <dalej@apple.com>
+
        * rtl.h:  Add NOTE_PRECONDITIONED.
        * unroll.c:  Set it.
        * loop.c:  Set loop_info->preconditioned from it.
index b293cc28ccb80f75740daf8de4339e2d098d0434..53b7a9b5e3c936f2986f180d3ef21630fd171a8f 100644 (file)
@@ -683,6 +683,10 @@ rs6000_override_options (default_cpu)
        target_flags |= MASK_AIX_STRUCT_RET;
     }
 
+  if (TARGET_LONG_DOUBLE_128
+      && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN))
+    real_format_for_mode[TFmode - QFmode] = &ibm_extended_format;
+
   /* Register global variables with the garbage collector.  */
   rs6000_add_gc_roots ();
 
@@ -1306,7 +1310,21 @@ easy_fp_constant (op, mode)
     return 0;
 #endif
 
-  if (mode == DFmode)
+  if (mode == TFmode)
+    {
+      long k[4];
+      REAL_VALUE_TYPE rv;
+
+      REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
+      REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
+
+      return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
+             && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1
+             && num_insns_constant_wide ((HOST_WIDE_INT) k[2]) == 1
+             && num_insns_constant_wide ((HOST_WIDE_INT) k[3]) == 1);
+    }
+
+  else if (mode == DFmode)
     {
       long k[2];
       REAL_VALUE_TYPE rv;
@@ -2095,7 +2113,7 @@ rs6000_legitimize_address (x, oldx, mode)
           && GET_MODE_NUNITS (mode) == 1
           && ((TARGET_HARD_FLOAT && TARGET_FPRS)
               || TARGET_POWERPC64
-              || mode != DFmode)
+              || (mode != DFmode && mode != TFmode))
           && (TARGET_POWERPC64 || mode != DImode)
           && mode != TImode)
     {
@@ -2348,7 +2366,7 @@ rs6000_legitimate_address (mode, x, reg_ok_strict)
   if (mode != TImode
       && ((TARGET_HARD_FLOAT && TARGET_FPRS)
          || TARGET_POWERPC64
-         || mode != DFmode)
+         || (mode != DFmode && mode != TFmode))
       && (TARGET_POWERPC64 || mode != DImode)
       && LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
     return 1;
@@ -3026,7 +3044,7 @@ function_arg_advance (cum, mode, type, named)
 
       if (GET_MODE_CLASS (mode) == MODE_FLOAT
          && TARGET_HARD_FLOAT && TARGET_FPRS)
-       cum->fregno++;
+       cum->fregno += (mode == TFmode ? 2 : 1);
 
       if (TARGET_DEBUG_ARG)
        {
@@ -10453,21 +10471,21 @@ rs6000_emit_prologue ()
                      gen_rtx_REG (Pmode, 11));
   }
 
+#if TARGET_MACHO
   if (DEFAULT_ABI == ABI_DARWIN
       && flag_pic && current_function_uses_pic_offset_table)
     {
       rtx dest = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
-#if TARGET_MACHO
       char *picbase = machopic_function_base_name ();
       rtx src = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (picbase, -1));
 
       rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (dest, src)));
-#endif
 
       rs6000_maybe_dead (
        emit_move_insn (gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM),
                        gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)));
     }
+#endif
 }
 
 /* Write function prologue.  */
@@ -11085,7 +11103,7 @@ rs6000_output_function_epilogue (file, size)
 
                      if (mode == SFmode)
                        bits = 0x2;
-                     else if (mode == DFmode)
+                     else if (mode == DFmode || mode == TFmode)
                        bits = 0x3;
                      else
                        abort ();
@@ -11639,7 +11657,42 @@ output_toc (file, x, labelno, mode)
   /* Handle FP constants specially.  Note that if we have a minimal
      TOC, things we put here aren't actually in the TOC, so we can allow
      FP constants.  */
-  if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
+  if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == TFmode)
+    {
+      REAL_VALUE_TYPE rv;
+      long k[4];
+
+      REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
+      REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
+
+      if (TARGET_64BIT)
+       {
+         if (TARGET_MINIMAL_TOC)
+           fputs (DOUBLE_INT_ASM_OP, file);
+         else
+           fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
+                    k[0] & 0xffffffff, k[1] & 0xffffffff,
+                    k[2] & 0xffffffff, k[3] & 0xffffffff);
+         fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
+                  k[0] & 0xffffffff, k[1] & 0xffffffff,
+                  k[2] & 0xffffffff, k[3] & 0xffffffff);
+         return;
+       }
+      else
+       {
+         if (TARGET_MINIMAL_TOC)
+           fputs ("\t.long ", file);
+         else
+           fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
+                    k[0] & 0xffffffff, k[1] & 0xffffffff,
+                    k[2] & 0xffffffff, k[3] & 0xffffffff);
+         fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
+                  k[0] & 0xffffffff, k[1] & 0xffffffff,
+                  k[2] & 0xffffffff, k[3] & 0xffffffff);
+         return;
+       }
+    }
+  else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
     {
       REAL_VALUE_TYPE rv;
       long k[2];
index d1d84ef24db0175a663ce45f628dfef4d811c497..7f4139be88d0803302b261a595cbc7878e524c8b 100644 (file)
@@ -660,7 +660,8 @@ extern int rs6000_default_long_calls;
    emulated in a trap handler.  */
 #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN)                             \
   (STRICT_ALIGNMENT                                                    \
-   || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode)      \
+   || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == TFmode       \
+       || (MODE) == DImode)                                            \
        && (ALIGN) < 32))
 \f
 /* Standard register usage.  */
@@ -2073,7 +2074,7 @@ typedef struct rs6000_args
       || (TARGET_32BIT                                         \
          ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4)       \
          : ! (INTVAL (XEXP (X, 1)) & 3)))                      \
-  && ((MODE) != TImode                                         \
+  && (((MODE) != TFmode && (MODE) != TImode)                   \
       || (TARGET_32BIT                                         \
          ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12)      \
          : (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8)      \
index 91fa56c763729740c4d4f5f5ac31fe92ff682efe..13adeca14b0787eaa162e1396921a7aa5d609f87 100644 (file)
    #"
   [(set_attr "type" "compare")
    (set_attr "length" "4,8")])
-\f
+
 (define_split
   [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
        (compare:CC
        (compare:CC (match_dup 0)
                    (const_int 0)))]
   "")
-
+\f
 ;; Rotate and shift insns, in all their variants.  These support shifts,
 ;; field inserts and extracts, and various combinations thereof.
 (define_expand "insv"
 (define_split
   [(set (match_operand:TF 0 "gpc_reg_operand" "")
        (match_operand:TF 1 "const_double_operand" ""))]
-  "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
-   && TARGET_LONG_DOUBLE_128"
-  [(set (match_dup 3) (match_dup 1))
-   (set (match_dup 0)
-       (float_extend:TF (match_dup 3)))]
+  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+   && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_POWERPC64
+   && TARGET_LONG_DOUBLE_128 && reload_completed
+   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
+       || (GET_CODE (operands[0]) == SUBREG
+          && GET_CODE (SUBREG_REG (operands[0])) == REG
+          && REGNO (SUBREG_REG (operands[0])) <= 31))"
+  [(set (match_dup 2) (match_dup 6))
+   (set (match_dup 3) (match_dup 7))
+   (set (match_dup 4) (match_dup 8))
+   (set (match_dup 5) (match_dup 9))]
+  "
+{
+  long l[4];
+  REAL_VALUE_TYPE rv;
+
+  REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+  REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l);
+
+  operands[2] = operand_subword (operands[0], 0, 0, TFmode);
+  operands[3] = operand_subword (operands[0], 1, 0, TFmode);
+  operands[4] = operand_subword (operands[0], 2, 0, TFmode);
+  operands[5] = operand_subword (operands[0], 3, 0, TFmode);
+  operands[6] = gen_int_mode (l[0], SImode);
+  operands[7] = gen_int_mode (l[1], SImode);
+  operands[8] = gen_int_mode (l[2], SImode);
+  operands[9] = gen_int_mode (l[3], SImode);
+}")
+
+(define_split
+  [(set (match_operand:TF 0 "gpc_reg_operand" "")
+       (match_operand:TF 1 "easy_fp_constant" ""))]
+  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
+   && TARGET_LONG_DOUBLE_128 && reload_completed
+   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
+       || (GET_CODE (operands[0]) == SUBREG
+          && GET_CODE (SUBREG_REG (operands[0])) == REG
+          && REGNO (SUBREG_REG (operands[0])) <= 31))"
+  [(set (match_dup 2) (match_dup 4))
+   (set (match_dup 3) (match_dup 5))]
   "
 {
-  operands[2] = operand_subword (operands[1], 0, 0, DFmode);
-  operands[3] = gen_reg_rtx (DFmode);
+  long l[4];
+  REAL_VALUE_TYPE rv;
+
+  REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+  REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l);
+
+  operands[2] = operand_subword (operands[0], 0, 0, TFmode);
+  operands[3] = operand_subword (operands[0], 1, 0, TFmode);
+  operands[4] = gen_int_mode (l[0], DImode);
+  operands[5] = gen_int_mode (l[1], DImode);
 }")
 
 (define_insn_and_split "extenddftf2"