This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Support Xilinx PowerPC single-precision FPU


Joseph S. Myers wrote:
This patch uses out-of-date license notice text in xfpu.md.

Fixed.


--
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.c gcc/gcc/config/rs6000/rs6000.c
--- gcc-orig/gcc/config/rs6000/rs6000.c	2008-10-08 13:38:18.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.c	2008-10-08 13:38:27.000000000 -0700
@@ -145,6 +145,8 @@ struct rs6000_cpu_select rs6000_select[3
 
 static GTY(()) bool rs6000_cell_dont_microcode;
 
+enum fpu_type_t fpu_type = FPU_NONE;
+
 /* Always emit branch hint bits.  */
 static GTY(()) bool rs6000_always_hint;
 
@@ -225,6 +227,9 @@ enum rs6000_abi rs6000_current_abi;
 /* Whether to use variant of AIX ABI for PowerPC64 Linux.  */
 int dot_symbols;
 
+/* Whether Xilinx FPU is used. */
+int rs6000_xilinx_fpu;
+
 /* Debug flags */
 const char *rs6000_debug_name;
 int rs6000_debug_stack;		/* debug stack applications */
@@ -2199,6 +2204,18 @@ optimization_options (int level ATTRIBUT
     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
@@ -2523,6 +2540,30 @@ rs6000_handle_option (size_t code, const
       /* -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 -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.h gcc/gcc/config/rs6000/rs6000.h
--- gcc-orig/gcc/config/rs6000/rs6000.h	2008-10-08 13:38:18.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.h	2008-10-08 13:38:27.000000000 -0700
@@ -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 -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.md gcc/gcc/config/rs6000/rs6000.md
--- gcc-orig/gcc/config/rs6000/rs6000.md	2008-10-08 13:38:18.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.md	2008-10-08 13:38:27.000000000 -0700
@@ -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,23 @@
   "")
 
 (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"
-  "")
+  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
+	          (fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))
+	     (clobber (match_dup 2))
+	     (clobber (match_dup 3))
+	     (clobber (match_dup 4))])]
+  "TARGET_HARD_FLOAT && ! TARGET_DOUBLE_FLOAT && TARGET_FPRS 
+   && TARGET_SINGLE_FLOAT && TARGET_XILINX_FPU"
+  "
+  if (TARGET_XILINX_FPU) 
+    {
+      operands[2] = gen_reg_rtx (SFmode);
+      operands[3] = assign_stack_temp (SFmode, GET_MODE_SIZE (SFmode), 0);
+      operands[4] = gen_rtx_MEM (SImode, XEXP (operands[3], 0));
+      emit_insn (gen_xil_fix_truncsfsi2(operands[0], operands[1], operands[2], operands[3], operands[4]));
+      DONE;
+    }
+")
 
 ; 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 +6184,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 +8766,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 -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/rs6000.opt gcc/gcc/config/rs6000/rs6000.opt
--- gcc-orig/gcc/config/rs6000/rs6000.opt	2008-10-08 13:38:18.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.opt	2008-10-08 13:38:27.000000000 -0700
@@ -272,3 +272,13 @@ Double-precision floating point unit
 msimple-fpu
 Target RejectNegative Var(rs6000_simple_fpu)
 Floating point unit does not support divide & sqrt
+
+mfpu=
+Target RejectNegative Joined 
+-mfpu=	Specify FP (sp, dp, sp-lite, dp-lite) (implies -mxilinx-fpu)
+
+mxilinx-fpu
+Target Var(rs6000_xilinx_fpu)
+Specify Xilinx FPU.
+
+
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/sysv4.h gcc/gcc/config/rs6000/sysv4.h
--- gcc-orig/gcc/config/rs6000/sysv4.h	2008-10-08 13:38:18.000000000 -0700
+++ gcc/gcc/config/rs6000/sysv4.h	2008-10-08 13:38:27.000000000 -0700
@@ -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 -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/xfpu.h gcc/gcc/config/rs6000/xfpu.h
--- gcc-orig/gcc/config/rs6000/xfpu.h	1969-12-31 16:00:00.000000000 -0800
+++ gcc/gcc/config/rs6000/xfpu.h	2008-10-08 13:38:27.000000000 -0700
@@ -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 -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/xfpu.md gcc/gcc/config/rs6000/xfpu.md
--- gcc-orig/gcc/config/rs6000/xfpu.md	1969-12-31 16:00:00.000000000 -0800
+++ gcc/gcc/config/rs6000/xfpu.md	2008-10-08 13:40:34.000000000 -0700
@@ -0,0 +1,144 @@
+;; 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
+
+
+(automata_option "v")
+(automata_option "time")
+(automata_option "progress")
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config.gcc gcc/gcc/config.gcc
--- gcc-orig/gcc/config.gcc	2008-10-08 13:38:19.000000000 -0700
+++ gcc/gcc/config.gcc	2008-10-08 13:38:27.000000000 -0700
@@ -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 -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/doc/invoke.texi gcc/gcc/doc/invoke.texi
--- gcc-orig/gcc/doc/invoke.texi	2008-10-08 13:38:15.000000000 -0700
+++ gcc/gcc/doc/invoke.texi	2008-10-08 13:38:27.000000000 -0700
@@ -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-preci
 @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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]