diff options
-rw-r--r-- | gcc/ChangeLog | 80 | ||||
-rw-r--r-- | gcc/config.gcc | 5 | ||||
-rw-r--r-- | gcc/config/rs6000/predicates.md | 3 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-c.c | 3 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 157 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 11 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 274 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.opt | 12 | ||||
-rw-r--r-- | gcc/config/rs6000/singlefp.h | 40 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 15 |
10 files changed, 432 insertions, 168 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b0f8f525cfc..95a932ef902 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,71 @@ +2008-09-24 Michael J. Eager <eager@eagercon.com> + + * config/rs6000/predicates.md (easy_fp_constant): Single FP consts + are easy. + * config/rs6000/rs6000.c (rs6000_override_options): Move + rs6000_init_hard_regno_mode_ok after all options changed. + Set rs6000_single_float, rs6000_double_float if TARGET_HARD_FLOAT. + (rs6000_handle_option): Process -msingle-float, -mdouble-float, + -msimple-fpu flags. Add warning messages if single FP not configured. + (rs6000_file_start): Output gnu_attribute for single-float. + (legitimate_lo_sum_address_p): Condition on TARGET_DOUBLE_FLOAT. + (rs6000_legitimize_address): Likewise. + (rs6000_legitimize_reload_address): Likewise. + (rs6000_emit_move): Condition on TARGET_DOUBLE_FLOAT, + TARGET_SINGLE_FLOAT. + (function_arg_advance): Likewise. + (function_arg): Likewise. + (setup_incoming_varargs): Condition on TARGET_DOUBLE_FLOAT. + (rs6000_gimplify_va_arg): Condition on TARGET_DOUBLE_FLOAT, + TARGET_SINGLE_FLOAT. + (rs6000_split_multireg_move): Condition on TARGET_DOUBLE_FLOAT. + (rs6000_emit_prologue): Likewise. + (rs6000_function_value): Condition on TARGET_DOUBLE_FLOAT, + TARGET_SINGLE_FLOAT. + (rs6000_libcall_value): Likewise. + * config/rs6000/rs6000.h (TARGET_SINGLE_FLOAT): New default to 1. + (TARGET_DOUBLE_FLOAT): New default to 1 + (TARGET_SIMPLE_FPU): New default to 0 + (TARGET_SINGLE_FPU): New default to 0 + (TARGET_SINGLE_FLOAT_MODE): New. + (TARGET_DOUBLE_FLOAT_MODE): New. + * config/rs6000/singlefp.h: New; redefine TARGET_SINGLE_FLOAT, + TARGET_DOUBLE_FLOAT, TARGET_SIMPLE_FPU, TARGET_SINGLE_FPU, + UNITS_PER_FP_WORD + * config/rs6000/rs6000.md (define_mode_iterator): Condition on + TARGET_DOUBLE_FLOAT, TARGET_SINGLE_FLOAT. + (extendsfdf2, extendsfdf2_fpr, truncdfsf2, truncdfsf2_fpr, + copysigndf3,fseldfsf4, negdf2, negdf2_fpr, absdf2, absdf2_fpr, + nabsdf2_fpr, adddf3, adddf3_fpr, subdf3, subdf3_fpr, muldf3, + muldf3_fpr, divdf3, divdf3_fpr, sqrtdf2, smaxdf3, smindf3, + movdfcc, *fseldfdf4, floatsidf2, *floatsidf2_internal, + floatunssidf2, *floatunssidf2_internal, fix_truncdfsi2, + *fix_truncdfsi2_internal, fix_truncdfsi2_internal_gfxopt, + fix_truncdfsi2_mfpgpr, fctiwz, btruncdf2, ceildf2, floordf2, + rounddf2, floatdidf2, floatsidf_ppc64_mfpgpr, floatsidf_ppc64, + floatunssidf_ppc64, fix_truncdfdi2, movdf_hardfloat32, + movdf_hardfloat64_mfpgpr, movdf_hardfloat64, extenddftf2_fprs, + extenddftf2_internal, trunctfdf2_internal2, fix_trunc_helper, + abstf2_internal, movdf_update1, movdf_update2, cmpdf_internal1, + cmptf_internal1, *cmptf_internal2): Condition on + TARGET_DOUBLE_FLOAT. + (aux_truncdfsf2, negsf2, *negsf2, abssf2, *abssf2, addsf3, subsf3, + mulsf3, divsf3, sqrtsf2, copysignsf3, smaxsf3, sminsf3, movsfcc, + *fselsfsf4, fixuns_truncsfsi2, fix_truncsfsi2, floatunssisf2, + btruncsf2, ceilsf2, floorsf2, roundsf2, floatdisf2_internal1, + floatdisf2_internal2, *movsf_hardfloat, trunctfsf2_fprs, + *movsf_update1, *movsf_update2, *cmpsf_internal1): Condition on + TARGET_SINGLE_FLOAT. + (divsf3, sqrtsf2, divdf3, divdf3_fpr): Condition on TARGET_SIMPLE_FPU. + * config/rs6000/rs6000.opt (-msingle-float): New. + (-mdouble-float): New. + (-msimple-fpu): New. + * doc/invoke.texi (RS/6000 and PowerPC Options): Add + -msingle-float, -mdouble-float, -msimple-fpu options. + * config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Set + _SOFT_DOUBLE for -msingle-float. + * config.gcc: New config for target=powerpc-xilinx-eabi. + 2008-09-23 Eric Botcazou <ebotcazou@adacore.com> * config/sparc/constraints.md: New file. @@ -7008,7 +7076,7 @@ PR ada/36554 * dwarf2out.c (is_subrange_type): Deal with BOOLEAN_TYPE. -2008-07-30 Rafael テ」ila de Espテュndola <espindola@google.com> +2008-07-30 Rafael テvila de Espテュndola <espindola@google.com> PR 36974 * final.c (call_from_call_insn): Handle COND_EXEC. @@ -7220,7 +7288,7 @@ * config/rs6000/rs6000.h (SLOW_UNALIGNED_ACCESS): Add clause for vector modes. -2008-07-30 Rafael テ」ila de Espテュndola <espindola@google.com> +2008-07-30 Rafael テvila de Espテュndola <espindola@google.com> * final.c (call_from_call_insn): New. (final_scan_insn): Call assemble_external on FUNCTION_DECLs. @@ -8338,7 +8406,7 @@ (TARGET_OPTION_PRINT): Ditto. (TARGET_CAN_INLINE_P): Ditto. -2008-07-22 Rafael テ」ila de Espテュndola <espindola@google.com> +2008-07-22 Rafael テvila de Espテュndola <espindola@google.com> * c-typeck.c (build_external_ref): Don't call assemble_external. * final.c (output_operand): Call assemble_external. @@ -8359,7 +8427,7 @@ highest magnitude if this is still less or equal to the true quotient in magnitude. -2008-07-21 Rafael テ」ila de Espテュndola <espindola@google.com> +2008-07-21 Rafael テvila de Espテュndola <espindola@google.com> * Makefile.in: Replace toplev.h with TOPLEV_H. * c-decl.c (merge_decls): Don't set DECL_IN_SYSTEM_HEADER. @@ -8662,7 +8730,7 @@ (m32c_legitimate_address_p): Handle "++rii" addresses created by m32c_legitimize_reload_address. -2007-07-16 Rafael テ」ila de Espテュndola <espindola@google.com> +2007-07-16 Rafael テvila de Espテュndola <espindola@google.com> * c-decl.c (merge_decls): Keep DECL_SOURCE_LOCATION and DECL_IN_SYSTEM_HEADER in sync. @@ -8752,7 +8820,7 @@ * emit-rtl.c (set_mem_attributes_minus_bitpos): Improve comment. -2007-07-14 Rafael テ」ila de Espテュndola <espindola@google.com> +2007-07-14 Rafael テvila de Espテュndola <espindola@google.com> * c-decl.c (diagnose_mismatched_decls): Don't warn if TREE_NO_WARNING is set. diff --git a/gcc/config.gcc b/gcc/config.gcc index 22bca4d57a1..e3d170aad95 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1791,6 +1791,11 @@ powerpc-*-eabialtivec*) extra_options="${extra_options} rs6000/sysv4.opt" tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcendian rs6000/t-ppccomm" ;; +powerpc-xilinx-eabi*) + tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/singlefp.h" + extra_options="${extra_options} rs6000/sysv4.opt" + tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm" + ;; powerpc-*-eabi*) tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h" extra_options="${extra_options} rs6000/sysv4.opt" diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index f6929706899..90ab0810fc1 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -192,7 +192,8 @@ return 0; /* Consider all constants with -msoft-float to be easy. */ - if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE) + if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE + || (TARGET_HARD_FLOAT && (TARGET_SINGLE_FLOAT && ! TARGET_DOUBLE_FLOAT))) && mode != DImode) return 1; diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c index da1cb787169..10589bdc8e7 100644 --- a/gcc/config/rs6000/rs6000-c.c +++ b/gcc/config/rs6000/rs6000-c.c @@ -297,7 +297,8 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile) builtin_define ("__PAIRED__"); if (TARGET_SOFT_FLOAT) builtin_define ("_SOFT_FLOAT"); - if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE))) + if ((!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE))) + ||(TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_DOUBLE_FLOAT)) builtin_define ("_SOFT_DOUBLE"); /* Used by lwarx/stwcx. errata work-around. */ if (rs6000_cpu == PROCESSOR_PPC405) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index cdeb1c9c500..8cb3e7d1571 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1556,8 +1556,6 @@ rs6000_override_options (const char *default_cpu) | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP) }; - rs6000_init_hard_regno_mode_ok (); - set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT; #ifdef OS_MISSING_POWERPC64 if (OS_MISSING_POWERPC64) @@ -1968,6 +1966,25 @@ rs6000_override_options (const char *default_cpu) can be optimized to ap = __builtin_next_arg (0). */ if (DEFAULT_ABI != ABI_V4) targetm.expand_builtin_va_start = NULL; + + /* Set up single/double float flags. + If TARGET_HARD_FLOAT is set, but neither single or double is set, + then set both flags. */ + if (TARGET_HARD_FLOAT && TARGET_FPRS + && rs6000_single_float == 0 && rs6000_double_float == 0) + rs6000_single_float = rs6000_double_float = 1; + + /* Reset single and double FP flags if target is E500. */ + if (TARGET_E500) + { + rs6000_single_float = rs6000_double_float = 0; + if (TARGET_E500_SINGLE) + rs6000_single_float = 1; + if (TARGET_E500_DOUBLE) + rs6000_single_float = rs6000_double_float = 1; + } + + rs6000_init_hard_regno_mode_ok (); } /* Implement targetm.vectorize.builtin_mask_for_load. */ @@ -2477,6 +2494,37 @@ rs6000_handle_option (size_t code, const char *arg, int value) return false; } break; + + case OPT_msingle_float: + if (!TARGET_SINGLE_FPU) + warning (0, "-msingle-float option equivalent to -mhard-float"); + /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */ + rs6000_double_float = 0; + target_flags &= ~MASK_SOFT_FLOAT; + target_flags_explicit |= MASK_SOFT_FLOAT; + break; + + case OPT_mdouble_float: + /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */ + rs6000_single_float = 1; + target_flags &= ~MASK_SOFT_FLOAT; + target_flags_explicit |= MASK_SOFT_FLOAT; + break; + + case OPT_msimple_fpu: + if (!TARGET_SINGLE_FPU) + warning (0, "-msimple-fpu option ignored"); + break; + + case OPT_mhard_float: + /* -mhard_float implies -msingle-float and -mdouble-float. */ + rs6000_single_float = rs6000_double_float = 1; + break; + + case OPT_msoft_float: + /* -msoft_float implies -mnosingle-float and -mnodouble-float. */ + rs6000_single_float = rs6000_double_float = 0; + break; } return true; } @@ -2546,7 +2594,9 @@ rs6000_file_start (void) if (TARGET_32BIT && DEFAULT_ABI == ABI_V4) { fprintf (file, "\t.gnu_attribute 4, %d\n", - (TARGET_HARD_FLOAT && TARGET_FPRS) ? 1 : 2); + ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1 + : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3 + : 2)); fprintf (file, "\t.gnu_attribute 8, %d\n", (TARGET_ALTIVEC_ABI ? 2 : TARGET_SPE_ABI ? 3 @@ -3691,7 +3741,7 @@ legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict) return false; if (GET_MODE_BITSIZE (mode) > 64 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64 - && !(TARGET_HARD_FLOAT && TARGET_FPRS + && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (mode == DFmode || mode == DDmode)))) return false; @@ -3758,7 +3808,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, && GET_CODE (XEXP (x, 0)) == REG && GET_CODE (XEXP (x, 1)) != CONST_INT && GET_MODE_NUNITS (mode) == 1 - && ((TARGET_HARD_FLOAT && TARGET_FPRS) + && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_POWERPC64 || ((mode != DImode && mode != DFmode && mode != DDmode) || (TARGET_E500_DOUBLE && mode != DDmode))) @@ -3827,7 +3877,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, && CONSTANT_P (x) && GET_MODE_NUNITS (mode) == 1 && (GET_MODE_BITSIZE (mode) <= 32 - || ((TARGET_HARD_FLOAT && TARGET_FPRS) + || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) && (mode == DFmode || mode == DDmode)))) { rtx reg = gen_reg_rtx (Pmode); @@ -3842,7 +3892,7 @@ 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) + && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) || (mode != DFmode && mode != DDmode)) && mode != DImode && mode != TImode) @@ -4259,7 +4309,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode, && mode != TDmode && (mode != DImode || TARGET_POWERPC64) && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64 - || (TARGET_FPRS && TARGET_HARD_FLOAT))) + || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT))) { #if TARGET_MACHO if (flag_pic) @@ -4384,7 +4434,7 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict) && mode != TImode && mode != TFmode && mode != TDmode - && ((TARGET_HARD_FLOAT && TARGET_FPRS) + && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_POWERPC64 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE)) && (TARGET_POWERPC64 || mode != DImode) @@ -4839,7 +4889,7 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode) operands[1] = force_reg (mode, operands[1]); if (mode == SFmode && ! TARGET_POWERPC - && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && GET_CODE (operands[0]) == MEM) { int regnum; @@ -5200,7 +5250,9 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode) #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \ (SCALAR_FLOAT_MODE_P (MODE) \ && (CUM)->fregno <= FP_ARG_MAX_REG \ - && TARGET_HARD_FLOAT && TARGET_FPRS) + && TARGET_HARD_FLOAT && TARGET_FPRS \ + && (TARGET_DOUBLE_FLOAT_MODE (MODE) \ + || TARGET_SINGLE_FLOAT_MODE (MODE))) /* Nonzero if we can use an AltiVec register to pass this arg. */ #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \ @@ -5677,9 +5729,10 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, else if (DEFAULT_ABI == ABI_V4) { if (TARGET_HARD_FLOAT && TARGET_FPRS - && (mode == SFmode || mode == DFmode - || mode == SDmode || mode == DDmode || mode == TDmode - || (mode == TFmode && !TARGET_IEEEQUAD))) + && (TARGET_SINGLE_FLOAT_MODE (mode) + || (TARGET_DOUBLE_FLOAT + && (mode == DFmode || mode == DDmode || mode == TDmode)) + || (mode == TFmode && !TARGET_IEEEQUAD))) { /* _Decimal128 must use an even/odd register pair. This assumes that the register number is odd when fregno is odd. */ @@ -5745,7 +5798,8 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, cum->words = align_words + n_words; if (SCALAR_FLOAT_MODE_P (mode) - && TARGET_HARD_FLOAT && TARGET_FPRS) + && TARGET_HARD_FLOAT && TARGET_FPRS + && (TARGET_DOUBLE_FLOAT_MODE (mode) || TARGET_SINGLE_FLOAT_MODE (mode))) { /* _Decimal128 must be passed in an even/odd float register pair. This assumes that the register number is odd when fregno is @@ -6239,9 +6293,10 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, else if (abi == ABI_V4) { if (TARGET_HARD_FLOAT && TARGET_FPRS - && (mode == SFmode || mode == DFmode - || (mode == TFmode && !TARGET_IEEEQUAD) - || mode == SDmode || mode == DDmode || mode == TDmode)) + && (TARGET_SINGLE_FLOAT_MODE(mode) + || (TARGET_DOUBLE_FLOAT && (mode == SFmode || mode == DFmode)) + && ((mode == TFmode && !TARGET_IEEEQUAD) + || mode == SDmode || mode == DDmode || mode == TDmode))) { /* _Decimal128 must use an even/odd register pair. This assumes that the register number is odd when fregno is odd. */ @@ -6701,11 +6756,17 @@ setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size; fregno++, off += UNITS_PER_FP_WORD, nregs++) { - mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off)); - MEM_NOTRAP_P (mem) = 1; - set_mem_alias_set (mem, set); - set_mem_align (mem, GET_MODE_ALIGNMENT (DFmode)); - emit_move_insn (mem, gen_rtx_REG (DFmode, fregno)); + mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) + ? DFmode : SFmode, + plus_constant (save_area, off)); + MEM_NOTRAP_P (mem) = 1; + set_mem_alias_set (mem, set); + set_mem_align (mem, GET_MODE_ALIGNMENT ( + (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) + ? DFmode : SFmode)); + emit_move_insn (mem, gen_rtx_REG ( + (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) + ? DFmode : SFmode, fregno)); } emit_label (lab); @@ -6920,18 +6981,19 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, align = 1; if (TARGET_HARD_FLOAT && TARGET_FPRS - && (TYPE_MODE (type) == SFmode - || TYPE_MODE (type) == DFmode - || TYPE_MODE (type) == TFmode - || TYPE_MODE (type) == SDmode - || TYPE_MODE (type) == DDmode - || TYPE_MODE (type) == TDmode)) + && (TARGET_SINGLE_FLOAT_MODE (TYPE_MODE (type)) + || (TARGET_DOUBLE_FLOAT + && (TYPE_MODE (type) == DFmode + || TYPE_MODE (type) == TFmode + || TYPE_MODE (type) == SDmode + || TYPE_MODE (type) == DDmode + || TYPE_MODE (type) == TDmode)))) { /* FP args go in FP registers, if present. */ reg = fpr; n_reg = (size + 7) / 8; - sav_ofs = 8*4; - sav_scale = 8; + sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4; + sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4); if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode) align = 8; } @@ -14127,7 +14189,8 @@ rs6000_split_multireg_move (rtx dst, rtx src) mode = GET_MODE (dst); nregs = hard_regno_nregs[reg][mode]; if (FP_REGNO_P (reg)) - reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode; + reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : + ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode); else if (ALTIVEC_REGNO_P (reg)) reg_mode = V16QImode; else if (TARGET_E500_DOUBLE && mode == TFmode) @@ -16079,11 +16142,14 @@ rs6000_emit_prologue (void) properly. */ for (i = 0; i < 64 - info->first_fp_reg_save; i++) { - rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i); + rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) + ? DFmode : SFmode), + info->first_fp_reg_save + i); rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, GEN_INT (info->fp_save_offset + sp_offset + 8 * i)); - rtx mem = gen_frame_mem (DFmode, addr); + rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) + ? DFmode : SFmode), addr); RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg); } @@ -16190,7 +16256,9 @@ rs6000_emit_prologue (void) for (i = 0; i < 64 - info->first_fp_reg_save; i++) if ((df_regs_ever_live_p (info->first_fp_reg_save+i) && ! call_used_regs[info->first_fp_reg_save+i])) - emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode, + emit_frame_save (frame_reg_rtx, frame_ptr_rtx, + (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) + ? DFmode : SFmode, info->first_fp_reg_save + i, info->fp_save_offset + sp_offset + 8 * i, info->total_size); @@ -16835,11 +16903,14 @@ rs6000_emit_epilogue (int sibcall) } for (i = 0; info->first_fp_reg_save + i <= 63; i++) { - rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i); + rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) + ? DFmode : SFmode), + info->first_fp_reg_save + i); rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, GEN_INT (info->fp_save_offset + 8 * i)); - rtx mem = gen_frame_mem (DFmode, addr); + rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) + ? DFmode : SFmode), addr); RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem); } @@ -17244,9 +17315,12 @@ rs6000_emit_epilogue (int sibcall) GEN_INT (info->fp_save_offset + sp_offset + 8 * i)); - mem = gen_frame_mem (DFmode, addr); + mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) + ? DFmode : SFmode), addr); - emit_move_insn (gen_rtx_REG (DFmode, + emit_move_insn (gen_rtx_REG (((TARGET_HARD_FLOAT + && TARGET_DOUBLE_FLOAT) + ? DFmode : SFmode), info->first_fp_reg_save + i), mem); } @@ -22386,7 +22460,10 @@ rs6000_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED) if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS) /* _Decimal128 must use an even/odd register pair. */ regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN; - else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS) + else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_FPRS + && (TARGET_HARD_FLOAT + && (TARGET_SINGLE_FLOAT_MODE (mode) + || TARGET_DOUBLE_FLOAT))) regno = FP_ARG_RETURN; else if (TREE_CODE (valtype) == COMPLEX_TYPE && targetm.calls.split_complex_arg) diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 2d5bbff39ab..ce1b5559ddc 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -298,6 +298,17 @@ enum processor_type PROCESSOR_CELL }; +/* FPU operations supported. + Each use of TARGET_SINGLE_FLOAT or TARGET_DOUBLE_FLOAT must + also test TARGET_HARD_FLOAT. */ +#define TARGET_SINGLE_FLOAT 1 +#define TARGET_DOUBLE_FLOAT 1 +#define TARGET_SINGLE_FPU 0 +#define TARGET_SIMPLE_FPU 0 + +#define TARGET_SINGLE_FLOAT_MODE(MODE) (TARGET_SINGLE_FLOAT && (MODE) == SFmode) +#define TARGET_DOUBLE_FLOAT_MODE(MODE) (TARGET_DOUBLE_FLOAT && (MODE) == DFmode) + extern enum processor_type rs6000_cpu; /* Recast the processor type to the cpu attribute. */ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index d35e9d4eac2..ca615e5693c 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -202,8 +202,11 @@ (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")]) ; Any hardware-supported floating-point mode -(define_mode_iterator FP [(SF "TARGET_HARD_FLOAT") - (DF "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)") +(define_mode_iterator FP [ + (SF "TARGET_HARD_FLOAT + && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)") + (DF "TARGET_HARD_FLOAT + && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)") (TF "!TARGET_IEEEQUAD && TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE) @@ -5059,13 +5062,13 @@ (define_expand "extendsfdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "") (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))] - "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" "") (define_insn_and_split "*extendsfdf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f,f") (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "@ # fmr %0,%1 @@ -5081,53 +5084,53 @@ (define_expand "truncdfsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "") (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" "") (define_insn "*truncdfsf2_fpr" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "frsp %0,%1" [(set_attr "type" "fp")]) (define_insn "aux_truncdfsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRSP))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "frsp %0,%1" [(set_attr "type" "fp")]) (define_expand "negsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "") (neg:SF (match_operand:SF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" "") (define_insn "*negsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fneg %0,%1" [(set_attr "type" "fp")]) (define_expand "abssf2" [(set (match_operand:SF 0 "gpc_reg_operand" "") (abs:SF (match_operand:SF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" "") (define_insn "*abssf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fabs %0,%1" [(set_attr "type" "fp")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fnabs %0,%1" [(set_attr "type" "fp")]) @@ -5135,14 +5138,14 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "") (plus:SF (match_operand:SF 1 "gpc_reg_operand" "") (match_operand:SF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" "") (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" +"TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fadds %0,%1,%2" [(set_attr "type" "fp")]) @@ -5150,7 +5153,7 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "{fa|fadd} %0,%1,%2" [(set_attr "type" "fp")]) @@ -5158,14 +5161,14 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "") (minus:SF (match_operand:SF 1 "gpc_reg_operand" "") (match_operand:SF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" "") (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fsubs %0,%1,%2" [(set_attr "type" "fp")]) @@ -5173,7 +5176,7 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "{fs|fsub} %0,%1,%2" [(set_attr "type" "fp")]) @@ -5181,14 +5184,14 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "") (mult:SF (match_operand:SF 1 "gpc_reg_operand" "") (match_operand:SF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" "") (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fmuls %0,%1,%2" [(set_attr "type" "fp")]) @@ -5196,7 +5199,7 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "{fm|fmul} %0,%1,%2" [(set_attr "type" "dmul")]) @@ -5204,14 +5207,15 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "") (div:SF (match_operand:SF 1 "gpc_reg_operand" "") (match_operand:SF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" "") (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (div:SF (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" "fdivs %0,%1,%2" [(set_attr "type" "sdiv")]) @@ -5219,7 +5223,8 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (div:SF (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" "{fd|fdiv} %0,%1,%2" [(set_attr "type" "ddiv")]) @@ -5247,7 +5252,8 @@ (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD" "fmadds %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -5256,7 +5262,8 @@ (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD" "{fma|fmadd} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -5265,7 +5272,8 @@ (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD" "fmsubs %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -5274,7 +5282,8 @@ (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD" "{fms|fmsub} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -5284,7 +5293,7 @@ (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f"))))] "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (SFmode)" + && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)" "fnmadds %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -5293,7 +5302,7 @@ (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")) (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + "TARGET_POWERPC && TARGET_SINGLE_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && ! HONOR_SIGNED_ZEROS (SFmode)" "fnmadds %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -5303,7 +5312,8 @@ (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f"))))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD" "{fnma|fnmadd} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -5313,7 +5323,7 @@ (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f")))] "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD - && ! HONOR_SIGNED_ZEROS (SFmode)" + && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)" "{fnma|fnmadd} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -5323,7 +5333,7 @@ (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f"))))] "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (SFmode)" + && TARGET_SINGLE_FLOAT && HONOR_SIGNED_ZEROS (SFmode)" "fnmsubs %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -5333,7 +5343,7 @@ (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f"))))] "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD - && ! HONOR_SIGNED_ZEROS (SFmode)" + && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)" "fnmsubs %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -5342,7 +5352,8 @@ (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")) (match_operand:SF 3 "gpc_reg_operand" "f"))))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD" "{fnms|fnmsub} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -5352,27 +5363,31 @@ (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f"))))] "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD - && ! HONOR_SIGNED_ZEROS (SFmode)" + && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)" "{fnms|fnmsub} %0,%1,%2,%3" [(set_attr "type" "dmul")]) (define_expand "sqrtsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "") (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))] - "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS" + "(TARGET_PPC_GPOPT || TARGET_POWER2) + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT + && !TARGET_SIMPLE_FPU" "") (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT + && TARGET_FPRS && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" "fsqrts %0,%1" [(set_attr "type" "ssqrt")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_POWER2 && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_POWER2 && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" "fsqrt %0,%1" [(set_attr "type" "dsqrt")]) @@ -5405,7 +5420,7 @@ (match_dup 5)) (match_dup 3) (match_dup 4)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && !HONOR_NANS (SFmode) && !HONOR_SIGNED_ZEROS (SFmode)" { operands[3] = gen_reg_rtx (SFmode); @@ -5423,7 +5438,7 @@ (match_dup 5)) (match_dup 3) (match_dup 4)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !HONOR_NANS (DFmode) && !HONOR_SIGNED_ZEROS (DFmode)" { operands[3] = gen_reg_rtx (DFmode); @@ -5441,7 +5456,8 @@ (match_operand:SF 2 "gpc_reg_operand" "")) (match_dup 1) (match_dup 2)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && !flag_trapping_math" "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}") (define_expand "sminsf3" @@ -5450,7 +5466,8 @@ (match_operand:SF 2 "gpc_reg_operand" "")) (match_dup 2) (match_dup 1)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && !flag_trapping_math" "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}") (define_split @@ -5458,7 +5475,8 @@ (match_operator:SF 3 "min_max_operator" [(match_operand:SF 1 "gpc_reg_operand" "") (match_operand:SF 2 "gpc_reg_operand" "")]))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_SINGLE_FLOAT && !flag_trapping_math" [(const_int 0)] " { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), @@ -5519,7 +5537,7 @@ (if_then_else:SF (match_operand 1 "comparison_operator" "") (match_operand:SF 2 "gpc_reg_operand" "") (match_operand:SF 3 "gpc_reg_operand" "")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" " { if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) @@ -5534,7 +5552,7 @@ (match_operand:SF 4 "zero_fp_constant" "F")) (match_operand:SF 2 "gpc_reg_operand" "f") (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fsel %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -5544,40 +5562,40 @@ (match_operand:DF 4 "zero_fp_constant" "F")) (match_operand:SF 2 "gpc_reg_operand" "f") (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "fsel %0,%1,%2,%3" [(set_attr "type" "fp")]) (define_expand "negdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "") (neg:DF (match_operand:DF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" "") (define_insn "*negdf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "fneg %0,%1" [(set_attr "type" "fp")]) (define_expand "absdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "") (abs:DF (match_operand:DF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" "") (define_insn "*absdf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "fabs %0,%1" [(set_attr "type" "fp")]) (define_insn "*nabsdf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "fnabs %0,%1" [(set_attr "type" "fp")]) @@ -5585,14 +5603,14 @@ [(set (match_operand:DF 0 "gpc_reg_operand" "") (plus:DF (match_operand:DF 1 "gpc_reg_operand" "") (match_operand:DF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" "") (define_insn "*adddf3_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f") (match_operand:DF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "{fa|fadd} %0,%1,%2" [(set_attr "type" "fp")]) @@ -5600,14 +5618,14 @@ [(set (match_operand:DF 0 "gpc_reg_operand" "") (minus:DF (match_operand:DF 1 "gpc_reg_operand" "") (match_operand:DF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" "") (define_insn "*subdf3_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (minus:DF (match_operand:DF 1 "gpc_reg_operand" "f") (match_operand:DF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "{fs|fsub} %0,%1,%2" [(set_attr "type" "fp")]) @@ -5615,14 +5633,14 @@ [(set (match_operand:DF 0 "gpc_reg_operand" "") (mult:DF (match_operand:DF 1 "gpc_reg_operand" "") (match_operand:DF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" "") (define_insn "*muldf3_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") (match_operand:DF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "{fm|fmul} %0,%1,%2" [(set_attr "type" "dmul")]) @@ -5630,14 +5648,14 @@ [(set (match_operand:DF 0 "gpc_reg_operand" "") (div:DF (match_operand:DF 1 "gpc_reg_operand" "") (match_operand:DF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE) && !TARGET_SIMPLE_FPU" "") (define_insn "*divdf3_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (div:DF (match_operand:DF 1 "gpc_reg_operand" "f") (match_operand:DF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU" "{fd|fdiv} %0,%1,%2" [(set_attr "type" "ddiv")]) @@ -5665,7 +5683,7 @@ (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") (match_operand:DF 2 "gpc_reg_operand" "f")) (match_operand:DF 3 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT" "{fma|fmadd} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -5674,7 +5692,7 @@ (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") (match_operand:DF 2 "gpc_reg_operand" "f")) (match_operand:DF 3 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT" "{fms|fmsub} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -5683,7 +5701,7 @@ (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") (match_operand:DF 2 "gpc_reg_operand" "f")) (match_operand:DF 3 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT && HONOR_SIGNED_ZEROS (DFmode)" "{fnma|fnmadd} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -5693,7 +5711,7 @@ (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")) (match_operand:DF 2 "gpc_reg_operand" "f")) (match_operand:DF 3 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT && ! HONOR_SIGNED_ZEROS (DFmode)" "{fnma|fnmadd} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -5703,7 +5721,7 @@ (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") (match_operand:DF 2 "gpc_reg_operand" "f")) (match_operand:DF 3 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT && HONOR_SIGNED_ZEROS (DFmode)" "{fnms|fnmsub} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -5713,7 +5731,7 @@ (minus:DF (match_operand:DF 3 "gpc_reg_operand" "f") (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") (match_operand:DF 2 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT && ! HONOR_SIGNED_ZEROS (DFmode)" "{fnms|fnmsub} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -5721,7 +5739,8 @@ (define_insn "sqrtdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS" + "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_DOUBLE_FLOAT" "fsqrt %0,%1" [(set_attr "type" "dsqrt")]) @@ -5734,7 +5753,8 @@ (match_operand:DF 2 "gpc_reg_operand" "")) (match_dup 1) (match_dup 2)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !flag_trapping_math" "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}") (define_expand "smindf3" @@ -5743,7 +5763,8 @@ (match_operand:DF 2 "gpc_reg_operand" "")) (match_dup 2) (match_dup 1)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !flag_trapping_math" "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}") (define_split @@ -5751,7 +5772,8 @@ (match_operator:DF 3 "min_max_operator" [(match_operand:DF 1 "gpc_reg_operand" "") (match_operand:DF 2 "gpc_reg_operand" "")]))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && !flag_trapping_math" [(const_int 0)] " { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), @@ -5764,7 +5786,7 @@ (if_then_else:DF (match_operand 1 "comparison_operator" "") (match_operand:DF 2 "gpc_reg_operand" "") (match_operand:DF 3 "gpc_reg_operand" "")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" " { if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) @@ -5779,7 +5801,7 @@ (match_operand:DF 4 "zero_fp_constant" "F")) (match_operand:DF 2 "gpc_reg_operand" "f") (match_operand:DF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "fsel %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -5798,13 +5820,13 @@ (define_expand "fixuns_truncsfsi2" [(set (match_operand:SI 0 "gpc_reg_operand" "") (unsigned_fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && !TARGET_FPRS" + "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT" "") (define_expand "fix_truncsfsi2" [(set (match_operand:SI 0 "gpc_reg_operand" "") (fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && !TARGET_FPRS" + "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT" "") ; For each of these conversions, there is a define_expand, a define_insn @@ -5820,7 +5842,8 @@ (clobber (match_dup 4)) (clobber (match_dup 5)) (clobber (match_dup 6))])] - "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" + "TARGET_HARD_FLOAT + && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" " { if (TARGET_E500_DOUBLE) @@ -5850,7 +5873,7 @@ (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f")) (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" + "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "#" "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))" [(pc)] @@ -5879,7 +5902,7 @@ (define_expand "floatunssisf2" [(set (match_operand:SF 0 "gpc_reg_operand" "") (unsigned_float:SF (match_operand:SI 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && !TARGET_FPRS" + "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT" "") (define_expand "floatunssidf2" @@ -5889,7 +5912,7 @@ (use (match_dup 3)) (clobber (match_dup 4)) (clobber (match_dup 5))])] - "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" + "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" " { if (TARGET_E500_DOUBLE) @@ -5917,7 +5940,7 @@ (use (match_operand:DF 3 "gpc_reg_operand" "f")) (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" + "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "#" "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))" [(pc)] @@ -5947,7 +5970,7 @@ (clobber (match_dup 2)) (clobber (match_dup 3))])] "(TARGET_POWER2 || TARGET_POWERPC) - && TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" + && TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" " { if (TARGET_E500_DOUBLE) @@ -5983,7 +6006,8 @@ (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) (clobber (match_operand:DI 2 "gpc_reg_operand" "=f")) (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o"))] - "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS" + "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_DOUBLE_FLOAT" "#" "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[3]))" [(pc)] @@ -6004,7 +6028,8 @@ [(set (match_operand:SI 0 "memory_operand" "=Z") (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))] - "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS + "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_DOUBLE_FLOAT && TARGET_PPC_GFXOPT" "#" "&& 1" @@ -6022,7 +6047,8 @@ (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) (clobber (match_operand:DI 2 "gpc_reg_operand" "=f")) (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))] - "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_DOUBLE_FLOAT" "#" "&& 1" [(set (match_dup 2) (unspec:DI [(fix:SI (match_dup 1))] UNSPEC_FCTIWZ)) @@ -6039,63 +6065,64 @@ [(set (match_operand:DI 0 "gpc_reg_operand" "=f") (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))] UNSPEC_FCTIWZ))] - "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS" + "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_DOUBLE_FLOAT" "{fcirz|fctiwz} %0,%1" [(set_attr "type" "fp")]) (define_insn "btruncdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "friz %0,%1" [(set_attr "type" "fp")]) (define_insn "btruncsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT " "friz %0,%1" [(set_attr "type" "fp")]) (define_insn "ceildf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "frip %0,%1" [(set_attr "type" "fp")]) (define_insn "ceilsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT " "frip %0,%1" [(set_attr "type" "fp")]) (define_insn "floordf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "frim %0,%1" [(set_attr "type" "fp")]) (define_insn "floorsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT " "frim %0,%1" [(set_attr "type" "fp")]) (define_insn "rounddf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "frin %0,%1" [(set_attr "type" "fp")]) (define_insn "roundsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT " "frin %0,%1" [(set_attr "type" "fp")]) @@ -6111,27 +6138,27 @@ (define_expand "floatsisf2" [(set (match_operand:SF 0 "gpc_reg_operand" "") (float:SF (match_operand:SI 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && !TARGET_FPRS" + "TARGET_HARD_FLOAT && (!TARGET_FPRS || TARGET_SINGLE_FPU)" "") (define_insn "floatdidf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (float:DF (match_operand:DI 1 "gpc_reg_operand" "!f#r")))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "fcfid %0,%1" [(set_attr "type" "fp")]) (define_insn "fix_truncdfdi2" [(set (match_operand:DI 0 "gpc_reg_operand" "=!f#r") (fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "fctidz %0,%1" [(set_attr "type" "fp")]) (define_expand "floatdisf2" [(set (match_operand:SF 0 "gpc_reg_operand" "") (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT " " { rtx val = operands[1]; @@ -6153,7 +6180,7 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (float:SF (match_operand:DI 1 "gpc_reg_operand" "!f#r"))) (clobber (match_scratch:DF 2 "=f"))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "#" "&& reload_completed" [(set (match_dup 2) @@ -6187,7 +6214,7 @@ (label_ref (match_operand:DI 2 "" "")) (pc))) (set (match_dup 0) (match_dup 1))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" " { operands[3] = gen_reg_rtx (DImode); @@ -8219,7 +8246,7 @@ (match_operand:SF 1 "input_operand" "r,m,r,f,m,f,r,r,h,0,G,Fn"))] "(gpc_reg_operand (operands[0], SFmode) || gpc_reg_operand (operands[1], SFmode)) - && (TARGET_HARD_FLOAT && TARGET_FPRS)" + && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)" "@ mr %0,%1 {l%U1%X1|lwz%U1%X1} %0,%1 @@ -8357,7 +8384,7 @@ (define_insn "*movdf_hardfloat32" [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!r,!r,!r") (match_operand:DF 1 "input_operand" "r,m,r,f,m,f,G,H,F"))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS + "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" "* @@ -8452,7 +8479,9 @@ (define_insn "*movdf_softfloat32" [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r") (match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))] - "! TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || TARGET_E500_SINGLE) + "! TARGET_POWERPC64 + && ((TARGET_FPRS && !TARGET_DOUBLE_FLOAT) + || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE) && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" "* @@ -8495,7 +8524,8 @@ (define_insn "*movdf_hardfloat64_mfpgpr" [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r,r,f") (match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F,f,r"))] - "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS + "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" "@ @@ -8521,7 +8551,8 @@ (define_insn "*movdf_hardfloat64" [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r") (match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F"))] - "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS + "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" "@ @@ -8614,7 +8645,8 @@ (float_extend:TF (match_operand:DF 1 "input_operand" ""))) (use (match_dup 2))])] "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && TARGET_LONG_DOUBLE_128" { operands[2] = CONST0_RTX (DFmode); /* Generate GOT reference early for SVR4 PIC. */ @@ -8627,7 +8659,8 @@ (float_extend:TF (match_operand:DF 1 "input_operand" "fr,mf,mf,rmGHF"))) (use (match_operand:DF 2 "zero_reg_mem_operand" "rf,m,f,n"))] "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && TARGET_LONG_DOUBLE_128" "#" "&& reload_completed" [(pc)] @@ -8684,7 +8717,8 @@ [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))] "!TARGET_IEEEQUAD && TARGET_XL_COMPAT - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && TARGET_LONG_DOUBLE_128" "fadd %0,%1,%L1" [(set_attr "type" "fp")]) @@ -8708,7 +8742,8 @@ (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f"))) (clobber (match_scratch:DF 2 "=f"))] "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT + && TARGET_LONG_DOUBLE_128" "#" "&& reload_completed" [(set (match_dup 2) @@ -8738,7 +8773,7 @@ (unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "f")] UNSPEC_FIX_TRUNC_TF)) (clobber (match_operand:DF 2 "gpc_reg_operand" "=&f"))] - "TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2" [(set_attr "type" "fp") (set_attr "length" "20")]) @@ -8859,7 +8894,8 @@ (pc))) (set (match_dup 6) (neg:DF (match_dup 6)))] "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT + && TARGET_LONG_DOUBLE_128" " { const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode); @@ -10010,7 +10046,7 @@ (match_operand:SI 2 "reg_or_short_operand" "r,I")))) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE" "@ lfsux %3,%0,%2 lfsu %3,%2(%0)" @@ -10022,7 +10058,7 @@ (match_operand:SF 3 "gpc_reg_operand" "f,f")) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE" "@ stfsux %3,%0,%2 stfsu %3,%2(%0)" @@ -10058,7 +10094,7 @@ (match_operand:SI 2 "reg_or_short_operand" "r,I")))) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE" "@ lfdux %3,%0,%2 lfdu %3,%2(%0)" @@ -10070,7 +10106,7 @@ (match_operand:DF 3 "gpc_reg_operand" "f,f")) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE" "@ stfdux %3,%0,%2 stfdu %3,%2(%0)" @@ -10091,7 +10127,7 @@ (set (match_operand:DF 2 "gpc_reg_operand" "") (match_operand:DF 3 "memory_operand" ""))] "TARGET_POWER2 - && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && registers_ok_for_quad_peep (operands[0], operands[2]) && mems_ok_for_quad_peep (operands[1], operands[3])" [(set (match_dup 0) @@ -10113,7 +10149,7 @@ (set (match_operand:DF 2 "memory_operand" "") (match_operand:DF 3 "gpc_reg_operand" ""))] "TARGET_POWER2 - && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && registers_ok_for_quad_peep (operands[1], operands[3]) && mems_ok_for_quad_peep (operands[0], operands[2])" [(set (match_dup 0) @@ -11899,7 +11935,7 @@ [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") (compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fcmpu %0,%1,%2" [(set_attr "type" "fpcompare")]) @@ -11907,7 +11943,7 @@ [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f") (match_operand:DF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "fcmpu %0,%1,%2" [(set_attr "type" "fpcompare")]) @@ -11917,7 +11953,7 @@ (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f") (match_operand:TF 2 "gpc_reg_operand" "f")))] "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2" [(set_attr "type" "fpcompare") (set_attr "length" "12")]) @@ -11935,7 +11971,7 @@ (clobber (match_scratch:DF 9 "=f")) (clobber (match_scratch:DF 10 "=f"))] "!TARGET_IEEEQUAD && TARGET_XL_COMPAT - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" "#" "&& reload_completed" [(set (match_dup 3) (match_dup 13)) diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt index 6ad682fad2b..c036aeca441 100644 --- a/gcc/config/rs6000/rs6000.opt +++ b/gcc/config/rs6000/rs6000.opt @@ -260,3 +260,15 @@ Specify alignment of structure fields default/natural mprioritize-restricted-insns= Target RejectNegative Joined UInteger Var(rs6000_sched_restricted_insns_priority) Specify scheduling priority for dispatch slot restricted insns + +msingle-float +Target RejectNegative Var(rs6000_single_float) +Single-precision floating point unit + +mdouble-float +Target RejectNegative Var(rs6000_double_float) +Double-precision floating point unit + +msimple-fpu +Target RejectNegative Var(rs6000_simple_fpu) +Floating point unit does not support divide & sqrt diff --git a/gcc/config/rs6000/singlefp.h b/gcc/config/rs6000/singlefp.h new file mode 100644 index 00000000000..36e093c1a39 --- /dev/null +++ b/gcc/config/rs6000/singlefp.h @@ -0,0 +1,40 @@ +/* Definitions for PowerPC single-precision floating point unit + such as Xilinx PowerPC 405/440 APU. + + Copyright (C) 2008 Free Software Foundation, Inc. + Contributed by Michael Eager (eager@eagercon.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 3, 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 COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + + +/* Undefine definitions from rs6000.h. */ +#undef TARGET_SINGLE_FLOAT +#undef TARGET_DOUBLE_FLOAT +#undef TARGET_SINGLE_FPU +#undef TARGET_SIMPLE_FPU +#undef UNITS_PER_FP_WORD + +/* FPU operations supported. + If TARGET_SINGLE_FPU set, processor supports single fp options. */ +#define TARGET_SINGLE_FLOAT (rs6000_single_float) +#define TARGET_DOUBLE_FLOAT (rs6000_double_float) +#define TARGET_SINGLE_FPU 1 +#define TARGET_SIMPLE_FPU (rs6000_simple_fpu) + +/* FP word width depends on single/double fp support. */ +#define UNITS_PER_FP_WORD ((TARGET_SOFT_FLOAT || TARGET_DOUBLE_FLOAT) ? 8 : 4) + diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 05fc091009d..a289830a465 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -715,6 +715,7 @@ See RS/6000 and PowerPC Options. -m64 -m32 -mxl-compat -mno-xl-compat -mpe @gol -malign-power -malign-natural @gol -msoft-float -mhard-float -mmultiple -mno-multiple @gol +-msingle-float -mdouble-float -msimple-fpu @gol -mstring -mno-string -mupdate -mno-update @gol -mfused-madd -mno-fused-madd -mbit-align -mno-bit-align @gol -mstrict-align -mno-strict-align -mrelocatable @gol @@ -13419,7 +13420,8 @@ following options: @gccoptlist{-maltivec -mfprnd -mhard-float -mmfcrf -mmultiple @gol -mnew-mnemonics -mpopcntb -mpower -mpower2 -mpowerpc64 @gol --mpowerpc-gpopt -mpowerpc-gfxopt -mstring -mmulhw -mdlmzb -mmfpgpr} +-mpowerpc-gpopt -mpowerpc-gfxopt -msingle-float -mdouble-float @gol +-msimple-fpu -mstring -mmulhw -mdlmzb -mmfpgpr} The particular options set for any particular CPU will vary between compiler versions, depending on what setting seems to produce optimal @@ -13636,6 +13638,17 @@ Generate code that does not use (uses) the floating-point register set. Software floating point emulation is provided if you use the @option{-msoft-float} option, and pass the option to GCC when linking. +@item -msingle-float +@itemx -mdouble-float +@opindex msingle-float +@opindex mdouble-float +Generate code for single or double-precision floating point operations. +@option{-mdouble-float} implies @option{-msingle-float}. + +@item -msimple-fpu +@opindex msimple-fpu +Do not generate sqrt and div instructions for hardware floating point unit. + @item -mmultiple @itemx -mno-multiple @opindex mmultiple |