This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
FPU erratum fix for PPC405 powerpc-xilinx-eabi
- From: Michael Eager <eager at eagercon dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 26 Jan 2009 09:08:11 -0800
- Subject: 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)