config.gcc: Add support for --enable-e500_double.
authorAldy Hernandez <aldyh@redhat.com>
Thu, 21 Oct 2004 22:28:29 +0000 (22:28 +0000)
committerAldy Hernandez <aldyh@gcc.gnu.org>
Thu, 21 Oct 2004 22:28:29 +0000 (22:28 +0000)
* config.gcc: Add support for --enable-e500_double.

* config/rs6000/e500-double.h: New file.

* config/rs6000/rs6000.h: Define TARGET_E500_SINGLE and
TARGET_E500_DOUBLE.

* config/rs6000/eabi.h: Define TARGET_E500_SINGLE and
TARGET_E500_DOUBLE.

* config/rs6000/linuxspe.h: Same.

* doc/invoke.texi (Option Summary): Document new options for
mfloat-gprs.
(RS/6000 and PowerPC Options): Same.

* config/rs6000/rs6000.c (rs6000_parse_float_gprs_option): New
function.
(rs6000_override_options): Use it.  Use
SUB3TARGET_OVERRIDE_OPTIONS.
Add 8548 to processor_target_table.
(rs6000_legitimate_address): Handle e500 doubles.
(rs6000_legitimize_address): Same.
(rs6000_legitimize_reload_address): Same.
(rs6000_hard_regno_nregs): Same.
(spe_func_has_64bit_regs_p): Same.
(emit_frame_save): Same.
(gen_frame_mem_offset): Same.
(rs6000_dwarf_register_span): Same.
(rs6000_generate_compare): Same.
(easy_fp_constant): Same.
(legitimate_offset_address_p): Same.

* config/rs6000/spe.md: (cmdfeq_gpr): New.
(tstdfeq_gpr): New.
(cmpdfgt_gpr): New.
(tstdfgt_gpr): New.
(tstdfgt_gpr): New.
(cmpdflt_gpr): New.
(tstdflt_gpr): New.
Add new constants.

From-SVN: r89416

gcc/ChangeLog
gcc/config.gcc
gcc/config/rs6000/e500-double.h [new file with mode: 0644]
gcc/config/rs6000/eabi.h
gcc/config/rs6000/linuxspe.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/spe.md
gcc/doc/invoke.texi

index 49f28bed75f5b7c473e4b1d256975d9b10b167f9..6264a63df161e51f1852ea4215f49c9147ed76c6 100644 (file)
@@ -1,3 +1,47 @@
+2004-10-21  Aldy Hernandez  <aldyh@redhat.com>
+
+       * config.gcc: Add support for --enable-e500_double.
+
+       * config/rs6000/e500-double.h: New file.
+
+       * config/rs6000/rs6000.h: Define TARGET_E500_SINGLE and
+       TARGET_E500_DOUBLE.
+
+       * config/rs6000/eabi.h: Define TARGET_E500_SINGLE and
+       TARGET_E500_DOUBLE.
+
+       * config/rs6000/linuxspe.h: Same.
+
+       * doc/invoke.texi (Option Summary): Document new options for
+       mfloat-gprs.
+       (RS/6000 and PowerPC Options): Same.
+
+       * config/rs6000/rs6000.c (rs6000_parse_float_gprs_option): New
+       function.
+       (rs6000_override_options): Use it.  Use
+       SUB3TARGET_OVERRIDE_OPTIONS.
+       Add 8548 to processor_target_table.
+       (rs6000_legitimate_address): Handle e500 doubles.
+       (rs6000_legitimize_address): Same.
+       (rs6000_legitimize_reload_address): Same.
+       (rs6000_hard_regno_nregs): Same.
+       (spe_func_has_64bit_regs_p): Same.
+       (emit_frame_save): Same.
+       (gen_frame_mem_offset): Same.
+       (rs6000_dwarf_register_span): Same.
+       (rs6000_generate_compare): Same.
+       (easy_fp_constant): Same.
+       (legitimate_offset_address_p): Same.
+
+       * config/rs6000/spe.md: (cmdfeq_gpr): New.
+       (tstdfeq_gpr): New.
+       (cmpdfgt_gpr): New.
+       (tstdfgt_gpr): New.
+       (tstdfgt_gpr): New.
+       (cmpdflt_gpr): New.
+       (tstdflt_gpr): New.
+       Add new constants.
+
 2004-10-21  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
 
        * config/arc/lib1funcs.asm (___umulsidi3): Fix typo.
index 0308fc9c8eeb2eeaddfe1cb3d94020db0a55a7b4..c1820ccb8315198171dde876c03ad27dffb3cded 100644 (file)
@@ -2665,6 +2665,11 @@ fi
                c_target_objs="${c_target_objs} rs6000-c.o"
                cxx_target_objs="${cxx_target_objs} rs6000-c.o"
                tmake_file="rs6000/t-rs6000 ${tmake_file}"
+
+                if test x$enable_e500_double = xyes
+                then
+                        tm_file="$tm_file rs6000/e500-double.h"
+                fi
                ;;
 
        sparc*-*-*)
diff --git a/gcc/config/rs6000/e500-double.h b/gcc/config/rs6000/e500-double.h
new file mode 100644 (file)
index 0000000..5f0c734
--- /dev/null
@@ -0,0 +1,25 @@
+/* Target definitions for E500 with double precision FP.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+   Contributed by Aldy Hernandez (aldyh@redhat.com).
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 2, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING.  If not, write to the
+   Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.  */
+
+#undef  SUB3TARGET_OVERRIDE_OPTIONS
+#define SUB3TARGET_OVERRIDE_OPTIONS \
+  if (rs6000_float_gprs_string == NULL) \
+    rs6000_float_gprs = 2;
index ff8df2c3e417cf5ac89fc881dc0e92d2b86ef4f4..8de75a6cee26267fb588115dc05ac0f8a78f8f8c 100644 (file)
 #undef TARGET_E500
 #undef TARGET_ISEL
 #undef TARGET_FPRS
+#undef TARGET_E500_SINGLE
+#undef TARGET_E500_DOUBLE
 
 #define TARGET_SPE_ABI rs6000_spe_abi
 #define TARGET_SPE rs6000_spe
 #define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540)
 #define TARGET_ISEL rs6000_isel
-#define TARGET_FPRS (!rs6000_float_gprs)
+#define TARGET_FPRS (rs6000_float_gprs == 0)
+#define TARGET_E500_SINGLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 1)
+#define TARGET_E500_DOUBLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 2)
index 36b494e59615ab9553901cb4e21d25dee4ac9069..f4e02ebf624eff418bd858768ce508bf73fdb3d9 100644 (file)
 #undef TARGET_E500
 #undef TARGET_ISEL
 #undef TARGET_FPRS
+#undef TARGET_E500_SINGLE
+#undef TARGET_E500_DOUBLE
 
 #define TARGET_SPE_ABI rs6000_spe_abi
 #define TARGET_SPE rs6000_spe
 #define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540)
 #define TARGET_ISEL rs6000_isel
-#define TARGET_FPRS (!rs6000_float_gprs)
+#define TARGET_FPRS (rs6000_float_gprs == 0)
+#define TARGET_E500_SINGLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 1)
+#define TARGET_E500_DOUBLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 2)
 
 #undef  SUBSUBTARGET_OVERRIDE_OPTIONS
 #define SUBSUBTARGET_OVERRIDE_OPTIONS \
index 7d2d1d9b7947051b1ab7567fa880c123c1d71544..6117bdb6b60bb9ed00fd0b8431d99ff2c8fea801 100644 (file)
@@ -723,6 +723,7 @@ static void rs6000_parse_abi_options (void);
 static void rs6000_parse_alignment_option (void);
 static void rs6000_parse_tls_size_option (void);
 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
+static void rs6000_parse_float_gprs_option (void);
 static int first_altivec_reg_to_save (void);
 static unsigned int compute_vrsave_mask (void);
 static void compute_save_world_info(rs6000_stack_t *info_ptr);
@@ -1119,6 +1120,8 @@ rs6000_override_options (const char *default_cpu)
         {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
         {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
         {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+        /* 8548 has a dummy entry for now.  */
+        {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
         {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
         {"970", PROCESSOR_POWER4,
          POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
@@ -1292,14 +1295,14 @@ rs6000_override_options (const char *default_cpu)
   /* Handle -malign-XXXXX option.  */
   rs6000_parse_alignment_option ();
 
+  rs6000_parse_float_gprs_option ();
+
   /* Handle generic -mFOO=YES/NO options.  */
   rs6000_parse_yes_no_option ("vrsave", rs6000_altivec_vrsave_string,
                              &rs6000_altivec_vrsave);
   rs6000_parse_yes_no_option ("isel", rs6000_isel_string,
                              &rs6000_isel);
   rs6000_parse_yes_no_option ("spe", rs6000_spe_string, &rs6000_spe);
-  rs6000_parse_yes_no_option ("float-gprs", rs6000_float_gprs_string,
-                             &rs6000_float_gprs);
 
   /* Handle -mtls-size option.  */
   rs6000_parse_tls_size_option ();
@@ -1310,6 +1313,9 @@ rs6000_override_options (const char *default_cpu)
 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
   SUBSUBTARGET_OVERRIDE_OPTIONS;
 #endif
+#ifdef SUB3TARGET_OVERRIDE_OPTIONS
+  SUB3TARGET_OVERRIDE_OPTIONS;
+#endif
 
   if (TARGET_E500)
     {
@@ -1622,6 +1628,23 @@ rs6000_parse_abi_options (void)
     error ("unknown ABI specified: '%s'", rs6000_abi_string);
 }
 
+/* Handle -mfloat-gprs= options.  */
+static void
+rs6000_parse_float_gprs_option (void)
+{
+  if (rs6000_float_gprs_string == 0)
+    return;
+  else if (! strcmp (rs6000_float_gprs_string, "yes")
+          || ! strcmp (rs6000_float_gprs_string, "single"))
+    rs6000_float_gprs = 1;
+  else if (! strcmp (rs6000_float_gprs_string, "double"))
+    rs6000_float_gprs = 2;
+  else if (! strcmp (rs6000_float_gprs_string, "no"))
+    rs6000_float_gprs = 0;
+  else
+    error ("invalid option for -mfloat-gprs");
+}
+
 /* Handle -malign-XXXXXX options.  */
 static void
 rs6000_parse_alignment_option (void)
@@ -2163,7 +2186,7 @@ easy_fp_constant (rtx op, enum machine_mode mode)
     return 0;
 
   /* Consider all constants with -msoft-float to be easy.  */
-  if ((TARGET_SOFT_FLOAT || !TARGET_FPRS)
+  if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
       && mode != DImode)
     return 1;
 
@@ -2197,6 +2220,9 @@ easy_fp_constant (rtx op, enum machine_mode mode)
       long k[2];
       REAL_VALUE_TYPE rv;
 
+      if (TARGET_E500_DOUBLE)
+       return 0;
+
       REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
       REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
 
@@ -3173,6 +3199,9 @@ rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
       return SPE_CONST_OFFSET_OK (offset);
 
     case DFmode:
+      if (TARGET_E500_DOUBLE)
+       return SPE_CONST_OFFSET_OK (offset);
+
     case DImode:
       if (mode == DFmode || !TARGET_POWERPC64)
        extra = 4;
@@ -3325,7 +3354,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
           && GET_MODE_NUNITS (mode) == 1
           && ((TARGET_HARD_FLOAT && TARGET_FPRS)
               || TARGET_POWERPC64
-              || (mode != DFmode && mode != TFmode))
+              || ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode))
           && (TARGET_POWERPC64 || mode != DImode)
           && mode != TImode)
     {
@@ -3344,7 +3373,8 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
       reg = force_reg (Pmode, x);
       return reg;
     }
-  else if (SPE_VECTOR_MODE (mode))
+  else if (SPE_VECTOR_MODE (mode)
+          || (TARGET_E500_DOUBLE && mode == DFmode))
     {
       /* We accept [reg + reg] and [reg + OFFSET].  */
 
@@ -3388,7 +3418,8 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
           && GET_CODE (x) != CONST_INT
           && GET_CODE (x) != CONST_DOUBLE
           && CONSTANT_P (x)
-          && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
+          && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+              || (mode != DFmode || TARGET_E500_DOUBLE))
           && mode != DImode
           && mode != TImode)
     {
@@ -3735,6 +3766,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
       && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
       && GET_CODE (XEXP (x, 1)) == CONST_INT
       && !SPE_VECTOR_MODE (mode)
+      && !(TARGET_E500_DOUBLE && mode == DFmode)
       && !ALTIVEC_VECTOR_MODE (mode))
     {
       HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
@@ -3838,6 +3870,7 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
   if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
       && !ALTIVEC_VECTOR_MODE (mode)
       && !SPE_VECTOR_MODE (mode)
+      && !(TARGET_E500_DOUBLE && mode == DFmode)
       && TARGET_UPDATE
       && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
     return 1;
@@ -3859,7 +3892,7 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
       && mode != TFmode
       && ((TARGET_HARD_FLOAT && TARGET_FPRS)
          || TARGET_POWERPC64
-         || (mode != DFmode && mode != TFmode))
+         || ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode))
       && (TARGET_POWERPC64 || mode != DImode)
       && legitimate_indexed_address_p (x, reg_ok_strict))
     return 1;
@@ -3924,6 +3957,9 @@ rs6000_hard_regno_nregs (int regno, enum machine_mode mode)
   if (FP_REGNO_P (regno))
     return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
 
+  if (TARGET_E500_DOUBLE && mode == DFmode)
+    return 1;
+
   if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
     return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD;
 
@@ -10864,6 +10900,10 @@ rs6000_generate_compare (enum rtx_code code)
       && rs6000_compare_fp_p)
     {
       rtx cmp, or1, or2, or_result, compare_result2;
+      enum machine_mode op_mode = GET_MODE (rs6000_compare_op0);
+
+      if (op_mode == VOIDmode)
+       op_mode = GET_MODE (rs6000_compare_op1);
 
       /* Note: The E500 comparison instructions set the GT bit (x +
         1), on success.  This explains the mess.  */
@@ -10871,28 +10911,52 @@ rs6000_generate_compare (enum rtx_code code)
       switch (code)
        {
        case EQ: case UNEQ: case NE: case LTGT:
-         cmp = flag_finite_math_only
-           ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
-                              rs6000_compare_op1)
-           : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
-                              rs6000_compare_op1);
+         if (op_mode == SFmode)
+           cmp = flag_finite_math_only
+             ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
+                                rs6000_compare_op1)
+             : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
+                                rs6000_compare_op1);
+         else if (op_mode == DFmode)
+           cmp = flag_finite_math_only
+             ? gen_tstdfeq_gpr (compare_result, rs6000_compare_op0,
+                                rs6000_compare_op1)
+             : gen_cmpdfeq_gpr (compare_result, rs6000_compare_op0,
+                                rs6000_compare_op1);
+         else abort ();
          break;
        case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
-         cmp = flag_finite_math_only
-           ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
-                              rs6000_compare_op1)
-           : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
-                              rs6000_compare_op1);
+         if (op_mode == SFmode)
+           cmp = flag_finite_math_only
+             ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
+                                rs6000_compare_op1)
+             : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
+                                rs6000_compare_op1);
+         else if (op_mode == DFmode)
+           cmp = flag_finite_math_only
+             ? gen_tstdfgt_gpr (compare_result, rs6000_compare_op0,
+                                rs6000_compare_op1)
+             : gen_cmpdfgt_gpr (compare_result, rs6000_compare_op0,
+                                rs6000_compare_op1);
+         else abort ();
          break;
        case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
-         cmp = flag_finite_math_only
-           ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
-                              rs6000_compare_op1)
-           : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
-                              rs6000_compare_op1);
+         if (op_mode == SFmode)
+           cmp = flag_finite_math_only
+             ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
+                                rs6000_compare_op1)
+             : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
+                                rs6000_compare_op1);
+         else if (op_mode == DFmode)
+           cmp = flag_finite_math_only
+             ? gen_tstdflt_gpr (compare_result, rs6000_compare_op0,
+                                rs6000_compare_op1)
+             : gen_cmpdflt_gpr (compare_result, rs6000_compare_op0,
+                                rs6000_compare_op1);
+         else abort ();
          break;
-       default:
-         abort ();
+        default:
+          abort ();
        }
 
       /* Synthesize LE and GE from LT/GT || EQ.  */
@@ -10915,11 +10979,19 @@ rs6000_generate_compare (enum rtx_code code)
          compare_result2 = gen_reg_rtx (CCFPmode);
 
          /* Do the EQ.  */
-         cmp = flag_finite_math_only
-           ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
-                              rs6000_compare_op1)
-           : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
-                              rs6000_compare_op1);
+         if (op_mode == SFmode)
+           cmp = flag_finite_math_only
+             ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
+                                rs6000_compare_op1)
+             : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
+                                rs6000_compare_op1);
+         else if (op_mode == DFmode)
+           cmp = flag_finite_math_only
+             ? gen_tstdfeq_gpr (compare_result2, rs6000_compare_op0,
+                                rs6000_compare_op1)
+             : gen_cmpdfeq_gpr (compare_result2, rs6000_compare_op0,
+                                rs6000_compare_op1);
+         else abort ();
          emit_insn (cmp);
 
          or1 = gen_rtx_GT (SImode, compare_result, const0_rtx);
@@ -13289,6 +13361,7 @@ emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
 
   /* Some cases that need register indexed addressing.  */
   if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+      || (TARGET_E500_DOUBLE && mode == DFmode)
       || (TARGET_SPE_ABI
          && SPE_VECTOR_MODE (mode)
          && !SPE_CONST_OFFSET_OK (offset)))
@@ -13328,7 +13401,8 @@ gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
 
   int_rtx = GEN_INT (offset);
 
-  if (TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
+  if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
+      || (TARGET_E500_DOUBLE && mode == DFmode))
     {
       offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
       emit_move_insn (offset_rtx, int_rtx);
@@ -18082,7 +18156,11 @@ rs6000_dwarf_register_span (rtx reg)
 {
   unsigned regno;
 
-  if (!TARGET_SPE || !SPE_VECTOR_MODE (GET_MODE (reg)))
+  if (TARGET_SPE
+      && (SPE_VECTOR_MODE (GET_MODE (reg))
+         || (TARGET_E500_DOUBLE && GET_MODE (reg) == DFmode)))
+    ;
+  else
     return NULL_RTX;
 
   regno = REGNO (reg);
index 28932aa661ec8e448c4c036320c9b79685f74045..0a209b674cfa48a0f358b5aa2c0c6bdd8db14315 100644 (file)
@@ -568,6 +568,8 @@ extern const char *rs6000_warn_altivec_long_switch;
 #define TARGET_E500 0
 #define TARGET_ISEL 0
 #define TARGET_FPRS 1
+#define TARGET_E500_SINGLE 0
+#define TARGET_E500_DOUBLE 0
 
 /* Sometimes certain combinations of command options do not make sense
    on a particular target machine.  You can define a macro
index 3627c88fe636f7af219eda66e1d049970cfc0b7b..6a130021a5b24338f46fdee18142cf2a4199ab18 100644 (file)
 
 (define_constants
   [(SPE_ACC_REGNO      111)
-   (SPEFSCR_REGNO      112)])
+   (SPEFSCR_REGNO      112)
+
+   (CMPDFEQ_GPR                1006)
+   (TSTDFEQ_GPR                1007)
+   (CMPDFGT_GPR                1008)
+   (TSTDFGT_GPR                1009)
+   (CMPDFLT_GPR                1010)
+   (TSTDFLT_GPR                1011)
+   ])
 
 (define_insn "*negsf2_gpr"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=r")
   "TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
   "efststlt %0,%1,%2"
   [(set_attr "type" "veccmpsimple")])
+
+;; Same thing, but for double-precision.
+
+(define_insn "cmpdfeq_gpr"
+  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+       (unspec:CCFP
+        [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
+                       (match_operand:DF 2 "gpc_reg_operand" "r"))]
+        CMPDFEQ_GPR))]
+  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && !flag_unsafe_math_optimizations"
+  "efdcmpeq %0,%1,%2"
+  [(set_attr "type" "veccmp")])
+
+(define_insn "tstdfeq_gpr"
+  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+       (unspec:CCFP
+        [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
+                       (match_operand:DF 2 "gpc_reg_operand" "r"))]
+        TSTDFEQ_GPR))]
+  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && flag_unsafe_math_optimizations"
+  "efdtsteq %0,%1,%2"
+  [(set_attr "type" "veccmpsimple")])
+
+(define_insn "cmpdfgt_gpr"
+  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+       (unspec:CCFP
+        [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
+                       (match_operand:DF 2 "gpc_reg_operand" "r"))]
+        CMPDFGT_GPR))]
+  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && !flag_unsafe_math_optimizations"
+  "efdcmpgt %0,%1,%2"
+  [(set_attr "type" "veccmp")])
+
+(define_insn "tstdfgt_gpr"
+  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+       (unspec:CCFP
+        [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
+                       (match_operand:DF 2 "gpc_reg_operand" "r"))]
+        TSTDFGT_GPR))]
+  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && flag_unsafe_math_optimizations"
+  "efdtstgt %0,%1,%2"
+  [(set_attr "type" "veccmpsimple")])
+
+(define_insn "cmpdflt_gpr"
+  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+       (unspec:CCFP
+        [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
+                       (match_operand:DF 2 "gpc_reg_operand" "r"))]
+        CMPDFLT_GPR))]
+  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && !flag_unsafe_math_optimizations"
+  "efdcmplt %0,%1,%2"
+  [(set_attr "type" "veccmp")])
+
+(define_insn "tstdflt_gpr"
+  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+       (unspec:CCFP
+        [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r")
+                       (match_operand:DF 2 "gpc_reg_operand" "r"))]
+        TSTDFLT_GPR))]
+  "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && flag_unsafe_math_optimizations"
+  "efdtstlt %0,%1,%2"
+  [(set_attr "type" "veccmpsimple")])
index 66e87a15990e1062cbf58073c93fc29acbe19a23..a2b0d83df0cbbb73904f8089b6f98f7dd7c292eb 100644 (file)
@@ -616,7 +616,7 @@ See RS/6000 and PowerPC Options.
 -mabi=spe  -mabi=no-spe @gol
 -misel=yes  -misel=no @gol
 -mspe=yes  -mspe=no @gol
--mfloat-gprs=yes  -mfloat-gprs=no @gol
+-mfloat-gprs=yes  -mfloat-gprs=no -mfloat-gprs=single -mfloat-gprs=double @gol
 -mprototype  -mno-prototype @gol
 -msim  -mmvme  -mads  -myellowknife  -memb  -msdata @gol
 -msdata=@var{opt}  -mvxworks  -mwindiss  -G @var{num}  -pthread}
@@ -10279,12 +10279,23 @@ This switch enables or disables the generation of ISEL instructions.
 This switch enables or disables the generation of SPE simd
 instructions.
 
-@item -mfloat-gprs=@var{yes/no}
+@item -mfloat-gprs=@var{yes/single/double/no}
 @itemx -mfloat-gprs
 @opindex mfloat-gprs
 This switch enables or disables the generation of floating point
 operations on the general purpose registers for architectures that
-support it.  This option is currently only available on the MPC8540.
+support it.
+
+The argument @var{yes} or @var{single} enables the use of
+single-precision floating point operations.
+
+The argument @var{double} enables the use of single and
+double-precision floating point operations.
+
+The argument @var{no} disables floating point operations on the
+general purpose registers.
+
+This option is currently only available on the MPC854x.
 
 @item -m32
 @itemx -m64