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: patch: reject incompatible classes in simplify_subreg


On Mon, Dec 06, 2004 at 06:54:58PM -0400, Aldy Hernandez wrote:
> The problem here in this testcase is that operand_subword is called on: 
> 
> 	(subreg:DI (reg:DF 122 [ a ]) 0)
> 
> Down the call chain we call simplify_subreg, reducing the above into 
> (subreg:SI (reg:DF 122 [ a ]) 0), which *I* thought was suspect.

Ug.  You've got 64-bit registers, but you're not really telling the
compiler that you've got 64-bit registers.  Of course things go a
little bit wonky.

I'm not sure how to fix this such that you can be sure that it won't
show up in some other context, but if negdf and absdf are the primary
culprits generating this sort of ugliness, then I suggest hiding it
all behind pattern magic, like so.

If I've got the mnemonics wrong, what I'm after is to swap the two
halves of the register, use the single-precision neg/abs/nabs insn
to fiddle the high bit appropriately, then swap the halves back.
Yaye, no temporary registers needed.


r~



Index: rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.336
diff -c -p -d -u -r1.336 rs6000.md
--- rs6000.md	1 Dec 2004 17:18:38 -0000	1.336
+++ rs6000.md	7 Dec 2004 06:31:00 -0000
@@ -4879,7 +4879,7 @@
 (define_expand "negdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(neg:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT"
   "")
 
 (define_insn "*negdf2_fpr"
@@ -4892,7 +4892,7 @@
 (define_expand "absdf2"
   [(set (match_operand:DF 0 "gpc_reg_operand" "")
 	(abs:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "TARGET_HARD_FLOAT"
   "")
 
 (define_insn "*absdf2_fpr"
Index: spe.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/spe.md,v
retrieving revision 1.29
diff -c -p -d -u -r1.29 spe.md
--- spe.md	10 Nov 2004 01:08:22 -0000	1.29
+++ spe.md	7 Dec 2004 06:31:01 -0000
@@ -52,6 +52,34 @@
   "efsnabs %0,%1"
   [(set_attr "type" "fpsimple")])
 
+;; These patterns are here so that the rtl expander doesn't go off thinking
+;; that it's a good idea to try to implement negdf and absdf with subregs and
+;; integer arithmetic and then (fail to) discover that we've slightly
+;; misrepresented the true nature of our funny registers.
+(define_insn "*negdf2_gpr"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=r")
+	(neg:DF (match_operand:DF 1 "gpc_reg_operand" "r")))]
+  "TARGET_HARD_FLOAT && !TARGET_FPRS && !TARGET_E500_DOUBLE"
+  "evmergelohi %0,%1,%1\;efsneg %0,%0\;evmergelohi %0,%0,%0"
+  [(set_attr "type" "three")
+   (set_attr "length" "12")])
+
+(define_insn "*absdf2_gpr"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=r")
+	(abs:DF (match_operand:DF 1 "gpc_reg_operand" "r")))]
+  "TARGET_HARD_FLOAT && !TARGET_FPRS && !TARGET_E500_DOUBLE"
+  "evmergelohi %0,%1,%1\;efsabs %0,%0\;evmergelohi %0,%0,%0"
+  [(set_attr "type" "three")
+   (set_attr "length" "12")])
+
+(define_insn "*nabsdf2_gpr"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=r")
+	(neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "r"))))]
+  "TARGET_HARD_FLOAT && !TARGET_FPRS && !TARGET_E500_DOUBLE"
+  "evmergelohi %0,%1,%1\;efsnabs %0,%0\;evmergelohi %0,%0,%0"
+  [(set_attr "type" "three")
+   (set_attr "length" "12")])
+
 (define_insn "*addsf3_gpr"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=r")
 	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "%r")


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