[PATCH, RS6000] gpc_reg_operand

Alan Modra amodra@gmail.com
Tue May 19 01:11:00 GMT 2015


gpc_reg_operand contains a test that dates back to the early 1990s,
when FIRST_PSEUDO_REGISTER was 76.  At that point, testing
REGNO (op) >= ARG_POINTER_REGNUM allowed ap, xer/ca, cr0..cr7 and
pseudos.  A later patch corrected this to remove xer.  Nowadays we
have a lot more hard registers, altivec, vsx, htm, spe hi.  Some of
these are definitely special registers so not appropriate for
gpc_reg_operand to match.  This patch corrects the situation, to
just allow pseudos, int, fp, altivec and vsx.  ap and sfp are allowed
via INT_REGNO_P.  Note that I've removed cr0..cr7.  I believe this is
OK along with the extzvdi_internal2 change.  I checked all uses of
gpc_reg_operand and predicates derived from gpc_reg_operand.

The patch also removes some operand predicates I discovered were
unused, and tightens the vr save/restore patterns I added some time
ago.  Bootstrapped and regression tested powerpc64le-linux and
powerpc64-linux, the latter with -mcpu=power7.  OK for mainline?

	* config/rs6000/predicates.md (gpc_reg_operand): Don't allow all
	hard registers numbered greater or equal to ARG_POINTER_REGNUM.
	(reg_or_neg_short_operand, fix_trunc_dest_operand): Delete
	unused predicates.
	* config/rs6000/altivec.md (save_vregs_*, restore_vregs_*):
	Use altivec_register_operand.  Make insn predicate TARGET_ALTIVEC.
	* config/rs6000/rs6000.md (extzvdi_internal2): Use cc_reg_operand.
	* config/rs6000/vsx.md (vsx_float<VSi><mode>2): Expand comment.

Index: gcc/config/rs6000/predicates.md
===================================================================
--- gcc/config/rs6000/predicates.md	(revision 223208)
+++ gcc/config/rs6000/predicates.md	(working copy)
@@ -207,9 +207,12 @@
   if (!REG_P (op))
     return 0;
 
-  if (REGNO (op) >= ARG_POINTER_REGNUM && !CA_REGNO_P (REGNO (op)))
+  if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
     return 1;
 
+  if (TARGET_ALTIVEC && ALTIVEC_REGNO_P (REGNO (op)))
+    return 1;
+
   if (TARGET_VSX && VSX_REGNO_P (REGNO (op)))
     return 1;
 
@@ -357,17 +360,6 @@
     (match_operand 0 "short_cint_operand")
     (match_operand 0 "gpc_reg_operand")))
 
-;; Return 1 if op is a constant integer valid whose negation is valid for
-;; D field or non-special register register.
-;; Do not allow a constant zero because all patterns that call this
-;; predicate use "addic r1,r2,-const" to set carry when r2 is greater than
-;; or equal to const, which does not work for zero.
-(define_predicate "reg_or_neg_short_operand"
-  (if_then_else (match_code "const_int")
-    (match_test "satisfies_constraint_P (op)
-		 && INTVAL (op) != 0")
-    (match_operand 0 "gpc_reg_operand")))
-
 ;; Return 1 if op is a constant integer valid for DS field
 ;; or non-special register.
 (define_predicate "reg_or_aligned_short_operand"
@@ -713,15 +705,6 @@
 		    || (GET_CODE (XEXP (op, 0)) == PRE_MODIFY
 			&& indexed_address (XEXP (XEXP (op, 0), 1), mode))))"))
 
-;; Used for the destination of the fix_truncdfsi2 expander.
-;; If stfiwx will be used, the result goes to memory; otherwise,
-;; we're going to emit a store and a load of a subreg, so the dest is a
-;; register.
-(define_predicate "fix_trunc_dest_operand"
-  (if_then_else (match_test "! TARGET_E500_DOUBLE && TARGET_PPC_GFXOPT")
-   (match_operand 0 "memory_operand")
-   (match_operand 0 "gpc_reg_operand")))
-
 ;; Return 1 if the operand is either a non-special register or can be used
 ;; as the operand of a `mode' add insn.
 (define_predicate "add_operand"
Index: gcc/config/rs6000/altivec.md
===================================================================
--- gcc/config/rs6000/altivec.md	(revision 223208)
+++ gcc/config/rs6000/altivec.md	(working copy)
@@ -353,8 +353,8 @@
       (use (reg:P 0))
       (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b")
 			     (match_operand:P 3 "short_cint_operand" "I")))
-	   (match_operand:V4SI 4 "gpc_reg_operand" "v"))])]
-  ""
+	   (match_operand:V4SI 4 "altivec_register_operand" "v"))])]
+  "TARGET_ALTIVEC"
   "bl %1"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
@@ -367,8 +367,8 @@
       (use (reg:P 0))
       (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b")
 			     (match_operand:P 3 "short_cint_operand" "I")))
-	   (match_operand:V4SI 4 "gpc_reg_operand" "v"))])]
-  ""
+	   (match_operand:V4SI 4 "altivec_register_operand" "v"))])]
+  "TARGET_ALTIVEC"
   "bl %1"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
@@ -379,10 +379,10 @@
       (use (match_operand:P 1 "symbol_ref_operand" "s"))
       (clobber (reg:P 11))
       (use (reg:P 0))
-      (set (match_operand:V4SI 2 "gpc_reg_operand" "=v")
+      (set (match_operand:V4SI 2 "altivec_register_operand" "=v")
 	   (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b")
 			     (match_operand:P 4 "short_cint_operand" "I"))))])]
-  ""
+  "TARGET_ALTIVEC"
   "bl %1"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
@@ -393,10 +393,10 @@
       (use (match_operand:P 1 "symbol_ref_operand" "s"))
       (clobber (reg:P 12))
       (use (reg:P 0))
-      (set (match_operand:V4SI 2 "gpc_reg_operand" "=v")
+      (set (match_operand:V4SI 2 "altivec_register_operand" "=v")
 	   (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b")
 			     (match_operand:P 4 "short_cint_operand" "I"))))])]
-  ""
+  "TARGET_ALTIVEC"
   "bl %1"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 223208)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -3653,7 +3653,7 @@
    (set_attr "dot" "yes")])
 
 (define_insn "*extzvdi_internal2"
-  [(set (match_operand:CC 4 "gpc_reg_operand" "=x")
+  [(set (match_operand:CC 4 "cc_reg_operand" "=x")
 	(compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
 			 (match_operand:SI 2 "const_int_operand" "i")
 			 (match_operand:SI 3 "const_int_operand" "i"))
Index: gcc/config/rs6000/vsx.md
===================================================================
--- gcc/config/rs6000/vsx.md	(revision 223208)
+++ gcc/config/rs6000/vsx.md	(working copy)
@@ -1199,7 +1199,8 @@
 ;; the fprs because we don't want to add the altivec registers to movdi/movsi.
 ;; For the unsigned tests, there isn't a generic double -> unsigned conversion
 ;; in rs6000.md so don't test VECTOR_UNIT_VSX_P, just test against VSX.
-;; Don't use vsx_register_operand here, use gpc_reg_operand to match rs6000.md.
+;; Don't use vsx_register_operand here, use gpc_reg_operand to match rs6000.md
+;; in allowing virtual registers.
 (define_insn "vsx_float<VSi><mode>2"
   [(set (match_operand:VSX_F 0 "gpc_reg_operand" "=<VSr>,?<VSa>")
 	(float:VSX_F (match_operand:<VSI> 1 "gpc_reg_operand" "<VSr2>,<VSr3>")))]

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Gcc-patches mailing list