diff options
-rw-r--r-- | gcc/ChangeLog | 44 | ||||
-rw-r--r-- | gcc/config.gcc | 5 | ||||
-rw-r--r-- | gcc/config/rs6000/e500-double.h | 25 | ||||
-rw-r--r-- | gcc/config/rs6000/eabi.h | 6 | ||||
-rw-r--r-- | gcc/config/rs6000/linuxspe.h | 6 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 140 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 2 | ||||
-rw-r--r-- | gcc/config/rs6000/spe.md | 72 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 17 |
9 files changed, 280 insertions, 37 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 49f28bed75f..6264a63df16 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/config.gcc b/gcc/config.gcc index 0308fc9c8ee..c1820ccb831 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -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 index 00000000000..5f0c734762e --- /dev/null +++ b/gcc/config/rs6000/e500-double.h @@ -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; diff --git a/gcc/config/rs6000/eabi.h b/gcc/config/rs6000/eabi.h index ff8df2c3e41..8de75a6cee2 100644 --- a/gcc/config/rs6000/eabi.h +++ b/gcc/config/rs6000/eabi.h @@ -49,9 +49,13 @@ #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) diff --git a/gcc/config/rs6000/linuxspe.h b/gcc/config/rs6000/linuxspe.h index 36b494e5961..f4e02ebf624 100644 --- a/gcc/config/rs6000/linuxspe.h +++ b/gcc/config/rs6000/linuxspe.h @@ -32,12 +32,16 @@ #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 \ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 7d2d1d9b794..6117bdb6b60 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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); diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 28932aa661e..0a209b674cf 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -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 diff --git a/gcc/config/rs6000/spe.md b/gcc/config/rs6000/spe.md index 3627c88fe63..6a130021a5b 100644 --- a/gcc/config/rs6000/spe.md +++ b/gcc/config/rs6000/spe.md @@ -21,7 +21,15 @@ (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") @@ -2532,3 +2540,65 @@ "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")]) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 66e87a15990..a2b0d83df0c 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 |