re PR target/19019 (GCC ldouble format incompatibility with XLC long double)
authorDavid Edelsohn <edelsohn@gnu.org>
Sun, 13 Feb 2005 21:31:35 +0000 (21:31 +0000)
committerDavid Edelsohn <dje@gcc.gnu.org>
Sun, 13 Feb 2005 21:31:35 +0000 (16:31 -0500)
        PR target/19019
        * config/rs6000/aix.h ({TARGET,MASK}_XL_CALL): Rename to
        {TARGET,MASK}_XL_COMPAT.
        (SUBTARGET_SWITCHES): Rename xl-call to xl-compat.  Use
        MASK_XL_COMPAT.
        * config/rs6000/beos.h ({TARGET,MASK}_XL_CALL): Remove.
        * config/rs6000/rs6000.c (function_arg): Change TARGET_XL_CALL to
        TARGET_XL_COMPAT.
        (rs6000_arg_partial_bytes): Same.
        (rs6000_generate_compare): Generate PARALLEL for compare if TFmode
        and XL compatibility enabled.
        * config/rs6000/rs6000.h (TARGET_XL_CALL): Rename to TARGET_XL_COMPAT.
        * config/rs6000/rs6000.md (cmptf_internal1): Add !TARGET_XL_COMPAT
        test to final condition.
        (cmptf_internal2): New.
        * doc/invoke.texi (RS/6000 Subtarget Options): Change xl-call to
        xl-compat.  Add TFmode information to description.

From-SVN: r94991

gcc/ChangeLog
gcc/config/rs6000/aix.h
gcc/config/rs6000/beos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md
gcc/doc/invoke.texi

index 0e873a8..697588c 100644 (file)
@@ -1,3 +1,23 @@
+2005-02-13  David Edelsohn  <edelsohn@gnu.org>
+
+       PR target/19019
+       * config/rs6000/aix.h ({TARGET,MASK}_XL_CALL): Rename to
+       {TARGET,MASK}_XL_COMPAT.
+       (SUBTARGET_SWITCHES): Rename xl-call to xl-compat.  Use
+       MASK_XL_COMPAT.
+       * config/rs6000/beos.h ({TARGET,MASK}_XL_CALL): Remove.
+       * config/rs6000/rs6000.c (function_arg): Change TARGET_XL_CALL to
+       TARGET_XL_COMPAT.
+       (rs6000_arg_partial_bytes): Same.
+       (rs6000_generate_compare): Generate PARALLEL for compare if TFmode
+       and XL compatibility enabled.
+       * config/rs6000/rs6000.h (TARGET_XL_CALL): Rename to TARGET_XL_COMPAT.
+       * config/rs6000/rs6000.md (cmptf_internal1): Add !TARGET_XL_COMPAT
+       test to final condition.
+       (cmptf_internal2): New.
+       * doc/invoke.texi (RS/6000 Subtarget Options): Change xl-call to
+       xl-compat.  Add TFmode information to description.
+
 2005-02-13  Kazu Hirata  <kazu@cs.umass.edu>
 
        * flags.h, read-rtl.c, tree-ssa-live.h: Update copyright.
index cb674c8..d8a0f69 100644 (file)
 #define JUMP_TABLES_IN_TEXT_SECTION 1
 
 /* Enable AIX XL compiler calling convention breakage compatibility.  */
-#undef TARGET_XL_CALL
-#define MASK_XL_CALL           0x40000000
-#define        TARGET_XL_CALL          (target_flags & MASK_XL_CALL)
+#undef TARGET_XL_COMPAT
+#define MASK_XL_COMPAT         0x40000000
+#define        TARGET_XL_COMPAT        (target_flags & MASK_XL_COMPAT)
 #undef  SUBTARGET_SWITCHES
 #define SUBTARGET_SWITCHES             \
-  {"xl-call",          MASK_XL_CALL,                                   \
-   N_("Always pass floating-point arguments in memory") },             \
-  {"no-xl-call",       - MASK_XL_CALL,                                 \
-   N_("Don't always pass floating-point arguments in memory") },       \
+  {"xl-compat",        MASK_XL_COMPAT,                                 \
+   N_("Conform more closely to IBM XLC semantics") },          \
+  {"no-xl-compat",     - MASK_XL_COMPAT,                                       \
+   N_("Default GCC semantics that differ from IBM XLC") },     \
   SUBSUBTARGET_SWITCHES
 #define SUBSUBTARGET_SWITCHES 
 
index 1ce36bf..a9e88ac 100644 (file)
 #undef  TARGET_VERSION
 #define TARGET_VERSION fprintf (stderr, " (BeOS/PowerPC)");
 
-/* Enable AIX XL compiler calling convention breakage compatibility.  */
-#define MASK_XL_CALL           0x40000000
-#define        TARGET_XL_CALL          (target_flags & MASK_XL_CALL)
-#undef  SUBTARGET_SWITCHES
-#define SUBTARGET_SWITCHES             \
-  {"xl-call",          MASK_XL_CALL,                                   \
-   N_("Always pass floating-point arguments in memory") },             \
-  {"no-xl-call",       - MASK_XL_CALL,                                 \
-   N_("Don't always pass floating-point arguments in memory") },       \
-  {"threads",          0},                                             \
-  {"pe",               0},
-
 #undef ASM_SPEC
 #define ASM_SPEC "-u %(asm_cpu)"
 
index f1bb23f..4d327fd 100644 (file)
@@ -5604,7 +5604,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
          needs_psave = (type
                         && (cum->nargs_prototype <= 0
                             || (DEFAULT_ABI == ABI_AIX
-                                && TARGET_XL_CALL
+                                && TARGET_XL_COMPAT
                                 && align_words >= GP_ARG_NUM_REG)));
 
          if (!needs_psave && mode == fmode)
@@ -5712,7 +5712,7 @@ rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
       && !(type
           && (cum->nargs_prototype <= 0
               || (DEFAULT_ABI == ABI_AIX
-                  && TARGET_XL_CALL
+                  && TARGET_XL_COMPAT
                   && align_words >= GP_ARG_NUM_REG))))
     {
       if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3) > FP_ARG_MAX_REG + 1)
@@ -11458,10 +11458,34 @@ rs6000_generate_compare (enum rtx_code code)
       emit_insn (cmp);
     }
   else
-    emit_insn (gen_rtx_SET (VOIDmode, compare_result,
-                           gen_rtx_COMPARE (comp_mode,
-                                            rs6000_compare_op0,
-                                            rs6000_compare_op1)));
+    {
+      /* Generate XLC-compatible TFmode compare as PARALLEL with extra
+        CLOBBERs to match cmptf_internal2 pattern.  */
+      if (comp_mode == CCFPmode && TARGET_XL_COMPAT
+         && GET_MODE (rs6000_compare_op0) == TFmode
+         && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+         && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
+       emit_insn (gen_rtx_PARALLEL (VOIDmode,
+         gen_rtvec (9,
+                    gen_rtx_SET (VOIDmode,
+                                 compare_result,
+                                 gen_rtx_COMPARE (comp_mode,
+                                                  rs6000_compare_op0,
+                                                  rs6000_compare_op1)),
+                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
+                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
+                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
+                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
+                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
+                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
+                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
+                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
+      else
+       emit_insn (gen_rtx_SET (VOIDmode, compare_result,
+                               gen_rtx_COMPARE (comp_mode,
+                                                rs6000_compare_op0,
+                                                rs6000_compare_op1)));
+    }
 
   /* Some kinds of FP comparisons need an OR operation;
      under flag_unsafe_math_optimizations we don't bother.  */
index 0ccec58..1a2d12d 100644 (file)
@@ -262,7 +262,7 @@ extern int target_flags;
 #define TARGET_POWERPC64       (target_flags & MASK_POWERPC64)
 #endif
 
-#define TARGET_XL_CALL 0
+#define TARGET_XL_COMPAT 0
 
 /* Run-time compilation parameters selecting different hardware subsets.
 
index c2dd678..515bb05 100644 (file)
   [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
        (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f")
                      (match_operand:TF 2 "gpc_reg_operand" "f")))]
-  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && !TARGET_XL_COMPAT
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
   [(set_attr "type" "fpcompare")
    (set_attr "length" "12")])
+
+(define_insn_and_split "*cmptf_internal2"
+  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+       (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f")
+                     (match_operand:TF 2 "gpc_reg_operand" "f")))
+    (clobber (match_scratch:DF 3 "=f"))
+    (clobber (match_scratch:DF 4 "=f"))
+    (clobber (match_scratch:DF 5 "=f"))
+    (clobber (match_scratch:DF 6 "=f"))
+    (clobber (match_scratch:DF 7 "=f"))
+    (clobber (match_scratch:DF 8 "=f"))
+    (clobber (match_scratch:DF 9 "=f"))
+    (clobber (match_scratch:DF 10 "=f"))]
+  "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && TARGET_XL_COMPAT
+   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 3) (match_dup 13))
+   (set (match_dup 4) (match_dup 14))
+   (set (match_dup 9) (abs:DF (match_dup 5)))
+   (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
+   (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
+                          (label_ref (match_dup 11))
+                          (pc)))
+   (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
+   (set (pc) (label_ref (match_dup 12)))
+   (match_dup 11)
+   (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
+   (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
+   (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
+   (set (match_dup 0) (compare:CCFP (match_dup 7) (match_dup 4)))
+   (match_dup 12)]
+{
+  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);
+
+  operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word);
+  operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word);
+  operands[7] = simplify_gen_subreg (DFmode, operands[2], TFmode, hi_word);
+  operands[8] = simplify_gen_subreg (DFmode, operands[2], TFmode, lo_word);
+  operands[11] = gen_label_rtx ();
+  operands[12] = gen_label_rtx ();
+  real_inf (&rv);
+  operands[13] = force_const_mem (DFmode,
+                                 CONST_DOUBLE_FROM_REAL_VALUE (rv, DFmode));
+  operands[14] = force_const_mem (DFmode,
+                                 CONST_DOUBLE_FROM_REAL_VALUE (dconst0,
+                                                               DFmode));
+  if (TARGET_TOC)
+    {
+      operands[13] = gen_const_mem (DFmode,
+                                   create_TOC_reference (XEXP (operands[13], 0)));
+      operands[14] = gen_const_mem (DFmode,
+                                   create_TOC_reference (XEXP (operands[14], 0)));
+      set_mem_alias_set (operands[13], get_TOC_alias_set ());
+      set_mem_alias_set (operands[14], get_TOC_alias_set ());
+    }
+})
 \f
 ;; Now we have the scc insns.  We can do some combinations because of the
 ;; way the machine works.
index d440cef..a93c8f0 100644 (file)
@@ -602,7 +602,7 @@ See RS/6000 and PowerPC Options.
 -mpowerpc-gfxopt  -mno-powerpc-gfxopt @gol
 -mnew-mnemonics  -mold-mnemonics @gol
 -mfull-toc   -mminimal-toc  -mno-fp-in-toc  -mno-sum-in-toc @gol
--m64  -m32  -mxl-call  -mno-xl-call  -mpe @gol
+-m64  -m32  -mxl-compat  -mno-xl-compat  -mpe @gol
 -malign-power  -malign-natural @gol
 -msoft-float  -mhard-float  -mmultiple  -mno-multiple @gol
 -mstring  -mno-string  -mupdate  -mno-update @gol
@@ -10501,13 +10501,17 @@ Specifying @option{-maix64} implies @option{-mpowerpc64} and
 @option{-mpowerpc}, while @option{-maix32} disables the 64-bit ABI and
 implies @option{-mno-powerpc64}.  GCC defaults to @option{-maix32}.
 
-@item -mxl-call
-@itemx -mno-xl-call
-@opindex mxl-call
-@opindex mno-xl-call
-On AIX, pass floating-point arguments to prototyped functions beyond the
-register save area (RSA) on the stack in addition to argument FPRs.  The
-AIX calling convention was extended but not initially documented to
+@item -mxl-compat
+@itemx -mno-xl-compat
+@opindex mxl-compat
+@opindex mno-xl-compat
+Produce code that conforms more closely to IBM XLC semantics when using
+AIX-compatible ABI.  Pass floating-point arguments to prototyped
+functions beyond the register save area (RSA) on the stack in addition
+to argument FPRs.  Do not assume that most significant double in 128
+bit long double value is properly rounded when comparing values.
+
+The AIX calling convention was extended but not initially documented to
 handle an obscure K&R C case of calling a function that takes the
 address of its arguments with fewer arguments than declared.  AIX XL
 compilers access floating point arguments which do not fit in the