diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/config.gcc | 5 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 38 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 14 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 104 | ||||
-rw-r--r-- | gcc/config/rs6000/sysv4.h | 3 | ||||
-rw-r--r-- | gcc/config/rs6000/xfpu.h | 26 | ||||
-rw-r--r-- | gcc/config/rs6000/xfpu.md | 140 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 12 |
9 files changed, 327 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 410dc97c7b3..709013084dc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2008-10-11 Michael J. Eager <eager@eagercon.com> + + * config/rs6000/rs6000.c (rs6000_parse_fpu_option): Interpret + -mfpu options. + (rs6000_handle_option): Process -mfpu options. + * config/rs6000/rs6000.h: (TARGET_XILINX_FPU): New. + (enum fpu_type_t): New. + * config/rs6000/rs6000.md (attr fp_type): New. + Include xfpu.md. + (addsf3, subsf3, mulsf3, adddf3, subdf3, muldf3, trunctfdf2): Set + fp_type. + (floatsisf2): Remove TARGET_SINGLE_FPU condition. + (floatdidf2): Add TARGET_SINGLE_FPU condition. + * config/rs6000/rs6000.opt (-mfpu): New. + (-mxilinx-fpu): New. + * config/rs6000/sysv4.h: (DRIVER_SELF_SPECS): New. + * config/rs6000/xfpu.h: New. Define TARGET_XILINX_FPU. + * config/rs6000/xfpu.md: New. Define Xilinx pipeline. + * gcc/config.gcc: powerpc-xilinx-eabi target: New. + * gcc/doc/invoke.texi (RS/6000 and PowerPC Options): Add -mfpu option. + 2008-10-11 Jakub Jelinek <jakub@redhat.com> PR target/35760 diff --git a/gcc/config.gcc b/gcc/config.gcc index 37afa852abb..8f31bdef144 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1899,6 +1899,11 @@ powerpcle-*-eabi*) tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm" extra_options="${extra_options} rs6000/sysv4.opt" ;; +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 rs6000/xfpu.h" + extra_options="${extra_options} rs6000/sysv4.opt" + tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm" + ;; rs6000-ibm-aix4.[12]* | powerpc-ibm-aix4.[12]*) tm_file="${tm_file} rs6000/aix.h rs6000/aix41.h rs6000/xcoff.h" tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-newas" diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 1218ea9b9b0..49828de96e4 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -2199,11 +2199,25 @@ optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED) flag_section_anchors = 2; } +static enum fpu_type_t +rs6000_parse_fpu_option (const char *option) +{ + if (!strcmp("none", option)) return FPU_NONE; + if (!strcmp("sp_lite", option)) return FPU_SF_LITE; + if (!strcmp("dp_lite", option)) return FPU_DF_LITE; + if (!strcmp("sp_full", option)) return FPU_SF_FULL; + if (!strcmp("dp_full", option)) return FPU_DF_FULL; + error("unknown value %s for -mfpu", option); + return FPU_NONE; +} + /* Implement TARGET_HANDLE_OPTION. */ static bool rs6000_handle_option (size_t code, const char *arg, int value) { + enum fpu_type_t fpu_type = FPU_NONE; + switch (code) { case OPT_mno_power: @@ -2523,6 +2537,30 @@ rs6000_handle_option (size_t code, const char *arg, int value) /* -msoft_float implies -mnosingle-float and -mnodouble-float. */ rs6000_single_float = rs6000_double_float = 0; break; + + case OPT_mfpu_: + fpu_type = rs6000_parse_fpu_option(arg); + if (fpu_type != FPU_NONE) + /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */ + { + target_flags &= ~MASK_SOFT_FLOAT; + target_flags_explicit |= MASK_SOFT_FLOAT; + rs6000_xilinx_fpu = 1; + if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL) + rs6000_single_float = 1; + if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL) + rs6000_single_float = rs6000_double_float = 1; + if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE) + rs6000_simple_fpu = 1; + } + else + { + /* -mfpu=none is equivalent to -msoft-float */ + target_flags |= MASK_SOFT_FLOAT; + target_flags_explicit |= MASK_SOFT_FLOAT; + rs6000_single_float = rs6000_double_float = 0; + } + break; } return true; } diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 39fc0f6c9b6..de212cd9c05 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -305,6 +305,7 @@ enum processor_type #define TARGET_DOUBLE_FLOAT 1 #define TARGET_SINGLE_FPU 0 #define TARGET_SIMPLE_FPU 0 +#define TARGET_XILINX_FPU 0 extern enum processor_type rs6000_cpu; @@ -321,6 +322,18 @@ extern enum processor_type rs6000_cpu; #define PROCESSOR_DEFAULT PROCESSOR_RIOS1 #define PROCESSOR_DEFAULT64 PROCESSOR_RS64A +/* FP processor type. */ +enum fpu_type_t +{ + FPU_NONE, /* No FPU */ + FPU_SF_LITE, /* Limited Single Precision FPU */ + FPU_DF_LITE, /* Limited Double Precision FPU */ + FPU_SF_FULL, /* Full Single Precision FPU */ + FPU_DF_FULL /* Full Double Single Precision FPU */ +}; + +extern enum fpu_type_t fpu_type; + /* Specify the dialect of assembler to use. New mnemonics is dialect one and the old mnemonics are dialect zero. */ #define ASSEMBLER_DIALECT (TARGET_NEW_MNEMONICS ? 1 : 0) @@ -393,6 +406,7 @@ extern int rs6000_float_gprs; extern int rs6000_alignment_flags; extern const char *rs6000_sched_insert_nops_str; extern enum rs6000_nop_insertion rs6000_sched_insert_nops; +extern int rs6000_xilinx_fpu; /* Alignment options for fields in structures for sub-targets following AIX-like ABI. diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 044b11765e9..7b0f1a131c9 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -119,6 +119,9 @@ (define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,var_delayed_compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr" (const_string "integer")) +;; Define floating point instruction sub-types for use with Xfpu.md +(define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default")) + ;; Length (in bytes). ; '(pc)' in the following doesn't include the instruction itself; it is ; calculated as if the instruction had zero size. @@ -174,6 +177,7 @@ (include "power5.md") (include "power6.md") (include "cell.md") +(include "xfpu.md") (include "predicates.md") (include "constraints.md") @@ -5149,7 +5153,8 @@ (match_operand:SF 2 "gpc_reg_operand" "f")))] "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fadds %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_addsub_s")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") @@ -5157,7 +5162,8 @@ (match_operand:SF 2 "gpc_reg_operand" "f")))] "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "{fa|fadd} %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_addsub_d")]) (define_expand "subsf3" [(set (match_operand:SF 0 "gpc_reg_operand" "") @@ -5172,7 +5178,8 @@ (match_operand:SF 2 "gpc_reg_operand" "f")))] "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fsubs %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_addsub_s")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") @@ -5180,7 +5187,8 @@ (match_operand:SF 2 "gpc_reg_operand" "f")))] "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "{fs|fsub} %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_addsub_d")]) (define_expand "mulsf3" [(set (match_operand:SF 0 "gpc_reg_operand" "") @@ -5195,7 +5203,8 @@ (match_operand:SF 2 "gpc_reg_operand" "f")))] "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "fmuls %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_mul_s")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") @@ -5203,7 +5212,8 @@ (match_operand:SF 2 "gpc_reg_operand" "f")))] "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "{fm|fmul} %0,%1,%2" - [(set_attr "type" "dmul")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_mul_d")]) (define_expand "divsf3" [(set (match_operand:SF 0 "gpc_reg_operand" "") @@ -5257,7 +5267,8 @@ "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD" "fmadds %0,%1,%2,%3" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_maddsub_s")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") @@ -5267,7 +5278,8 @@ "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD" "{fma|fmadd} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") @@ -5277,7 +5289,8 @@ "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD" "fmsubs %0,%1,%2,%3" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_maddsub_s")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") @@ -5287,7 +5300,8 @@ "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD" "{fms|fmsub} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") @@ -5297,7 +5311,8 @@ "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_SINGLE_FLOAT && HONOR_SIGNED_ZEROS (SFmode)" "fnmadds %0,%1,%2,%3" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_maddsub_s")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") @@ -5307,7 +5322,8 @@ "TARGET_POWERPC && TARGET_SINGLE_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && ! HONOR_SIGNED_ZEROS (SFmode)" "fnmadds %0,%1,%2,%3" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_maddsub_s")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") @@ -5317,7 +5333,8 @@ "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD" "{fnma|fnmadd} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") @@ -5327,7 +5344,8 @@ "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)" "{fnma|fnmadd} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") @@ -5337,7 +5355,8 @@ "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_SINGLE_FLOAT && HONOR_SIGNED_ZEROS (SFmode)" "fnmsubs %0,%1,%2,%3" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_maddsub_s")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") @@ -5347,7 +5366,8 @@ "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)" "fnmsubs %0,%1,%2,%3" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_maddsub_s")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") @@ -5357,7 +5377,8 @@ "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD" "{fnms|fnmsub} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") @@ -5372,7 +5393,7 @@ (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_PPC_GPOPT || TARGET_POWER2 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" "") @@ -5380,7 +5401,7 @@ (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_PPC_GPOPT || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" "fsqrts %0,%1" [(set_attr "type" "ssqrt")]) @@ -5614,7 +5635,8 @@ (match_operand:DF 2 "gpc_reg_operand" "f")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "{fa|fadd} %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_addsub_d")]) (define_expand "subdf3" [(set (match_operand:DF 0 "gpc_reg_operand" "") @@ -5629,7 +5651,8 @@ (match_operand:DF 2 "gpc_reg_operand" "f")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "{fs|fsub} %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_addsub_d")]) (define_expand "muldf3" [(set (match_operand:DF 0 "gpc_reg_operand" "") @@ -5644,7 +5667,9 @@ (match_operand:DF 2 "gpc_reg_operand" "f")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" "{fm|fmul} %0,%1,%2" - [(set_attr "type" "dmul")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_mul_d")]) + (define_expand "divdf3" [(set (match_operand:DF 0 "gpc_reg_operand" "") @@ -5687,7 +5712,8 @@ (match_operand:DF 3 "gpc_reg_operand" "f")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT" "{fma|fmadd} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") @@ -5696,7 +5722,8 @@ (match_operand:DF 3 "gpc_reg_operand" "f")))] "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT" "{fms|fmsub} %0,%1,%2,%3" - [(set_attr "type" "dmul")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") @@ -5706,7 +5733,8 @@ "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")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") @@ -5716,7 +5744,8 @@ "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")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") @@ -5726,7 +5755,8 @@ "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")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") @@ -5736,7 +5766,8 @@ "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")]) + [(set_attr "type" "dmul") + (set_attr "fp_type" "fp_maddsub_d")]) (define_insn "sqrtdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") @@ -5826,10 +5857,10 @@ "") (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_SINGLE_FLOAT" - "") + [(set (match_operand:SI 0 "gpc_reg_operand" "") + (fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT" + "") ; For each of these conversions, there is a define_expand, a define_insn ; with a '#' template, and a define_split (with C code). The idea is @@ -6140,20 +6171,20 @@ (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_SINGLE_FPU)" + "TARGET_HARD_FLOAT && !TARGET_FPRS" "") (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_DOUBLE_FLOAT" + "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" "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_DOUBLE_FLOAT" + "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" "fctidz %0,%1" [(set_attr "type" "fp")]) @@ -8722,7 +8753,8 @@ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" "fadd %0,%1,%L1" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "fp_type" "fp_addsub_d")]) (define_expand "trunctfsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "") diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h index b94de3bbbf4..8e309803cd9 100644 --- a/gcc/config/rs6000/sysv4.h +++ b/gcc/config/rs6000/sysv4.h @@ -729,6 +729,9 @@ extern int fixuplabelno; #define LINK_OS_DEFAULT_SPEC "" +#define DRIVER_SELF_SPECS "%{mfpu=none: %<mfpu=* \ + %<msingle-float %<mdouble-float}" + /* Override rs6000.h definition. */ #undef CPP_SPEC #define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \ diff --git a/gcc/config/rs6000/xfpu.h b/gcc/config/rs6000/xfpu.h new file mode 100644 index 00000000000..af631163634 --- /dev/null +++ b/gcc/config/rs6000/xfpu.h @@ -0,0 +1,26 @@ +/* Definitions for 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_XILINX_FPU + +#define TARGET_XILINX_FPU (rs6000_xilinx_fpu) diff --git a/gcc/config/rs6000/xfpu.md b/gcc/config/rs6000/xfpu.md new file mode 100644 index 00000000000..25c449a515a --- /dev/null +++ b/gcc/config/rs6000/xfpu.md @@ -0,0 +1,140 @@ +;; Scheduling description for the Xilinx PowerPC 405 APU Floating Point Unit. +;; 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/>. + +;;---------------------------------------------------- +;; Xilinx APU FPU Pipeline Description +;; +;; - attr 'type' and 'fp_type' should definitely +;; be cleaned up at some point in the future. +;; ddiv,sdiv,dmul,smul etc are quite confusing. +;; Should use consistent fp* attrs. 'fp_type' +;; should also go away, leaving us only with 'fp' +;; +;;---------------------------------------------------- + +;; ------------------------------------------------------------------------- +;; Latencies +;; Latest latency figures (all in FCB cycles). PowerPC to FPU frequency ratio +;; assumed to be 1/2. (most common deployment) +;; Add 2 PPC cycles for (register file access + wb) and 2 PPC cycles +;; for issue (from PPC) +;; SP DP +;; Loads: 4 6 +;; Stores: 1 2 (from availability of data) +;; Move/Abs/Neg: 1 1 +;; Add/Subtract: 5 7 +;; Multiply: 4 11 +;; Multiply-add: 10 19 +;; Convert (any): 4 6 +;; Divide/Sqrt: 27 56 +;; Compares: 1 2 +;; +;; bypasses needed for forwarding capability of the FPU. +;; Add this at some future time. +;; ------------------------------------------------------------------------- +(define_automaton "Xfpu") +(define_cpu_unit "Xfpu_issue,Xfpu_addsub,Xfpu_mul,Xfpu_div,Xfpu_sqrt" "Xfpu") + + +(define_insn_reservation "fp-default" 2 + (and (and + (eq_attr "type" "fp") + (eq_attr "fp_type" "fp_default")) + (eq_attr "cpu" "ppc405")) + "Xfpu_issue*2") + +(define_insn_reservation "fp-compare" 6 + (and (eq_attr "type" "fpcompare") ;; Inconsistent naming + (eq_attr "cpu" "ppc405")) + "Xfpu_issue*2,Xfpu_addsub") + +(define_insn_reservation "fp-addsub-s" 14 + (and (and + (eq_attr "type" "fp") + (eq_attr "fp_type" "fp_addsub_s")) + (eq_attr "cpu" "ppc405")) + "Xfpu_issue*2,Xfpu_addsub") + +(define_insn_reservation "fp-addsub-d" 18 + (and (and + (eq_attr "type" "fp") + (eq_attr "fp_type" "fp_addsub_d")) + (eq_attr "cpu" "ppc405")) + "Xfpu_issue*2,Xfpu_addsub") + +(define_insn_reservation "fp-mul-s" 12 + (and (and + (eq_attr "type" "fp") + (eq_attr "fp_type" "fp_mul_s")) + (eq_attr "cpu" "ppc405")) + "Xfpu_issue*2,Xfpu_mul") + +(define_insn_reservation "fp-mul-d" 16 ;; Actually 28. Long latencies are killing the automaton formation. Need to figure out why. + (and (and + (eq_attr "type" "fp") + (eq_attr "fp_type" "fp_mul_d")) + (eq_attr "cpu" "ppc405")) + "Xfpu_issue*2,Xfpu_mul") + +(define_insn_reservation "fp-div-s" 24 ;; Actually 34 + (and (eq_attr "type" "sdiv") ;; Inconsistent attr naming + (eq_attr "cpu" "ppc405")) + "Xfpu_issue*2,Xfpu_div*10") ;; Unpipelined + +(define_insn_reservation "fp-div-d" 34 ;; Actually 116 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppc405")) ;; Inconsistent attr naming + "Xfpu_issue*2,Xfpu_div*10") ;; Unpipelined + +(define_insn_reservation "fp-maddsub-s" 24 + (and (and + (eq_attr "type" "fp") + (eq_attr "fp_type" "fp_maddsub_s")) + (eq_attr "cpu" "ppc405")) + "Xfpu_issue*2,Xfpu_mul,nothing*7,Xfpu_addsub") + +(define_insn_reservation "fp-maddsub-d" 34 ;; Actually 42 + (and (and + (eq_attr "type" "dmul") ;; Inconsistent attr naming + (eq_attr "fp_type" "fp_maddsub_d")) + (eq_attr "cpu" "ppc405")) + "Xfpu_issue*2,Xfpu_mul,nothing*7,Xfpu_addsub") + +(define_insn_reservation "fp-load" 10 ;; FIXME. Is double/single precision the same ? + (and (eq_attr "type" "fpload, fpload_ux, fpload_u") + (eq_attr "cpu" "ppc405")) + "Xfpu_issue*10") + +(define_insn_reservation "fp-store" 4 + (and (eq_attr "type" "fpstore, fpstore_ux, fpstore_u") + (eq_attr "cpu" "ppc405")) + "Xfpu_issue*4") + +(define_insn_reservation "fp-sqrt-s" 24 ;; Actually 56 + (and (eq_attr "type" "ssqrt") + (eq_attr "cpu" "ppc405")) + "Xfpu_issue*2,Xfpu_sqrt*10") ;; Unpipelined + + +(define_insn_reservation "fp-sqrt-d" 34 ;; Actually 116 + (and (eq_attr "type" "dsqrt") + (eq_attr "cpu" "ppc405")) + "Xfpu_issue*2,Xfpu_sqrt*10") ;; Unpipelined + diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 755c4222615..c5c47fed86f 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -649,6 +649,7 @@ Objective-C and Objective-C++ Dialects}. -mshared -mno-shared -mplt -mno-plt -mxgot -mno-xgot @gol -mgp32 -mgp64 -mfp32 -mfp64 -mhard-float -msoft-float @gol -msingle-float -mdouble-float -mdsp -mno-dsp -mdspr2 -mno-dspr2 @gol +-mfpu=@var{fpu-type} @gol -msmartmips -mno-smartmips @gol -mpaired-single -mno-paired-single -mdmx -mno-mdmx @gol -mips3d -mno-mips3d -mmt -mno-mt -mllsc -mno-llsc @gol @@ -13656,6 +13657,17 @@ Generate code for single or double-precision floating point operations. @opindex msimple-fpu Do not generate sqrt and div instructions for hardware floating point unit. +@item -mfpu +@opindex mfpu +Specify type of floating point unit. Valid values are @var{sp_lite} +(equivalent to -msingle-float -msimple-fpu), @var{dp_lite} (equivalent +to -mdouble-float -msimple-fpu), @var{sp_full} (equivalent to -msingle-float), +and @var{dp_full} (equivalent to -mdouble-float). + +@item -mxilinx-fpu +@opindex mxilinx-fpu +Perform optimizations for floating point unit on Xilinx PPC 405/440. + @item -mmultiple @itemx -mno-multiple @opindex mmultiple |