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]

FPU erratum fix for PPC405 powerpc-xilinx-eabi


The FPU attached Xilinx PowerPC 405 core has an erratum:
Only the CR1 register can be set by FP compare instructions.

The attached patch creates a new register class CR1_REGS which
contains only CR1, a new constraint "e" which is set to CR1_REGS
when -mcpu=405 and -mfpu=*, and to CR_REGS otherwise, only in
--target=powerpc-xilinx-eabi, and to CR_REGS for all other PowerPC
targets.  The FP compare templates are changed to use constraint "e"
instead of "y" which is CR_REGS.

--
Michael Eager	 eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306  650-325-8077
2009-01-26  Michael Eager <eager@eagercon.com>

	* config/rs6000/constraints.md: constraint "e": New, CR1_REGS if
	XILINX_FPU_CR1_FIX set, else CR_REGS.
	* config/rs6000/rs6000.h: XILINX_FPU_CR1_FIX, CR1_REGS: New,
	enum reg_class: add mask for CR1_REGS
	* config/rs6000/rs6000.md: *cmpsf_internal1, *cmpdf_internal1, 
	*cmptf_internal1, *cmptf_internal2: convert "y" constraint (CR_REGS)
	to "e" contstraint.
	* config/rs6000/xilinx.h: XILINX_FPU_CR1_FIX: New, set if PPC405 and
	rs6000_xilinx_fpu
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/constraints.md gcc/gcc/config/rs6000/constraints.md
--- gcc-orig/gcc/config/rs6000/constraints.md	2009-01-22 10:19:54.000000000 -0800
+++ gcc/gcc/config/rs6000/constraints.md	2009-01-22 10:22:55.000000000 -0800
@@ -44,6 +44,9 @@
 (define_register_constraint "x" "CR0_REGS"
   "@internal")
 
+(define_register_constraint "e" "XILINX_FPU_CR1_FIX ? CR1_REGS : CR_REGS"
+  "@internal")
+
 (define_register_constraint "y" "CR_REGS"
   "@internal")
 
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	2009-01-22 10:19:54.000000000 -0800
+++ gcc/gcc/config/rs6000/rs6000.h	2009-01-22 10:22:55.000000000 -0800
@@ -56,6 +56,9 @@
 #define PPC405_ERRATUM77 0
 #endif
 
+/* If set, fix Xilinx PowerPC 405 FPU CR1 erratum. */
+#define XILINX_FPU_CR1_FIX 0
+
 #ifndef TARGET_PAIRED_FLOAT
 #define TARGET_PAIRED_FLOAT 0
 #endif
@@ -1085,6 +1088,7 @@ enum reg_class
   SPECIAL_REGS,
   SPEC_OR_GEN_REGS,
   CR0_REGS,
+  CR1_REGS,
   CR_REGS,
   NON_FLOAT_REGS,
   XER_REGS,
@@ -1115,6 +1119,7 @@ enum reg_class
   "SPECIAL_REGS",							\
   "SPEC_OR_GEN_REGS",							\
   "CR0_REGS",								\
+  "CR1_REGS",								\
   "CR_REGS",								\
   "NON_FLOAT_REGS",							\
   "XER_REGS",								\
@@ -1144,6 +1149,7 @@ enum reg_class
   { 0x00000000, 0x00000000, 0x00000007, 0x00002000 }, /* SPECIAL_REGS */     \
   { 0xffffffff, 0x00000000, 0x0000000f, 0x00022000 }, /* SPEC_OR_GEN_REGS */ \
   { 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */	     \
+  { 0x00000000, 0x00000000, 0x00000020, 0x00000000 }, /* CR1_REGS */	     \
   { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */	     \
   { 0xffffffff, 0x00000000, 0x0000efff, 0x00020000 }, /* NON_FLOAT_REGS */   \
   { 0x00000000, 0x00000000, 0x00001000, 0x00000000 }, /* XER_REGS */	     \
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	2009-01-22 10:19:54.000000000 -0800
+++ gcc/gcc/config/rs6000/rs6000.md	2009-01-22 10:22:55.000000000 -0800
@@ -12188,7 +12188,7 @@
    (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
 
 (define_insn "*cmpsf_internal1"
-  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+  [(set (match_operand:CCFP 0 "cc_reg_operand" "=e")
 	(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
 		      (match_operand:SF 2 "gpc_reg_operand" "f")))]
   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
@@ -12196,7 +12196,7 @@
   [(set_attr "type" "fpcompare")])
 
 (define_insn "*cmpdf_internal1"
-  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+  [(set (match_operand:CCFP 0 "cc_reg_operand" "=e")
 	(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
 		      (match_operand:DF 2 "gpc_reg_operand" "f")))]
   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
@@ -12205,7 +12205,7 @@
 
 ;; Only need to compare second words if first words equal
 (define_insn "*cmptf_internal1"
-  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+  [(set (match_operand:CCFP 0 "cc_reg_operand" "=e")
 	(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f")
 		      (match_operand:TF 2 "gpc_reg_operand" "f")))]
   "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
@@ -12215,7 +12215,7 @@
    (set_attr "length" "12")])
 
 (define_insn_and_split "*cmptf_internal2"
-  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+  [(set (match_operand:CCFP 0 "cc_reg_operand" "=e")
 	(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f")
 		      (match_operand:TF 2 "gpc_reg_operand" "f")))
     (clobber (match_scratch:DF 3 "=f"))
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/xilinx.h gcc/gcc/config/rs6000/xilinx.h
--- gcc-orig/gcc/config/rs6000/xilinx.h	2009-01-22 10:19:54.000000000 -0800
+++ gcc/gcc/config/rs6000/xilinx.h	2009-01-22 10:22:55.000000000 -0800
@@ -36,3 +36,5 @@ ecrti.o%s %{pg: %{!mno-clearbss: xil-pgc
 
 #undef	LINK_START_DEFAULT_SPEC
 #define LINK_START_DEFAULT_SPEC "-T xilinx.ld%s"
+
+#define XILINX_FPU_CR1_FIX ((rs6000_cpu == PROCESSOR_PPC405) && rs6000_xilinx_fpu)

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