rs6000.c (rs6000_emit_eh_toc_restore): Remove ALIGN parm.
authorDavid Edelsohn <edelsohn@gnu.org>
Tue, 20 Nov 2001 16:13:07 +0000 (16:13 +0000)
committerDavid Edelsohn <dje@gcc.gnu.org>
Tue, 20 Nov 2001 16:13:07 +0000 (11:13 -0500)
        * rs6000.c (rs6000_emit_eh_toc_restore): Remove ALIGN parm.

        * rs6000.c (rs6000_emit_move): Add TFmode case.
        * sysv4.h (MASK_LONG_DOUBLE_128, TARGET_LONG_DOUBLE_128,
        LONG_DOUBLE_TYPE_SIZE, MAX_LONG_DOUBLE_TYPE_SIZE,
        LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Move from here...
        * rs6000.h: ... to here.
        * rs6000.md (movtf, extenddftf2, extendsftf2, trunctfdf2,
        trunctfsf2, floatditf2, floatsitf2, fix_trunctfdi2,
        fix_trunctfsi2, negtf2, abstf2, nabstf2): New patterns.

From-SVN: r47218

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

index f5325dcf8a7189688c75e877b5b66af32ed705ae..96e01267ac94d5daf8353ebd5581c0041b2a16a0 100644 (file)
@@ -1,3 +1,16 @@
+2001-11-20  David Edelsohn  <edelsohn@gnu.org>
+
+       * rs6000.c (rs6000_emit_eh_toc_restore): Remove ALIGN parm.
+
+       * rs6000.c (rs6000_emit_move): Add TFmode case.
+       * sysv4.h (MASK_LONG_DOUBLE_128, TARGET_LONG_DOUBLE_128,
+       LONG_DOUBLE_TYPE_SIZE, MAX_LONG_DOUBLE_TYPE_SIZE,
+       LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Move from here...
+       * rs6000.h: ... to here.
+       * rs6000.md (movtf, extenddftf2, extendsftf2, trunctfdf2,
+       trunctfsf2, floatditf2, floatsitf2, fix_trunctfdi2,
+       fix_trunctfsi2, negtf2, abstf2, nabstf2): New patterns.
+
 Tue Nov 20 06:41:38 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
        * emit-rtl.c (get_mem_attrs): Fix typo.
index 186692db38cc49292d2da10e0ad7573b9a43b420..d9b3e0902ec42096fc407e1b1d7c56fb33dd06f1 100644 (file)
@@ -1935,6 +1935,7 @@ rs6000_emit_move (dest, source, mode)
        operands[1] = force_const_mem (mode, operands[1]);
       break;
 
+    case TFmode:
     case DFmode:
     case SFmode:
       if (CONSTANT_P (operands[1]) 
@@ -6594,7 +6595,7 @@ rs6000_emit_eh_toc_restore (stacksize)
   emit_label (loop_start);
   
   do_compare_rtx_and_jump (opcode, tocompare, NE, 1,
-                          SImode, NULL_RTX, 0, NULL_RTX,
+                          SImode, NULL_RTX, NULL_RTX,
                           no_toc_restore_needed);
   
   mem = gen_rtx_MEM (Pmode, 
@@ -6604,7 +6605,7 @@ rs6000_emit_eh_toc_restore (stacksize)
 
   emit_label (no_toc_restore_needed);
   do_compare_rtx_and_jump (top_of_stack, bottom_of_stack, EQ, 1,
-                          Pmode, NULL_RTX, 0, NULL_RTX,
+                          Pmode, NULL_RTX, NULL_RTX,
                           loop_exit);
 
   mem = gen_rtx_MEM (Pmode, bottom_of_stack);
index 238cedc456217bcda1b37cc0e5295bb71d4f8fc0..94aa09e8b9382b228f5400b677a366109b15cb55 100644 (file)
@@ -217,6 +217,9 @@ extern int target_flags;
 /* Enhance the current ABI with AltiVec extensions.  */
 #define MASK_ALTIVEC_ABI       0x00100000
 
+/* Use 128-bit long double.  */
+#define MASK_LONG_DOUBLE_128   0x00200000
+
 #define TARGET_POWER           (target_flags & MASK_POWER)
 #define TARGET_POWER2          (target_flags & MASK_POWER2)
 #define TARGET_POWERPC         (target_flags & MASK_POWERPC)
@@ -237,6 +240,7 @@ extern int target_flags;
 #define TARGET_SCHED_PROLOG    (target_flags & MASK_SCHED_PROLOG)
 #define TARGET_ALTIVEC         (target_flags & MASK_ALTIVEC)
 #define TARGET_ALTIVEC_ABI     (target_flags & MASK_ALTIVEC_ABI)
+#define TARGET_LONG_DOUBLE_128 (target_flags & MASK_LONG_DOUBLE_128)
 
 #define TARGET_32BIT           (! TARGET_64BIT)
 #define TARGET_HARD_FLOAT      (! TARGET_SOFT_FLOAT)
@@ -341,6 +345,10 @@ extern int target_flags;
                        N_("Generate fused multiply/add instructions")},\
   {"no-fused-madd",    MASK_NO_FUSED_MADD,                             \
                        N_("Don't generate fused multiply/add instructions")},\
+  {"long-double-64",   -MASK_LONG_DOUBLE_128,                          \
+                       N_("Use 64 bit long doubles") },                \
+  {"long-double-128",   MASK_LONG_DOUBLE_128,                          \
+                       N_("Use 128 bit long doubles") },               \
   {"sched-prolog",      MASK_SCHED_PROLOG,                              \
                        ""},                                            \
   {"no-sched-prolog",   -MASK_SCHED_PROLOG,                             \
@@ -576,7 +584,18 @@ extern int rs6000_debug_arg;               /* debug argument handling */
 /* A C expression for the size in bits of the type `long double' on
    the target machine.  If you don't define this, the default is two
    words.  */
-#define LONG_DOUBLE_TYPE_SIZE 64
+#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
+
+/* Constant which presents upper bound of the above value.  */
+#define MAX_LONG_DOUBLE_TYPE_SIZE 128
+
+/* Define this to set long double type size to use in libgcc2.c, which can
+   not depend on target_flags.  */
+#ifdef __LONG_DOUBLE_128__
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128
+#else
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
+#endif
 
 /* Width in bits of a pointer.
    See also the macro `Pmode' defined below.  */
index 6b8dda70683dd2919597ae2022341a2d33834a84..0292c57ec452e01f95549af5db4e24628ac791b2 100644 (file)
   [(set_attr "type" "*,load,store,*,*,*")
    (set_attr "length" "*,*,*,8,12,16")])
 \f
+(define_expand "movtf"
+  [(set (match_operand:TF 0 "general_operand" "")
+       (match_operand:TF 1 "any_operand" ""))]
+  "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+  "{ rs6000_emit_move (operands[0], operands[1], TFmode); DONE; }")
+
+(define_insn "*movtf_internal"
+  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,m,!r,!r,!r")
+       (match_operand:TF 1 "input_operand" "f,m,f,G,H,F"))]
+  "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128
+   && (gpc_reg_operand (operands[0], TFmode)
+       || gpc_reg_operand (operands[1], TFmode))"
+  "*
+{
+  switch (which_alternative)
+    {
+    default:
+      abort ();
+    case 0:
+      /* We normally copy the low-numbered register first.  However, if
+        the first register operand 0 is the same as the second register of
+        operand 1, we must copy in the opposite order.  */
+      if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+       return \"fmr %L0,%L1\;fmr %0,%1\";
+      else
+       return \"fmr %0,%1\;fmr %L0,%L1\";
+    case 1:
+      return \"lfd %0,%1\;lfd %L0,%L1\";
+    case 2:
+      return \"stfd %1,%0\;stfd %L1,%L0\";
+    case 3:
+    case 4:
+    case 5:
+      return \"#\";
+    }
+}"
+  [(set_attr "type" "fp,fpload,fpstore,*,*,*")
+   (set_attr "length" "8,8,8,12,16,20")])
+
+(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_LONG_DOUBLE_128"
+  [(set (match_dup 3) (match_dup 1))
+   (set (match_dup 0)
+       (float_extend:TF (match_dup 3)))]
+  "
+{
+  operands[2] = operand_subword (operands[1], 0, 0, DFmode);
+  operands[3] = gen_reg_rtx (DFmode);
+}")
+
+(define_insn_and_split "extenddftf2"
+  [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
+       (float_extend:TF (match_operand:DF 1 "gpc_reg_operand" "f")))]
+  "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+  "#"
+  ""
+  [(set (match_dup 2) (match_dup 3))]
+  "
+{
+  operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0] + 1));
+  operands[3] = CONST0_RTX (DFmode);
+}")
+
+(define_insn_and_split "extendsftf2"
+  [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
+       (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "f")))]
+  "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+  "#"
+  ""
+  [(set (match_dup 2) (match_dup 3))]
+  "
+{
+  operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0] + 1));
+  operands[3] = CONST0_RTX (SFmode);
+}")
+
+(define_insn "trunctfdf2"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+       (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))]
+  "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+  "fadd %0,%1,%L1"
+  [(set_attr "type" "fp")
+   (set_attr "length" "8")])
+
+(define_insn_and_split "trunctfsf2"
+  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+       (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f")))]
+  "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+  "#"
+  ""
+  [(set (match_dup 2)
+       (float_truncate:DF (match_dup 1)))
+   (set (match_dup 0)
+       (float_truncate:SF (match_dup 2)))]
+  "
+{
+  operands[2] = gen_reg_rtx (DFmode);
+}")
+
+(define_expand "floatditf2"
+  [(set (match_dup 2)
+       (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))
+   (set (match_operand:TF 0 "gpc_reg_operand" "")
+       (float_extend:TF (match_dup 2)))]
+  "DEFAULT_ABI == ABI_AIX && TARGET_POWERPC64
+   && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+  "{ operands[2] = gen_reg_rtx (DFmode); }")
+
+(define_expand "floatsitf2"
+  [(set (match_dup 2)
+       (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
+   (set (match_operand:TF 0 "gpc_reg_operand" "")
+       (float_extend:TF (match_dup 2)))]
+  "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+  "{ operands[2] = gen_reg_rtx (DFmode); }")
+
+(define_expand "fix_trunctfdi2"
+  [(set (match_dup 2)
+       (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
+   (set (match_operand:DI 0 "gpc_reg_operand" "")
+       (fix:SI (match_dup 2)))]
+  "DEFAULT_ABI == ABI_AIX && TARGET_POWERPC64
+   && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+  "{ operands[2] = gen_reg_rtx (DFmode); }")
+
+(define_expand "fix_trunctfsi2"
+  [(set (match_dup 2)
+       (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
+   (set (match_operand:SI 0 "gpc_reg_operand" "")
+       (fix:SI (match_dup 2)))]
+  "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+  "{ operands[2] = gen_reg_rtx (DFmode); }")
+
+(define_insn "negtf2"
+  [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
+       (neg:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
+  "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+  "*
+{
+  if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+    return \"fneg %L0,%L1\;fneg %0,%1\";
+  else
+    return \"fneg %0,%1\;fneg %L0,%L1\";
+}"
+  [(set_attr "type" "fp")
+   (set_attr "length" "8")])
+
+(define_insn "abstf2"
+  [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
+       (abs:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
+  "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+  "*
+{
+  if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+    return \"fabs %L0,%L1\;fabs %0,%1\";
+  else
+    return \"fabs %0,%1\;fabs %L0,%L1\";
+}"
+  [(set_attr "type" "fp")
+   (set_attr "length" "8")])
+
+(define_insn ""
+  [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
+       (neg:TF (abs:TF (match_operand:TF 1 "gpc_reg_operand" "f"))))]
+  "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
+  "*
+{
+  if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+    return \"fnabs %L0,%L1\;fnabs %0,%1\";
+  else
+    return \"fnabs %0,%1\;fnabs %L0,%L1\";
+}"
+  [(set_attr "type" "fp")
+   (set_attr "length" "8")])
+\f
 ;; Next come the multi-word integer load and store and the load and store
 ;; multiple insns.
 (define_expand "movdi"
index fcff961c90dbaa672958375d0a1952b0f7464658..99e4c27ba036ec0457c7af22d4e0f55171eaa96e 100644 (file)
@@ -56,8 +56,7 @@ extern enum rs6000_sdata_type rs6000_sdata;
 #define        MASK_LITTLE_ENDIAN      0x04000000      /* Target is little endian.  */
 #define        MASK_REGNAMES           0x02000000      /* Use alternate register names.  */
 #define        MASK_PROTOTYPE          0x01000000      /* Only prototyped fcns pass variable args.  */
-#define MASK_LONG_DOUBLE_128   0x00800000      /* Use IEEE quad long double.  */
-#define MASK_NO_BITFIELD_WORD  0x00400000      /* Bitfields cannot cross word boundaries */
+#define MASK_NO_BITFIELD_WORD  0x00800000      /* Bitfields cannot cross word boundaries */
 
 #define        TARGET_NO_BITFIELD_TYPE (target_flags & MASK_NO_BITFIELD_TYPE)
 #define        TARGET_STRICT_ALIGN     (target_flags & MASK_STRICT_ALIGN)
@@ -66,7 +65,6 @@ extern enum rs6000_sdata_type rs6000_sdata;
 #define        TARGET_LITTLE_ENDIAN    (target_flags & MASK_LITTLE_ENDIAN)
 #define        TARGET_REGNAMES         (target_flags & MASK_REGNAMES)
 #define        TARGET_PROTOTYPE        (target_flags & MASK_PROTOTYPE)
-#define TARGET_LONG_DOUBLE_128 (target_flags & MASK_LONG_DOUBLE_128)
 #define TARGET_NO_BITFIELD_WORD        (target_flags & MASK_NO_BITFIELD_WORD)
 #define        TARGET_TOC              ((target_flags & MASK_64BIT)            \
                                 || ((target_flags & (MASK_RELOCATABLE  \
@@ -126,10 +124,6 @@ extern int g_switch_set;           /* Whether -G xx was passed.  */
     N_("Produce big endian code.") },                                  \
   { "big",             -MASK_LITTLE_ENDIAN,                            \
     N_("Produce big endian code.") },                                  \
-  { "long-double-64",  -MASK_LONG_DOUBLE_128,                          \
-    N_("Use 64 bit long doubles") },                                   \
-  { "long-double-128",  MASK_LONG_DOUBLE_128,                          \
-    N_("Use 128 bit long doubles") },                                  \
   { "no-toc",           0, N_("no description yet") },                 \
   { "toc",              MASK_MINIMAL_TOC, N_("no description yet") },  \
   { "full-toc",                 MASK_MINIMAL_TOC, N_("no description yet") },  \
@@ -366,22 +360,6 @@ do {                                                                       \
 #undef WCHAR_TYPE_SIZE
 #define WCHAR_TYPE_SIZE 32
 
-/* Define for support of TFmode long double and REAL_ARITHMETIC.
-   PowerPC SVR4 ABI says that long double is 4 words.  */
-#undef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
-
-/* Constant which presents upper bound of the above value.  */
-#define MAX_LONG_DOUBLE_TYPE_SIZE 128
-
-/* Define this to set long double type size to use in libgcc2.c, which can
-   not depend on target_flags.  */
-#ifdef __LONG_DOUBLE_128__
-#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128
-#else
-#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
-#endif
-
 /* Make int foo : 8 not cause structures to be aligned to an int boundary.  */
 /* Override elfos.h definition.  */
 #undef PCC_BITFIELD_TYPE_MATTERS