patch: reject incompatible classes in simplify_subreg

Richard Henderson rth@redhat.com
Tue Dec 7 06:32:00 GMT 2004


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")



More information about the Gcc-patches mailing list