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]

PowerPC -- single precision FP register constraint


The existing FP register constraint 'f' is used for both single-
and double-precision FP values.  This causes problems with
powerpc-xilinx-eabi, which has only single-precision FP regs.

The attached patch creates a new register constraint 'd'
for FP registers containing double-precision values.
For a "classic" PowerPC which has double-precision FP regs,
this defaults to FLOAT_REGS, exactly the same as the 'f'
constraint.  For a PowerPC which only has single-precision
FP regs, this defaults to NO_REGS.

This passes regression tests with --target=powerpc-eabisim.

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

	* config/rs6000/constraints.md: register_constraint "d": New.
	* config/rs6000/dfp.md: floatditd2, fixdddi2, fixtddi2: replace 'f'
	constraint with 'd'
	* config/rs6000/rs6000.md: *fix_truncdfsi2_internal,
	fix_truncdfsi2_internal_gfxopt, fix_truncdfsi2_mfpgpr, fctiwz, stfiwx, 
	floatdidf2, fix_truncdfdi2, floatdisf2_internal1,
	*fix_trunctfsi2_internal, *movdi_internal32, *movdi_mfpgpr,
	*movdi_internal64: Same.
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-04-02 13:22:26.000000000 -0700
+++ gcc/gcc/config/rs6000/constraints.md	2009-04-02 13:22:59.000000000 -0700
@@ -23,6 +23,10 @@
 			 	 ? FLOAT_REGS : NO_REGS"
   "@internal")
 
+(define_register_constraint "d" "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+			 	 ? FLOAT_REGS : NO_REGS"
+  "@internal")
+
 (define_register_constraint "b" "BASE_REGS"
   "@internal")
 
diff -urNp --exclude '*.swp' --exclude DEV-PHASE --exclude .svn gcc-orig/gcc/config/rs6000/dfp.md gcc/gcc/config/rs6000/dfp.md
--- gcc-orig/gcc/config/rs6000/dfp.md	2009-04-02 13:22:26.000000000 -0700
+++ gcc/gcc/config/rs6000/dfp.md	2009-04-02 13:22:59.000000000 -0700
@@ -641,7 +641,7 @@
 
 (define_insn "floatditd2"
   [(set (match_operand:TD 0 "gpc_reg_operand" "=f")
-	(float:TD (match_operand:DI 1 "gpc_reg_operand" "f")))]
+	(float:TD (match_operand:DI 1 "gpc_reg_operand" "d")))]
   "TARGET_DFP"
   "dcffixq %0,%1"
   [(set_attr "type" "fp")])
@@ -660,8 +660,8 @@
 ;; This is the second stage of converting decimal float to integer type.
 
 (define_insn "fixdddi2"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
-	(fix:DI (match_operand:DD 1 "gpc_reg_operand" "f")))]
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
+	(fix:DI (match_operand:DD 1 "gpc_reg_operand" "d")))]
   "TARGET_DFP"
   "dctfix %0,%1"
   [(set_attr "type" "fp")])
@@ -680,7 +680,7 @@
 ;; This is the second stage of converting decimal float to integer type.
 
 (define_insn "fixtddi2"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
 	(fix:DI (match_operand:TD 1 "gpc_reg_operand" "f")))]
   "TARGET_DFP"
   "dctfixq %0,%1"
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-04-02 13:22:26.000000000 -0700
+++ gcc/gcc/config/rs6000/rs6000.md	2009-04-02 13:22:59.000000000 -0700
@@ -6073,7 +6073,7 @@
 (define_insn_and_split "*fix_truncdfsi2_internal"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
-   (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
+   (clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))
    (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o"))]
   "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
    && TARGET_DOUBLE_FLOAT"
@@ -6096,7 +6096,7 @@
 (define_insn_and_split "fix_truncdfsi2_internal_gfxopt"
   [(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"))]
+   (clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))]
   "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
    && TARGET_DOUBLE_FLOAT 
    && TARGET_PPC_GFXOPT"
@@ -6114,7 +6114,7 @@
 (define_insn_and_split "fix_truncdfsi2_mfpgpr"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
 	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
-   (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
+   (clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))
    (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))]
   "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 
    && TARGET_DOUBLE_FLOAT"
@@ -6131,8 +6131,8 @@
 ; because the first makes it clear that operand 0 is not live
 ; before the instruction.
 (define_insn "fctiwz"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
-	(unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))]
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
+	(unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "d"))]
 		   UNSPEC_FCTIWZ))]
   "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 
    && TARGET_DOUBLE_FLOAT"
@@ -6198,7 +6198,7 @@
 ; An UNSPEC is used so we don't have to support SImode in FP registers.
 (define_insn "stfiwx"
   [(set (match_operand:SI 0 "memory_operand" "=Z")
-	(unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "f")]
+	(unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
 		   UNSPEC_STFIWX))]
   "TARGET_PPC_GFXOPT"
   "stfiwx %1,%y0"
@@ -6212,14 +6212,14 @@
 
 (define_insn "floatdidf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
-	(float:DF (match_operand:DI 1 "gpc_reg_operand" "!f#r")))]
+	(float:DF (match_operand:DI 1 "gpc_reg_operand" "!d#r")))]
   "(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")))]
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=!d#r")
+	(fix:DI (match_operand:DF 1 "gpc_reg_operand" "d")))]
   "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
   "fctidz %0,%1"
   [(set_attr "type" "fp")])
@@ -6247,7 +6247,7 @@
 ;; from double rounding.
 (define_insn_and_split "floatdisf2_internal1"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
-        (float:SF (match_operand:DI 1 "gpc_reg_operand" "!f#r")))
+        (float:SF (match_operand:DI 1 "gpc_reg_operand" "!d#r")))
    (clobber (match_scratch:DF 2 "=f"))]
   "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
   "#"
@@ -8908,7 +8908,7 @@
         (fix:SI (match_operand:TF 1 "gpc_reg_operand" "f")))
    (clobber (match_operand:DF 2 "gpc_reg_operand" "=f"))
    (clobber (match_operand:DF 3 "gpc_reg_operand" "=&f"))
-   (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))
+   (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
    (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
   "!TARGET_IEEEQUAD
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
@@ -9004,8 +9004,8 @@
 ; List r->r after r->"o<>", otherwise reload will try to reload a
 ; non-offsettable address by using r->r which won't make progress.
 (define_insn "*movdi_internal32"
-  [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=o<>,r,r,*f,*f,m,r")
-	(match_operand:DI 1 "input_operand" "r,r,m,f,m,f,IJKnGHF"))]
+  [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=o<>,r,r,*d,*d,m,r")
+	(match_operand:DI 1 "input_operand" "r,r,m,d,m,d,IJKnGHF"))]
   "! TARGET_POWERPC64
    && (gpc_reg_operand (operands[0], DImode)
        || gpc_reg_operand (operands[1], DImode))"
@@ -9049,8 +9049,8 @@
 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
 
 (define_insn "*movdi_mfpgpr"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*f,*f,m,r,*h,*h,r,*f")
-	(match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,f,m,f,*h,r,0,*f,r"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*d,*d,m,r,*h,*h,r,*d")
+	(match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,d,m,d,*h,r,0,*d,r"))]
   "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
    && (gpc_reg_operand (operands[0], DImode)
        || gpc_reg_operand (operands[1], DImode))"
@@ -9074,8 +9074,8 @@
    (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4")])
 
 (define_insn "*movdi_internal64"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*f,*f,m,r,*h,*h")
-	(match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,f,m,f,*h,r,0"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*d,*d,m,r,*h,*h")
+	(match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,d,m,d,*h,r,0"))]
   "TARGET_POWERPC64 && (!TARGET_MFPGPR || !TARGET_HARD_FLOAT || !TARGET_FPRS)
    && (gpc_reg_operand (operands[0], DImode)
        || gpc_reg_operand (operands[1], DImode))"

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